support changing of password when it has expired

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@2905 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
1997-08-11 03:38:01 +00:00
parent 0107f90afd
commit baf84d8966

View File

@@ -254,6 +254,107 @@ get_init_creds_common(krb5_context context,
return 0; return 0;
} }
krb5_error_code
change_password (krb5_context context,
krb5_principal client,
char *password,
char *newpw,
size_t newpw_sz,
krb5_prompter_fct prompter,
void *data,
krb5_get_init_creds_opt *old_options)
{
krb5_prompt prompt;
krb5_error_code ret;
krb5_creds cpw_cred;
char buf1[BUFSIZ], buf2[BUFSIZ];
krb5_data password_data;
int result_code;
krb5_data result_code_string;
krb5_data result_string;
char *p;
krb5_get_init_creds_opt options;
memset (&cpw_cred, 0, sizeof(cpw_cred));
krb5_get_init_creds_opt_init (&options);
krb5_get_init_creds_opt_set_tkt_life (&options, 60);
krb5_get_init_creds_opt_set_preauth_list (&options,
old_options->preauth_list,
old_options->preauth_list_length);
krb5_data_zero (&result_code_string);
krb5_data_zero (&result_string);
ret = krb5_get_init_creds_password (context,
&cpw_cred,
client,
password,
prompter,
data,
0,
"kadmin/changepw",
&options);
if (ret)
goto out;
for(;;) {
password_data.data = buf1;
password_data.length = sizeof(buf1);
prompt.hidden = 1;
prompt.prompt = "New password";
prompt.reply = &password_data;
ret = (*prompter) (context, data, "Changing password", 1, &prompt);
if (ret)
goto out;
password_data.data = buf2;
password_data.length = sizeof(buf2);
prompt.hidden = 1;
prompt.prompt = "Repeat new password";
prompt.reply = &password_data;
ret = (*prompter) (context, data, "Changing password", 1, &prompt);
if (ret)
goto out;
if (strcmp (buf1, buf2) == 0)
break;
}
ret = krb5_change_password (context,
&cpw_cred,
buf1,
&result_code,
&result_code_string,
&result_string);
if (ret)
goto out;
asprintf (&p, "%s: %.*s\n",
result_code ? "Error" : "Success",
result_string.length,
result_string.data);
ret = (*prompter) (context, data, p, 0, NULL);
free (p);
if (result_code == 0) {
strncpy (newpw, buf1, newpw_sz);
ret = 0;
} else
ret = ENOTTY;
out:
memset (buf1, 0, sizeof(buf1));
memset (buf2, 0, sizeof(buf2));
krb5_data_free (&result_string);
krb5_data_free (&result_code_string);
krb5_free_creds_contents (context, &cpw_cred);
return ret;
}
krb5_error_code krb5_error_code
krb5_get_init_creds_password(krb5_context context, krb5_get_init_creds_password(krb5_context context,
krb5_creds *creds, krb5_creds *creds,
@@ -274,6 +375,7 @@ krb5_get_init_creds_password(krb5_context context,
krb5_kdc_rep kdc_reply; krb5_kdc_rep kdc_reply;
char buf[BUFSIZ]; char buf[BUFSIZ];
krb5_data password_data; krb5_data password_data;
int done;
ret = get_init_creds_common(context, creds, client, start_time, ret = get_init_creds_common(context, creds, client, start_time,
in_tkt_service, options, in_tkt_service, options,
@@ -303,20 +405,41 @@ krb5_get_init_creds_password(krb5_context context,
password = password_data.data; password = password_data.data;
} }
ret = krb5_get_in_cred (context, done = 0;
flags.i, while(!done) {
addrs, ret = krb5_get_in_cred (context,
etypes, flags.i,
pre_auth_types, addrs,
krb5_password_key_proc, etypes,
password, pre_auth_types,
NULL, krb5_password_key_proc,
NULL, password,
&this_cred, NULL,
&kdc_reply); NULL,
memset (buf, 0, sizeof(buf)); &this_cred,
if (ret) &kdc_reply);
goto out; switch (ret) {
case 0 :
done = 1;
break;
case KRB5KDC_ERR_KEY_EXPIRED :
ret = change_password (context,
client,
password,
buf,
sizeof(buf),
prompter,
data,
options);
if (ret)
goto out;
password = buf;
break;
default:
goto out;
}
}
if (prompter) if (prompter)
print_expire (context, print_expire (context,
krb5_princ_realm (context, this_cred.client), krb5_princ_realm (context, this_cred.client),
@@ -334,6 +457,7 @@ krb5_get_init_creds_password(krb5_context context,
return 0; return 0;
out: out:
memset (buf, 0, sizeof(buf));
free (pre_auth_types); free (pre_auth_types);
free (etypes); free (etypes);
krb5_free_creds_contents (context, &this_cred); krb5_free_creds_contents (context, &this_cred);