/*
 * call-seq:
 *   change_password(old_password, new_password)
 *
 * Allow user to change their Kerberos password, providing the +old_password+ 
 * and the +new_password+.
 * 
 * Returns true on success, raises a Krb5Auth::Krb5::Exception on failure.
 */
static VALUE Krb5_change_password(VALUE self, VALUE v_old, VALUE v_new)
{
  char *oldpass;
  char *newpass;
  int pw_result;
  struct ruby_krb5 *kerb;
  krb5_error_code krbret;
  krb5_data pw_res_string, res_string;

  Check_Type(v_old, T_STRING);
  Check_Type(v_new, T_STRING);

  oldpass = StringValueCStr(v_old);
  newpass = StringValueCStr(v_new);

  Data_Get_Struct(self, struct ruby_krb5, kerb);

  if(!kerb){
    NOSTRUCT_EXCEPT();
    return Qfalse;
  }

  krbret = krb5_get_init_creds_password(
    kerb->ctx,
    &kerb->creds,
    kerb->princ,
    oldpass,
    NULL,
    NULL,
    0,
    "kadmin/changepw",
    NULL
  );

  if(krbret){
    Krb5_register_error(krbret);
    return Qfalse; 
  }

  krbret = krb5_change_password(
    kerb->ctx,
    &kerb->creds,
    newpass,
    &pw_result,
    &pw_res_string,
    &res_string    
  );

  // 0 is success. Anything else is failure.

  if(krbret){
    Krb5_register_error(krbret);
    return Qfalse; 
  }

  if(pw_result){
    Krb5_register_error(pw_result);
    return Qfalse; 
  }

  return Qtrue;
}