1b528cefcSMark Murray /* 213e3f4d6SMark Murray * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "krb5_locl.h" 35b528cefcSMark Murray 365e9cd1aeSAssar Westerlund RCSID("$Id: init_creds_pw.c,v 1.44 2000/07/24 03:46:40 assar Exp $"); 37b528cefcSMark Murray 38b528cefcSMark Murray static int 39b528cefcSMark Murray get_config_time (krb5_context context, 40b528cefcSMark Murray char *realm, 41b528cefcSMark Murray char *name, 42b528cefcSMark Murray int def) 43b528cefcSMark Murray { 44b528cefcSMark Murray int ret; 45b528cefcSMark Murray 46b528cefcSMark Murray ret = krb5_config_get_time (context, NULL, 47b528cefcSMark Murray "realms", 48b528cefcSMark Murray realm, 49b528cefcSMark Murray name, 50b528cefcSMark Murray NULL); 51b528cefcSMark Murray if (ret >= 0) 52b528cefcSMark Murray return ret; 53b528cefcSMark Murray ret = krb5_config_get_time (context, NULL, 54b528cefcSMark Murray "libdefaults", 55b528cefcSMark Murray name, 56b528cefcSMark Murray NULL); 57b528cefcSMark Murray if (ret >= 0) 58b528cefcSMark Murray return ret; 59b528cefcSMark Murray return def; 60b528cefcSMark Murray } 61b528cefcSMark Murray 62b528cefcSMark Murray static krb5_boolean 63b528cefcSMark Murray get_config_bool (krb5_context context, 64b528cefcSMark Murray char *realm, 65b528cefcSMark Murray char *name) 66b528cefcSMark Murray { 67b528cefcSMark Murray return krb5_config_get_bool (context, 68b528cefcSMark Murray NULL, 69b528cefcSMark Murray "realms", 70b528cefcSMark Murray realm, 71b528cefcSMark Murray name, 72b528cefcSMark Murray NULL) 73b528cefcSMark Murray || krb5_config_get_bool (context, 74b528cefcSMark Murray NULL, 75b528cefcSMark Murray "libdefaults", 76b528cefcSMark Murray name, 77b528cefcSMark Murray NULL); 78b528cefcSMark Murray } 79b528cefcSMark Murray 80b528cefcSMark Murray static krb5_error_code 81b528cefcSMark Murray init_cred (krb5_context context, 82b528cefcSMark Murray krb5_creds *cred, 83b528cefcSMark Murray krb5_principal client, 84b528cefcSMark Murray krb5_deltat start_time, 85b528cefcSMark Murray const char *in_tkt_service, 86b528cefcSMark Murray krb5_get_init_creds_opt *options) 87b528cefcSMark Murray { 88b528cefcSMark Murray krb5_error_code ret; 89b528cefcSMark Murray krb5_realm *client_realm; 90b528cefcSMark Murray int tmp; 9113e3f4d6SMark Murray krb5_timestamp now; 92b528cefcSMark Murray 93b528cefcSMark Murray krb5_timeofday (context, &now); 94b528cefcSMark Murray 95b528cefcSMark Murray memset (cred, 0, sizeof(*cred)); 96b528cefcSMark Murray 97b528cefcSMark Murray if (client) 98b528cefcSMark Murray krb5_copy_principal(context, client, &cred->client); 99b528cefcSMark Murray else { 100b528cefcSMark Murray ret = krb5_get_default_principal (context, 101b528cefcSMark Murray &cred->client); 102b528cefcSMark Murray if (ret) 103b528cefcSMark Murray goto out; 104b528cefcSMark Murray } 105b528cefcSMark Murray 106b528cefcSMark Murray client_realm = krb5_princ_realm (context, cred->client); 107b528cefcSMark Murray 108b528cefcSMark Murray if (start_time) 109b528cefcSMark Murray cred->times.starttime = now + start_time; 110b528cefcSMark Murray 111b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_TKT_LIFE) 112b528cefcSMark Murray tmp = options->tkt_life; 113b528cefcSMark Murray else 114b528cefcSMark Murray tmp = get_config_time (context, 115b528cefcSMark Murray *client_realm, 116b528cefcSMark Murray "ticket_lifetime", 117b528cefcSMark Murray 10 * 60 * 60); 118b528cefcSMark Murray cred->times.endtime = now + tmp; 119b528cefcSMark Murray 120b528cefcSMark Murray tmp = 0; 121b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE) 122b528cefcSMark Murray tmp = options->renew_life; 123b528cefcSMark Murray else 124b528cefcSMark Murray tmp = get_config_time (context, 125b528cefcSMark Murray *client_realm, 126b528cefcSMark Murray "renew_lifetime", 127b528cefcSMark Murray 0); 128b528cefcSMark Murray if (tmp) 129b528cefcSMark Murray cred->times.renew_till = now + tmp; 130b528cefcSMark Murray 131b528cefcSMark Murray if (in_tkt_service) { 132b528cefcSMark Murray krb5_realm server_realm; 133b528cefcSMark Murray 134b528cefcSMark Murray ret = krb5_parse_name (context, in_tkt_service, &cred->server); 135b528cefcSMark Murray if (ret) 136b528cefcSMark Murray goto out; 137b528cefcSMark Murray server_realm = strdup (*client_realm); 138b528cefcSMark Murray free (cred->server->realm); 139b528cefcSMark Murray krb5_princ_set_realm (context, cred->server, &server_realm); 140b528cefcSMark Murray } else { 141b528cefcSMark Murray ret = krb5_make_principal(context, &cred->server, 142b528cefcSMark Murray *client_realm, KRB5_TGS_NAME, *client_realm, 143b528cefcSMark Murray NULL); 144b528cefcSMark Murray if (ret) 145b528cefcSMark Murray goto out; 146b528cefcSMark Murray } 147b528cefcSMark Murray return 0; 148b528cefcSMark Murray 149b528cefcSMark Murray out: 150b528cefcSMark Murray krb5_free_creds_contents (context, cred); 151b528cefcSMark Murray return ret; 152b528cefcSMark Murray } 153b528cefcSMark Murray 154b528cefcSMark Murray /* 155b528cefcSMark Murray * Parse the last_req data and show it to the user if it's interesting 156b528cefcSMark Murray */ 157b528cefcSMark Murray 158b528cefcSMark Murray static void 159b528cefcSMark Murray print_expire (krb5_context context, 160b528cefcSMark Murray krb5_realm *realm, 161b528cefcSMark Murray krb5_kdc_rep *rep, 162b528cefcSMark Murray krb5_prompter_fct prompter, 163b528cefcSMark Murray krb5_data *data) 164b528cefcSMark Murray { 165b528cefcSMark Murray int i; 166b528cefcSMark Murray LastReq *lr = &rep->enc_part.last_req; 16713e3f4d6SMark Murray krb5_timestamp sec; 168b528cefcSMark Murray time_t t; 169b528cefcSMark Murray 170b528cefcSMark Murray krb5_timeofday (context, &sec); 171b528cefcSMark Murray 172b528cefcSMark Murray t = sec + get_config_time (context, 173b528cefcSMark Murray *realm, 174b528cefcSMark Murray "warn_pwexpire", 175b528cefcSMark Murray 7 * 24 * 60 * 60); 176b528cefcSMark Murray 177b528cefcSMark Murray for (i = 0; i < lr->len; ++i) { 178b528cefcSMark Murray if (lr->val[i].lr_type == 6 179b528cefcSMark Murray && lr->val[i].lr_value <= t) { 180b528cefcSMark Murray char *p; 1815e9cd1aeSAssar Westerlund time_t tmp = lr->val[i].lr_value; 182b528cefcSMark Murray 1835e9cd1aeSAssar Westerlund asprintf (&p, "Your password will expire at %s", ctime(&tmp)); 184b528cefcSMark Murray (*prompter) (context, data, p, 0, NULL); 185b528cefcSMark Murray free (p); 186b528cefcSMark Murray return; 187b528cefcSMark Murray } 188b528cefcSMark Murray } 189b528cefcSMark Murray 190b528cefcSMark Murray if (rep->enc_part.key_expiration 191b528cefcSMark Murray && *rep->enc_part.key_expiration <= t) { 192b528cefcSMark Murray char *p; 1935e9cd1aeSAssar Westerlund time_t t = *rep->enc_part.key_expiration; 194b528cefcSMark Murray 1955e9cd1aeSAssar Westerlund asprintf (&p, "Your password/account will expire at %s", ctime(&t)); 196b528cefcSMark Murray (*prompter) (context, data, p, 0, NULL); 197b528cefcSMark Murray free (p); 198b528cefcSMark Murray } 199b528cefcSMark Murray } 200b528cefcSMark Murray 201b528cefcSMark Murray static krb5_error_code 202b528cefcSMark Murray get_init_creds_common(krb5_context context, 203b528cefcSMark Murray krb5_creds *creds, 204b528cefcSMark Murray krb5_principal client, 205b528cefcSMark Murray krb5_deltat start_time, 206b528cefcSMark Murray const char *in_tkt_service, 207b528cefcSMark Murray krb5_get_init_creds_opt *options, 208b528cefcSMark Murray krb5_addresses **addrs, 209b528cefcSMark Murray krb5_enctype **etypes, 210b528cefcSMark Murray krb5_creds *cred, 211b528cefcSMark Murray krb5_preauthtype **pre_auth_types, 212b528cefcSMark Murray krb5_kdc_flags *flags) 213b528cefcSMark Murray { 214b528cefcSMark Murray krb5_error_code ret; 215b528cefcSMark Murray krb5_realm *client_realm; 216b528cefcSMark Murray 217b528cefcSMark Murray ret = init_cred (context, cred, client, start_time, 218b528cefcSMark Murray in_tkt_service, options); 219b528cefcSMark Murray if (ret) 220b528cefcSMark Murray return ret; 221b528cefcSMark Murray 222b528cefcSMark Murray client_realm = krb5_princ_realm (context, cred->client); 223b528cefcSMark Murray 224b528cefcSMark Murray flags->i = 0; 225b528cefcSMark Murray 226b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) 227b528cefcSMark Murray flags->b.forwardable = options->forwardable; 228b528cefcSMark Murray else 229b528cefcSMark Murray flags->b.forwardable = get_config_bool (context, 230b528cefcSMark Murray *client_realm, 231b528cefcSMark Murray "forwardable"); 232b528cefcSMark Murray 233b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE) 234b528cefcSMark Murray flags->b.proxiable = options->proxiable; 235b528cefcSMark Murray else 236b528cefcSMark Murray flags->b.proxiable = get_config_bool (context, 237b528cefcSMark Murray *client_realm, 238b528cefcSMark Murray "proxiable"); 239b528cefcSMark Murray 240b528cefcSMark Murray if (start_time) 241b528cefcSMark Murray flags->b.postdated = 1; 242b528cefcSMark Murray if (cred->times.renew_till) 243b528cefcSMark Murray flags->b.renewable = 1; 244b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) 245b528cefcSMark Murray *addrs = options->address_list; 246b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { 247b528cefcSMark Murray *etypes = malloc((options->etype_list_length + 1) 248b528cefcSMark Murray * sizeof(krb5_enctype)); 249b528cefcSMark Murray if (*etypes == NULL) 250b528cefcSMark Murray return ENOMEM; 251b528cefcSMark Murray memcpy (*etypes, options->etype_list, 252b528cefcSMark Murray options->etype_list_length * sizeof(krb5_enctype)); 253b528cefcSMark Murray (*etypes)[options->etype_list_length] = ETYPE_NULL; 254b528cefcSMark Murray } 255b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) { 256b528cefcSMark Murray *pre_auth_types = malloc((options->preauth_list_length + 1) 257b528cefcSMark Murray * sizeof(krb5_preauthtype)); 258b528cefcSMark Murray if (*pre_auth_types == NULL) 259b528cefcSMark Murray return ENOMEM; 260b528cefcSMark Murray memcpy (*pre_auth_types, options->preauth_list, 261b528cefcSMark Murray options->preauth_list_length * sizeof(krb5_preauthtype)); 262b528cefcSMark Murray (*pre_auth_types)[options->preauth_list_length] = KRB5_PADATA_NONE; 263b528cefcSMark Murray } 264b528cefcSMark Murray if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT) 265b528cefcSMark Murray ; /* XXX */ 2665e9cd1aeSAssar Westerlund if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) 2675e9cd1aeSAssar Westerlund flags->b.request_anonymous = options->anonymous; 268b528cefcSMark Murray return 0; 269b528cefcSMark Murray } 270b528cefcSMark Murray 271b528cefcSMark Murray static krb5_error_code 272b528cefcSMark Murray change_password (krb5_context context, 273b528cefcSMark Murray krb5_principal client, 274b528cefcSMark Murray const char *password, 275b528cefcSMark Murray char *newpw, 276b528cefcSMark Murray size_t newpw_sz, 277b528cefcSMark Murray krb5_prompter_fct prompter, 278b528cefcSMark Murray void *data, 279b528cefcSMark Murray krb5_get_init_creds_opt *old_options) 280b528cefcSMark Murray { 281b528cefcSMark Murray krb5_prompt prompt; 282b528cefcSMark Murray krb5_error_code ret; 283b528cefcSMark Murray krb5_creds cpw_cred; 284b528cefcSMark Murray char buf1[BUFSIZ], buf2[BUFSIZ]; 285b528cefcSMark Murray krb5_data password_data; 286b528cefcSMark Murray int result_code; 287b528cefcSMark Murray krb5_data result_code_string; 288b528cefcSMark Murray krb5_data result_string; 289b528cefcSMark Murray char *p; 290b528cefcSMark Murray krb5_get_init_creds_opt options; 291b528cefcSMark Murray 292b528cefcSMark Murray memset (&cpw_cred, 0, sizeof(cpw_cred)); 293b528cefcSMark Murray 294b528cefcSMark Murray krb5_get_init_creds_opt_init (&options); 295b528cefcSMark Murray krb5_get_init_creds_opt_set_tkt_life (&options, 60); 2965e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_forwardable (&options, FALSE); 2975e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_proxiable (&options, FALSE); 2985e9cd1aeSAssar Westerlund if (old_options->flags & KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST) 299b528cefcSMark Murray krb5_get_init_creds_opt_set_preauth_list (&options, 300b528cefcSMark Murray old_options->preauth_list, 301b528cefcSMark Murray old_options->preauth_list_length); 302b528cefcSMark Murray 303b528cefcSMark Murray krb5_data_zero (&result_code_string); 304b528cefcSMark Murray krb5_data_zero (&result_string); 305b528cefcSMark Murray 306b528cefcSMark Murray ret = krb5_get_init_creds_password (context, 307b528cefcSMark Murray &cpw_cred, 308b528cefcSMark Murray client, 309b528cefcSMark Murray password, 310b528cefcSMark Murray prompter, 311b528cefcSMark Murray data, 312b528cefcSMark Murray 0, 313b528cefcSMark Murray "kadmin/changepw", 314b528cefcSMark Murray &options); 315b528cefcSMark Murray if (ret) 316b528cefcSMark Murray goto out; 317b528cefcSMark Murray 318b528cefcSMark Murray for(;;) { 319b528cefcSMark Murray password_data.data = buf1; 320b528cefcSMark Murray password_data.length = sizeof(buf1); 321b528cefcSMark Murray 322b528cefcSMark Murray prompt.hidden = 1; 323b528cefcSMark Murray prompt.prompt = "New password: "; 324b528cefcSMark Murray prompt.reply = &password_data; 325b528cefcSMark Murray 326b528cefcSMark Murray ret = (*prompter) (context, data, "Changing password", 1, &prompt); 327b528cefcSMark Murray if (ret) 328b528cefcSMark Murray goto out; 329b528cefcSMark Murray 330b528cefcSMark Murray password_data.data = buf2; 331b528cefcSMark Murray password_data.length = sizeof(buf2); 332b528cefcSMark Murray 333b528cefcSMark Murray prompt.hidden = 1; 334b528cefcSMark Murray prompt.prompt = "Repeat new password: "; 335b528cefcSMark Murray prompt.reply = &password_data; 336b528cefcSMark Murray 337b528cefcSMark Murray ret = (*prompter) (context, data, "Changing password", 1, &prompt); 338b528cefcSMark Murray if (ret) 339b528cefcSMark Murray goto out; 340b528cefcSMark Murray 341b528cefcSMark Murray if (strcmp (buf1, buf2) == 0) 342b528cefcSMark Murray break; 343b528cefcSMark Murray } 344b528cefcSMark Murray 345b528cefcSMark Murray ret = krb5_change_password (context, 346b528cefcSMark Murray &cpw_cred, 347b528cefcSMark Murray buf1, 348b528cefcSMark Murray &result_code, 349b528cefcSMark Murray &result_code_string, 350b528cefcSMark Murray &result_string); 351b528cefcSMark Murray if (ret) 352b528cefcSMark Murray goto out; 353b528cefcSMark Murray asprintf (&p, "%s: %.*s\n", 354b528cefcSMark Murray result_code ? "Error" : "Success", 355b528cefcSMark Murray (int)result_string.length, 356b528cefcSMark Murray (char*)result_string.data); 357b528cefcSMark Murray 358b528cefcSMark Murray ret = (*prompter) (context, data, p, 0, NULL); 359b528cefcSMark Murray free (p); 360b528cefcSMark Murray if (result_code == 0) { 36113e3f4d6SMark Murray strlcpy (newpw, buf1, newpw_sz); 362b528cefcSMark Murray ret = 0; 363b528cefcSMark Murray } else 364b528cefcSMark Murray ret = ENOTTY; 365b528cefcSMark Murray 366b528cefcSMark Murray out: 367b528cefcSMark Murray memset (buf1, 0, sizeof(buf1)); 368b528cefcSMark Murray memset (buf2, 0, sizeof(buf2)); 369b528cefcSMark Murray krb5_data_free (&result_string); 370b528cefcSMark Murray krb5_data_free (&result_code_string); 371b528cefcSMark Murray krb5_free_creds_contents (context, &cpw_cred); 372b528cefcSMark Murray return ret; 373b528cefcSMark Murray } 374b528cefcSMark Murray 375b528cefcSMark Murray krb5_error_code 376b528cefcSMark Murray krb5_get_init_creds_password(krb5_context context, 377b528cefcSMark Murray krb5_creds *creds, 378b528cefcSMark Murray krb5_principal client, 379b528cefcSMark Murray const char *password, 380b528cefcSMark Murray krb5_prompter_fct prompter, 381b528cefcSMark Murray void *data, 382b528cefcSMark Murray krb5_deltat start_time, 383b528cefcSMark Murray const char *in_tkt_service, 384b528cefcSMark Murray krb5_get_init_creds_opt *options) 385b528cefcSMark Murray { 386b528cefcSMark Murray krb5_error_code ret; 387b528cefcSMark Murray krb5_kdc_flags flags; 388b528cefcSMark Murray krb5_addresses *addrs = NULL; 389b528cefcSMark Murray krb5_enctype *etypes = NULL; 390b528cefcSMark Murray krb5_preauthtype *pre_auth_types = NULL; 391b528cefcSMark Murray krb5_creds this_cred; 392b528cefcSMark Murray krb5_kdc_rep kdc_reply; 393b528cefcSMark Murray char buf[BUFSIZ]; 394b528cefcSMark Murray krb5_data password_data; 395b528cefcSMark Murray int done; 396b528cefcSMark Murray 397b528cefcSMark Murray ret = get_init_creds_common(context, creds, client, start_time, 398b528cefcSMark Murray in_tkt_service, options, 399b528cefcSMark Murray &addrs, &etypes, &this_cred, &pre_auth_types, 400b528cefcSMark Murray &flags); 401b528cefcSMark Murray if(ret) 402b528cefcSMark Murray goto out; 403b528cefcSMark Murray 404b528cefcSMark Murray if (password == NULL) { 405b528cefcSMark Murray krb5_prompt prompt; 406b528cefcSMark Murray char *p; 407b528cefcSMark Murray 408b528cefcSMark Murray krb5_unparse_name (context, this_cred.client, &p); 409b528cefcSMark Murray asprintf (&prompt.prompt, "%s's Password: ", p); 410b528cefcSMark Murray free (p); 411b528cefcSMark Murray password_data.data = buf; 412b528cefcSMark Murray password_data.length = sizeof(buf); 413b528cefcSMark Murray prompt.hidden = 1; 414b528cefcSMark Murray prompt.reply = &password_data; 415b528cefcSMark Murray 416b528cefcSMark Murray ret = (*prompter) (context, data, NULL, 1, &prompt); 417b528cefcSMark Murray free (prompt.prompt); 418b528cefcSMark Murray if (ret) { 419b528cefcSMark Murray memset (buf, 0, sizeof(buf)); 420b528cefcSMark Murray ret = KRB5_LIBOS_PWDINTR; 421b528cefcSMark Murray goto out; 422b528cefcSMark Murray } 423b528cefcSMark Murray password = password_data.data; 424b528cefcSMark Murray } 425b528cefcSMark Murray 426b528cefcSMark Murray done = 0; 427b528cefcSMark Murray while(!done) { 428b528cefcSMark Murray memset(&kdc_reply, 0, sizeof(kdc_reply)); 429b528cefcSMark Murray ret = krb5_get_in_cred (context, 430b528cefcSMark Murray flags.i, 431b528cefcSMark Murray addrs, 432b528cefcSMark Murray etypes, 433b528cefcSMark Murray pre_auth_types, 434b528cefcSMark Murray NULL, 435b528cefcSMark Murray krb5_password_key_proc, 436b528cefcSMark Murray password, 437b528cefcSMark Murray NULL, 438b528cefcSMark Murray NULL, 439b528cefcSMark Murray &this_cred, 440b528cefcSMark Murray &kdc_reply); 441b528cefcSMark Murray switch (ret) { 442b528cefcSMark Murray case 0 : 443b528cefcSMark Murray done = 1; 444b528cefcSMark Murray break; 445b528cefcSMark Murray case KRB5KDC_ERR_KEY_EXPIRED : 4465e9cd1aeSAssar Westerlund /* try to avoid recursion */ 4475e9cd1aeSAssar Westerlund 4485e9cd1aeSAssar Westerlund if (in_tkt_service != NULL 4495e9cd1aeSAssar Westerlund && strcmp (in_tkt_service, "kadmin/changepw") == 0) 4505e9cd1aeSAssar Westerlund goto out; 4515e9cd1aeSAssar Westerlund 452b528cefcSMark Murray ret = change_password (context, 453b528cefcSMark Murray client, 454b528cefcSMark Murray password, 455b528cefcSMark Murray buf, 456b528cefcSMark Murray sizeof(buf), 457b528cefcSMark Murray prompter, 458b528cefcSMark Murray data, 459b528cefcSMark Murray options); 460b528cefcSMark Murray if (ret) 461b528cefcSMark Murray goto out; 462b528cefcSMark Murray password = buf; 463b528cefcSMark Murray break; 464b528cefcSMark Murray default: 465b528cefcSMark Murray goto out; 466b528cefcSMark Murray } 467b528cefcSMark Murray } 468b528cefcSMark Murray 469b528cefcSMark Murray if (prompter) 470b528cefcSMark Murray print_expire (context, 471b528cefcSMark Murray krb5_princ_realm (context, this_cred.client), 472b528cefcSMark Murray &kdc_reply, 473b528cefcSMark Murray prompter, 474b528cefcSMark Murray data); 475b528cefcSMark Murray out: 476b528cefcSMark Murray memset (buf, 0, sizeof(buf)); 477b528cefcSMark Murray if (ret == 0) 478b528cefcSMark Murray krb5_free_kdc_rep (context, &kdc_reply); 479b528cefcSMark Murray 480b528cefcSMark Murray free (pre_auth_types); 481b528cefcSMark Murray free (etypes); 482b528cefcSMark Murray if (ret == 0 && creds) 483b528cefcSMark Murray *creds = this_cred; 484b528cefcSMark Murray else 485b528cefcSMark Murray krb5_free_creds_contents (context, &this_cred); 486b528cefcSMark Murray return ret; 487b528cefcSMark Murray } 488b528cefcSMark Murray 489b528cefcSMark Murray krb5_error_code 490b528cefcSMark Murray krb5_keyblock_key_proc (krb5_context context, 491b528cefcSMark Murray krb5_keytype type, 492b528cefcSMark Murray krb5_data *salt, 493b528cefcSMark Murray krb5_const_pointer keyseed, 494b528cefcSMark Murray krb5_keyblock **key) 495b528cefcSMark Murray { 496b528cefcSMark Murray return krb5_copy_keyblock (context, keyseed, key); 497b528cefcSMark Murray } 498b528cefcSMark Murray 499b528cefcSMark Murray krb5_error_code 500b528cefcSMark Murray krb5_get_init_creds_keytab(krb5_context context, 501b528cefcSMark Murray krb5_creds *creds, 502b528cefcSMark Murray krb5_principal client, 503b528cefcSMark Murray krb5_keytab keytab, 504b528cefcSMark Murray krb5_deltat start_time, 505b528cefcSMark Murray const char *in_tkt_service, 506b528cefcSMark Murray krb5_get_init_creds_opt *options) 507b528cefcSMark Murray { 508b528cefcSMark Murray krb5_error_code ret; 509b528cefcSMark Murray krb5_kdc_flags flags; 510b528cefcSMark Murray krb5_addresses *addrs = NULL; 511b528cefcSMark Murray krb5_enctype *etypes = NULL; 512b528cefcSMark Murray krb5_preauthtype *pre_auth_types = NULL; 513b528cefcSMark Murray krb5_creds this_cred; 514b528cefcSMark Murray krb5_keytab_key_proc_args *a; 515b528cefcSMark Murray 516b528cefcSMark Murray ret = get_init_creds_common(context, creds, client, start_time, 517b528cefcSMark Murray in_tkt_service, options, 518b528cefcSMark Murray &addrs, &etypes, &this_cred, &pre_auth_types, 519b528cefcSMark Murray &flags); 520b528cefcSMark Murray if(ret) 521b528cefcSMark Murray goto out; 522b528cefcSMark Murray 523b528cefcSMark Murray a = malloc (sizeof(*a)); 524b528cefcSMark Murray if (a == NULL) { 525b528cefcSMark Murray ret = ENOMEM; 526b528cefcSMark Murray goto out; 527b528cefcSMark Murray } 528b528cefcSMark Murray a->principal = this_cred.client; 529b528cefcSMark Murray a->keytab = keytab; 530b528cefcSMark Murray 531b528cefcSMark Murray ret = krb5_get_in_cred (context, 532b528cefcSMark Murray flags.i, 533b528cefcSMark Murray addrs, 534b528cefcSMark Murray etypes, 535b528cefcSMark Murray pre_auth_types, 536b528cefcSMark Murray NULL, 537b528cefcSMark Murray krb5_keytab_key_proc, 538b528cefcSMark Murray a, 539b528cefcSMark Murray NULL, 540b528cefcSMark Murray NULL, 541b528cefcSMark Murray &this_cred, 542b528cefcSMark Murray NULL); 543b528cefcSMark Murray if (ret) 544b528cefcSMark Murray goto out; 545b528cefcSMark Murray free (pre_auth_types); 546b528cefcSMark Murray free (etypes); 547b528cefcSMark Murray if (creds) 548b528cefcSMark Murray *creds = this_cred; 549b528cefcSMark Murray else 550b528cefcSMark Murray krb5_free_creds_contents (context, &this_cred); 551b528cefcSMark Murray return 0; 552b528cefcSMark Murray 553b528cefcSMark Murray out: 554b528cefcSMark Murray free (pre_auth_types); 555b528cefcSMark Murray free (etypes); 556b528cefcSMark Murray krb5_free_creds_contents (context, &this_cred); 557b528cefcSMark Murray return ret; 558b528cefcSMark Murray } 559