1b528cefcSMark Murray /* 2*ae771770SStanislav Sedov * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6*ae771770SStanislav Sedov * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7*ae771770SStanislav Sedov * 8b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 9b528cefcSMark Murray * modification, are permitted provided that the following conditions 10b528cefcSMark Murray * are met: 11b528cefcSMark Murray * 12b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 13b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 14b528cefcSMark Murray * 15b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 16b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 17b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 18b528cefcSMark Murray * 19b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 20b528cefcSMark Murray * may be used to endorse or promote products derived from this software 21b528cefcSMark Murray * without specific prior written permission. 22b528cefcSMark Murray * 23b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33b528cefcSMark Murray * SUCH DAMAGE. 34b528cefcSMark Murray */ 35b528cefcSMark Murray 36b528cefcSMark Murray #include "kuser_locl.h" 37c19800e8SDoug Rabson 38*ae771770SStanislav Sedov #ifdef __APPLE__ 39*ae771770SStanislav Sedov #include <Security/Security.h> 40*ae771770SStanislav Sedov #endif 41c19800e8SDoug Rabson 42*ae771770SStanislav Sedov #ifndef NO_NTLM 43c19800e8SDoug Rabson #include "heimntlm.h" 44*ae771770SStanislav Sedov #endif 455e9cd1aeSAssar Westerlund 465e9cd1aeSAssar Westerlund int forwardable_flag = -1; 475e9cd1aeSAssar Westerlund int proxiable_flag = -1; 485e9cd1aeSAssar Westerlund int renewable_flag = -1; 49b528cefcSMark Murray int renew_flag = 0; 50c19800e8SDoug Rabson int pac_flag = -1; 51b528cefcSMark Murray int validate_flag = 0; 52b528cefcSMark Murray int version_flag = 0; 53b528cefcSMark Murray int help_flag = 0; 54c19800e8SDoug Rabson int addrs_flag = -1; 558373020dSJacques Vidrine struct getarg_strings extra_addresses; 565e9cd1aeSAssar Westerlund int anonymous_flag = 0; 57b528cefcSMark Murray char *lifetime = NULL; 58b528cefcSMark Murray char *renew_life = NULL; 59c19800e8SDoug Rabson char *server_str = NULL; 60b528cefcSMark Murray char *cred_cache = NULL; 61b528cefcSMark Murray char *start_str = NULL; 62*ae771770SStanislav Sedov static int switch_cache_flags = 1; 63b528cefcSMark Murray struct getarg_strings etype_str; 64b528cefcSMark Murray int use_keytab = 0; 65b528cefcSMark Murray char *keytab_str = NULL; 66bbd80c28SJacques Vidrine int do_afslog = -1; 67b528cefcSMark Murray int fcache_version; 68c19800e8SDoug Rabson char *password_file = NULL; 69c19800e8SDoug Rabson char *pk_user_id = NULL; 70*ae771770SStanislav Sedov int pk_enterprise_flag = 0; 71*ae771770SStanislav Sedov struct hx509_certs_data *ent_user_id = NULL; 72c19800e8SDoug Rabson char *pk_x509_anchors = NULL; 73c19800e8SDoug Rabson int pk_use_enckey = 0; 74c19800e8SDoug Rabson static int canonicalize_flag = 0; 75*ae771770SStanislav Sedov static int enterprise_flag = 0; 76*ae771770SStanislav Sedov static int ok_as_delegate_flag = 0; 77*ae771770SStanislav Sedov static int use_referrals_flag = 0; 78*ae771770SStanislav Sedov static int windows_flag = 0; 79*ae771770SStanislav Sedov #ifndef NO_NTLM 80c19800e8SDoug Rabson static char *ntlm_domain; 81*ae771770SStanislav Sedov #endif 82c19800e8SDoug Rabson 83b528cefcSMark Murray 845e9cd1aeSAssar Westerlund static struct getargs args[] = { 85c19800e8SDoug Rabson /* 86c19800e8SDoug Rabson * used by MIT 87c19800e8SDoug Rabson * a: ~A 88c19800e8SDoug Rabson * V: verbose 89c19800e8SDoug Rabson * F: ~f 90c19800e8SDoug Rabson * P: ~p 91c19800e8SDoug Rabson * C: v4 cache name? 92c19800e8SDoug Rabson * 5: 93*ae771770SStanislav Sedov * 94*ae771770SStanislav Sedov * old flags 95*ae771770SStanislav Sedov * 4: 96*ae771770SStanislav Sedov * 9: 97c19800e8SDoug Rabson */ 98b528cefcSMark Murray { "afslog", 0 , arg_flag, &do_afslog, 99*ae771770SStanislav Sedov NP_("obtain afs tokens", ""), NULL }, 100bbd80c28SJacques Vidrine 101b528cefcSMark Murray { "cache", 'c', arg_string, &cred_cache, 102*ae771770SStanislav Sedov NP_("credentials cache", ""), "cachename" }, 103b528cefcSMark Murray 104*ae771770SStanislav Sedov { "forwardable", 0, arg_negative_flag, &forwardable_flag, 105*ae771770SStanislav Sedov NP_("get tickets not forwardable", ""), NULL }, 106*ae771770SStanislav Sedov 107*ae771770SStanislav Sedov { NULL, 'f', arg_flag, &forwardable_flag, 108*ae771770SStanislav Sedov NP_("get forwardable tickets", ""), NULL }, 109b528cefcSMark Murray 110b528cefcSMark Murray { "keytab", 't', arg_string, &keytab_str, 111*ae771770SStanislav Sedov NP_("keytab to use", ""), "keytabname" }, 112b528cefcSMark Murray 113b528cefcSMark Murray { "lifetime", 'l', arg_string, &lifetime, 114*ae771770SStanislav Sedov NP_("lifetime of tickets", ""), "time" }, 115b528cefcSMark Murray 1165e9cd1aeSAssar Westerlund { "proxiable", 'p', arg_flag, &proxiable_flag, 117*ae771770SStanislav Sedov NP_("get proxiable tickets", ""), NULL }, 118b528cefcSMark Murray 119b528cefcSMark Murray { "renew", 'R', arg_flag, &renew_flag, 120*ae771770SStanislav Sedov NP_("renew TGT", ""), NULL }, 121b528cefcSMark Murray 1225e9cd1aeSAssar Westerlund { "renewable", 0, arg_flag, &renewable_flag, 123*ae771770SStanislav Sedov NP_("get renewable tickets", ""), NULL }, 124b528cefcSMark Murray 125b528cefcSMark Murray { "renewable-life", 'r', arg_string, &renew_life, 126*ae771770SStanislav Sedov NP_("renewable lifetime of tickets", ""), "time" }, 127b528cefcSMark Murray 128c19800e8SDoug Rabson { "server", 'S', arg_string, &server_str, 129*ae771770SStanislav Sedov NP_("server to get ticket for", ""), "principal" }, 130b528cefcSMark Murray 131b528cefcSMark Murray { "start-time", 's', arg_string, &start_str, 132*ae771770SStanislav Sedov NP_("when ticket gets valid", ""), "time" }, 133b528cefcSMark Murray 134b528cefcSMark Murray { "use-keytab", 'k', arg_flag, &use_keytab, 135*ae771770SStanislav Sedov NP_("get key from keytab", ""), NULL }, 136b528cefcSMark Murray 137b528cefcSMark Murray { "validate", 'v', arg_flag, &validate_flag, 138*ae771770SStanislav Sedov NP_("validate TGT", ""), NULL }, 139b528cefcSMark Murray 140b528cefcSMark Murray { "enctypes", 'e', arg_strings, &etype_str, 141*ae771770SStanislav Sedov NP_("encryption types to use", ""), "enctypes" }, 142b528cefcSMark Murray 143b528cefcSMark Murray { "fcache-version", 0, arg_integer, &fcache_version, 144*ae771770SStanislav Sedov NP_("file cache version to create", ""), NULL }, 145b528cefcSMark Murray 146c19800e8SDoug Rabson { "addresses", 'A', arg_negative_flag, &addrs_flag, 147*ae771770SStanislav Sedov NP_("request a ticket with no addresses", ""), NULL }, 148b528cefcSMark Murray 1498373020dSJacques Vidrine { "extra-addresses",'a', arg_strings, &extra_addresses, 150*ae771770SStanislav Sedov NP_("include these extra addresses", ""), "addresses" }, 1518373020dSJacques Vidrine 1525e9cd1aeSAssar Westerlund { "anonymous", 0, arg_flag, &anonymous_flag, 153*ae771770SStanislav Sedov NP_("request an anonymous ticket", ""), NULL }, 1545e9cd1aeSAssar Westerlund 155c19800e8SDoug Rabson { "request-pac", 0, arg_flag, &pac_flag, 156*ae771770SStanislav Sedov NP_("request a Windows PAC", ""), NULL }, 157c19800e8SDoug Rabson 158c19800e8SDoug Rabson { "password-file", 0, arg_string, &password_file, 159*ae771770SStanislav Sedov NP_("read the password from a file", ""), NULL }, 160c19800e8SDoug Rabson 161c19800e8SDoug Rabson { "canonicalize",0, arg_flag, &canonicalize_flag, 162*ae771770SStanislav Sedov NP_("canonicalize client principal", ""), NULL }, 163*ae771770SStanislav Sedov 164*ae771770SStanislav Sedov { "enterprise",0, arg_flag, &enterprise_flag, 165*ae771770SStanislav Sedov NP_("parse principal as a KRB5-NT-ENTERPRISE name", ""), NULL }, 166c19800e8SDoug Rabson #ifdef PKINIT 167*ae771770SStanislav Sedov { "pk-enterprise", 0, arg_flag, &pk_enterprise_flag, 168*ae771770SStanislav Sedov NP_("use enterprise name from certificate", ""), NULL }, 169*ae771770SStanislav Sedov 170c19800e8SDoug Rabson { "pk-user", 'C', arg_string, &pk_user_id, 171*ae771770SStanislav Sedov NP_("principal's public/private/certificate identifier", ""), "id" }, 172c19800e8SDoug Rabson 173c19800e8SDoug Rabson { "x509-anchors", 'D', arg_string, &pk_x509_anchors, 174*ae771770SStanislav Sedov NP_("directory with CA certificates", ""), "directory" }, 175c19800e8SDoug Rabson 176c19800e8SDoug Rabson { "pk-use-enckey", 0, arg_flag, &pk_use_enckey, 177*ae771770SStanislav Sedov NP_("Use RSA encrypted reply (instead of DH)", ""), NULL }, 178c19800e8SDoug Rabson #endif 179*ae771770SStanislav Sedov #ifndef NO_NTLM 180c19800e8SDoug Rabson { "ntlm-domain", 0, arg_string, &ntlm_domain, 181*ae771770SStanislav Sedov NP_("NTLM domain", ""), "domain" }, 182*ae771770SStanislav Sedov #endif 183c19800e8SDoug Rabson 184*ae771770SStanislav Sedov { "change-default", 0, arg_negative_flag, &switch_cache_flags, 185*ae771770SStanislav Sedov NP_("switch the default cache to the new credentials cache", ""), NULL }, 186*ae771770SStanislav Sedov 187*ae771770SStanislav Sedov { "ok-as-delegate", 0, arg_flag, &ok_as_delegate_flag, 188*ae771770SStanislav Sedov NP_("honor ok-as-delegate on tickets", ""), NULL }, 189*ae771770SStanislav Sedov 190*ae771770SStanislav Sedov { "use-referrals", 0, arg_flag, &use_referrals_flag, 191*ae771770SStanislav Sedov NP_("only use referrals, no dns canalisation", ""), NULL }, 192*ae771770SStanislav Sedov 193*ae771770SStanislav Sedov { "windows", 0, arg_flag, &windows_flag, 194*ae771770SStanislav Sedov NP_("get windows behavior", ""), NULL }, 195*ae771770SStanislav Sedov 196*ae771770SStanislav Sedov { "version", 0, arg_flag, &version_flag, NULL, NULL }, 197*ae771770SStanislav Sedov { "help", 0, arg_flag, &help_flag, NULL, NULL } 198b528cefcSMark Murray }; 199b528cefcSMark Murray 200b528cefcSMark Murray static void 201b528cefcSMark Murray usage (int ret) 202b528cefcSMark Murray { 203*ae771770SStanislav Sedov arg_printusage_i18n (args, 204b528cefcSMark Murray sizeof(args)/sizeof(*args), 205*ae771770SStanislav Sedov N_("Usage: ", ""), 206b528cefcSMark Murray NULL, 207*ae771770SStanislav Sedov "[principal [command]]", 208*ae771770SStanislav Sedov getarg_i18n); 209b528cefcSMark Murray exit (ret); 210b528cefcSMark Murray } 211b528cefcSMark Murray 2124137ff4cSJacques Vidrine static krb5_error_code 2134137ff4cSJacques Vidrine get_server(krb5_context context, 2144137ff4cSJacques Vidrine krb5_principal client, 2154137ff4cSJacques Vidrine const char *server, 2164137ff4cSJacques Vidrine krb5_principal *princ) 2174137ff4cSJacques Vidrine { 218*ae771770SStanislav Sedov krb5_const_realm realm; 2194137ff4cSJacques Vidrine if(server) 2204137ff4cSJacques Vidrine return krb5_parse_name(context, server, princ); 2214137ff4cSJacques Vidrine 222*ae771770SStanislav Sedov realm = krb5_principal_get_realm(context, client); 223*ae771770SStanislav Sedov return krb5_make_principal(context, princ, realm, 224*ae771770SStanislav Sedov KRB5_TGS_NAME, realm, NULL); 2254137ff4cSJacques Vidrine } 2264137ff4cSJacques Vidrine 227b528cefcSMark Murray static int 228b528cefcSMark Murray renew_validate(krb5_context context, 229b528cefcSMark Murray int renew, 230b528cefcSMark Murray int validate, 231b528cefcSMark Murray krb5_ccache cache, 232b528cefcSMark Murray const char *server, 233b528cefcSMark Murray krb5_deltat life) 234b528cefcSMark Murray { 235b528cefcSMark Murray krb5_error_code ret; 236c19800e8SDoug Rabson krb5_creds in, *out = NULL; 237b528cefcSMark Murray krb5_kdc_flags flags; 238b528cefcSMark Murray 239b528cefcSMark Murray memset(&in, 0, sizeof(in)); 240b528cefcSMark Murray 241b528cefcSMark Murray ret = krb5_cc_get_principal(context, cache, &in.client); 242b528cefcSMark Murray if(ret) { 243b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_get_principal"); 244b528cefcSMark Murray return ret; 245b528cefcSMark Murray } 2464137ff4cSJacques Vidrine ret = get_server(context, in.client, server, &in.server); 247b528cefcSMark Murray if(ret) { 2484137ff4cSJacques Vidrine krb5_warn(context, ret, "get_server"); 249b528cefcSMark Murray goto out; 250b528cefcSMark Murray } 251c19800e8SDoug Rabson 252c19800e8SDoug Rabson if (renew) { 253c19800e8SDoug Rabson /* 254c19800e8SDoug Rabson * no need to check the error here, it's only to be 255c19800e8SDoug Rabson * friendly to the user 256c19800e8SDoug Rabson */ 257c19800e8SDoug Rabson krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out); 258c19800e8SDoug Rabson } 259c19800e8SDoug Rabson 260b528cefcSMark Murray flags.i = 0; 261b528cefcSMark Murray flags.b.renewable = flags.b.renew = renew; 262b528cefcSMark Murray flags.b.validate = validate; 263c19800e8SDoug Rabson 264adb0ddaeSAssar Westerlund if (forwardable_flag != -1) 2655e9cd1aeSAssar Westerlund flags.b.forwardable = forwardable_flag; 266c19800e8SDoug Rabson else if (out) 267c19800e8SDoug Rabson flags.b.forwardable = out->flags.b.forwardable; 268c19800e8SDoug Rabson 269adb0ddaeSAssar Westerlund if (proxiable_flag != -1) 2705e9cd1aeSAssar Westerlund flags.b.proxiable = proxiable_flag; 271c19800e8SDoug Rabson else if (out) 272c19800e8SDoug Rabson flags.b.proxiable = out->flags.b.proxiable; 273c19800e8SDoug Rabson 274*ae771770SStanislav Sedov if (anonymous_flag) 2755e9cd1aeSAssar Westerlund flags.b.request_anonymous = anonymous_flag; 276b528cefcSMark Murray if(life) 277b528cefcSMark Murray in.times.endtime = time(NULL) + life; 278b528cefcSMark Murray 279c19800e8SDoug Rabson if (out) { 280c19800e8SDoug Rabson krb5_free_creds (context, out); 281c19800e8SDoug Rabson out = NULL; 282c19800e8SDoug Rabson } 283c19800e8SDoug Rabson 284c19800e8SDoug Rabson 285b528cefcSMark Murray ret = krb5_get_kdc_cred(context, 286b528cefcSMark Murray cache, 287b528cefcSMark Murray flags, 288b528cefcSMark Murray NULL, 289b528cefcSMark Murray NULL, 290b528cefcSMark Murray &in, 291b528cefcSMark Murray &out); 292b528cefcSMark Murray if(ret) { 293b528cefcSMark Murray krb5_warn(context, ret, "krb5_get_kdc_cred"); 294b528cefcSMark Murray goto out; 295b528cefcSMark Murray } 296b528cefcSMark Murray ret = krb5_cc_initialize(context, cache, in.client); 297b528cefcSMark Murray if(ret) { 298b528cefcSMark Murray krb5_free_creds (context, out); 299b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_initialize"); 300b528cefcSMark Murray goto out; 301b528cefcSMark Murray } 302b528cefcSMark Murray ret = krb5_cc_store_cred(context, cache, out); 3034137ff4cSJacques Vidrine 3044137ff4cSJacques Vidrine if(ret == 0 && server == NULL) { 3054137ff4cSJacques Vidrine /* only do this if it's a general renew-my-tgt request */ 306*ae771770SStanislav Sedov #ifndef NO_AFS 3074137ff4cSJacques Vidrine if(do_afslog && k_hasafs()) 3084137ff4cSJacques Vidrine krb5_afslog(context, cache, NULL, NULL); 309*ae771770SStanislav Sedov #endif 3104137ff4cSJacques Vidrine } 3114137ff4cSJacques Vidrine 312b528cefcSMark Murray krb5_free_creds (context, out); 313b528cefcSMark Murray if(ret) { 314b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_store_cred"); 315b528cefcSMark Murray goto out; 316b528cefcSMark Murray } 317b528cefcSMark Murray out: 318c19800e8SDoug Rabson krb5_free_cred_contents(context, &in); 319b528cefcSMark Murray return ret; 320b528cefcSMark Murray } 321b528cefcSMark Murray 322*ae771770SStanislav Sedov #ifndef NO_NTLM 323*ae771770SStanislav Sedov 3244137ff4cSJacques Vidrine static krb5_error_code 325c19800e8SDoug Rabson store_ntlmkey(krb5_context context, krb5_ccache id, 326*ae771770SStanislav Sedov const char *domain, struct ntlm_buf *buf) 327c19800e8SDoug Rabson { 328c19800e8SDoug Rabson krb5_error_code ret; 329*ae771770SStanislav Sedov krb5_data data; 330*ae771770SStanislav Sedov char *name; 331c19800e8SDoug Rabson 332*ae771770SStanislav Sedov asprintf(&name, "ntlm-key-%s", domain); 333*ae771770SStanislav Sedov if (name == NULL) { 334*ae771770SStanislav Sedov krb5_clear_error_message(context); 335*ae771770SStanislav Sedov return ENOMEM; 336c19800e8SDoug Rabson } 337c19800e8SDoug Rabson 338*ae771770SStanislav Sedov data.length = buf->length; 339*ae771770SStanislav Sedov data.data = buf->data; 340*ae771770SStanislav Sedov 341*ae771770SStanislav Sedov ret = krb5_cc_set_config(context, id, NULL, name, &data); 342*ae771770SStanislav Sedov free(name); 343*ae771770SStanislav Sedov return ret; 344*ae771770SStanislav Sedov } 345*ae771770SStanislav Sedov #endif 346*ae771770SStanislav Sedov 347c19800e8SDoug Rabson static krb5_error_code 3484137ff4cSJacques Vidrine get_new_tickets(krb5_context context, 3494137ff4cSJacques Vidrine krb5_principal principal, 3504137ff4cSJacques Vidrine krb5_ccache ccache, 351c19800e8SDoug Rabson krb5_deltat ticket_life, 352c19800e8SDoug Rabson int interactive) 353b528cefcSMark Murray { 354b528cefcSMark Murray krb5_error_code ret; 355c19800e8SDoug Rabson krb5_get_init_creds_opt *opt; 3564137ff4cSJacques Vidrine krb5_creds cred; 3575e9cd1aeSAssar Westerlund char passwd[256]; 3584137ff4cSJacques Vidrine krb5_deltat start_time = 0; 3598373020dSJacques Vidrine krb5_deltat renew = 0; 360*ae771770SStanislav Sedov const char *renewstr = NULL; 361c19800e8SDoug Rabson krb5_enctype *enctype = NULL; 362c19800e8SDoug Rabson krb5_ccache tempccache; 363*ae771770SStanislav Sedov #ifndef NO_NTLM 364*ae771770SStanislav Sedov struct ntlm_buf ntlmkey; 365c19800e8SDoug Rabson memset(&ntlmkey, 0, sizeof(ntlmkey)); 366*ae771770SStanislav Sedov #endif 367c19800e8SDoug Rabson passwd[0] = '\0'; 368c19800e8SDoug Rabson 369c19800e8SDoug Rabson if (password_file) { 370c19800e8SDoug Rabson FILE *f; 371c19800e8SDoug Rabson 372c19800e8SDoug Rabson if (strcasecmp("STDIN", password_file) == 0) 373c19800e8SDoug Rabson f = stdin; 374c19800e8SDoug Rabson else 375c19800e8SDoug Rabson f = fopen(password_file, "r"); 376c19800e8SDoug Rabson if (f == NULL) 377c19800e8SDoug Rabson krb5_errx(context, 1, "Failed to open the password file %s", 378c19800e8SDoug Rabson password_file); 379c19800e8SDoug Rabson 380c19800e8SDoug Rabson if (fgets(passwd, sizeof(passwd), f) == NULL) 381c19800e8SDoug Rabson krb5_errx(context, 1, 382*ae771770SStanislav Sedov N_("Failed to read password from file %s", ""), 383*ae771770SStanislav Sedov password_file); 384c19800e8SDoug Rabson if (f != stdin) 385c19800e8SDoug Rabson fclose(f); 386c19800e8SDoug Rabson passwd[strcspn(passwd, "\n")] = '\0'; 387c19800e8SDoug Rabson } 388c19800e8SDoug Rabson 389*ae771770SStanislav Sedov #ifdef __APPLE__ 390*ae771770SStanislav Sedov if (passwd[0] == '\0') { 391*ae771770SStanislav Sedov const char *realm; 392*ae771770SStanislav Sedov OSStatus osret; 393*ae771770SStanislav Sedov UInt32 length; 394*ae771770SStanislav Sedov void *buffer; 395*ae771770SStanislav Sedov char *name; 396*ae771770SStanislav Sedov 397*ae771770SStanislav Sedov realm = krb5_principal_get_realm(context, principal); 398*ae771770SStanislav Sedov 399*ae771770SStanislav Sedov ret = krb5_unparse_name_flags(context, principal, 400*ae771770SStanislav Sedov KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); 401*ae771770SStanislav Sedov if (ret) 402*ae771770SStanislav Sedov goto nopassword; 403*ae771770SStanislav Sedov 404*ae771770SStanislav Sedov osret = SecKeychainFindGenericPassword(NULL, strlen(realm), realm, 405*ae771770SStanislav Sedov strlen(name), name, 406*ae771770SStanislav Sedov &length, &buffer, NULL); 407*ae771770SStanislav Sedov free(name); 408*ae771770SStanislav Sedov if (osret == noErr && length < sizeof(passwd) - 1) { 409*ae771770SStanislav Sedov memcpy(passwd, buffer, length); 410*ae771770SStanislav Sedov passwd[length] = '\0'; 411*ae771770SStanislav Sedov } 412*ae771770SStanislav Sedov nopassword: 413*ae771770SStanislav Sedov do { } while(0); 414*ae771770SStanislav Sedov } 415*ae771770SStanislav Sedov #endif 416b528cefcSMark Murray 417b528cefcSMark Murray memset(&cred, 0, sizeof(cred)); 418b528cefcSMark Murray 419c19800e8SDoug Rabson ret = krb5_get_init_creds_opt_alloc (context, &opt); 420c19800e8SDoug Rabson if (ret) 421c19800e8SDoug Rabson krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); 422b528cefcSMark Murray 4235e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_default_flags(context, "kinit", 424c19800e8SDoug Rabson krb5_principal_get_realm(context, principal), opt); 4255e9cd1aeSAssar Westerlund 4265e9cd1aeSAssar Westerlund if(forwardable_flag != -1) 427c19800e8SDoug Rabson krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag); 4285e9cd1aeSAssar Westerlund if(proxiable_flag != -1) 429c19800e8SDoug Rabson krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag); 430*ae771770SStanislav Sedov if(anonymous_flag) 431c19800e8SDoug Rabson krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag); 432c19800e8SDoug Rabson if (pac_flag != -1) 433c19800e8SDoug Rabson krb5_get_init_creds_opt_set_pac_request(context, opt, 434c19800e8SDoug Rabson pac_flag ? TRUE : FALSE); 435c19800e8SDoug Rabson if (canonicalize_flag) 436c19800e8SDoug Rabson krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); 437*ae771770SStanislav Sedov if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag) 438*ae771770SStanislav Sedov krb5_get_init_creds_opt_set_win2k(context, opt, TRUE); 439*ae771770SStanislav Sedov if (pk_user_id || ent_user_id || anonymous_flag) { 440c19800e8SDoug Rabson ret = krb5_get_init_creds_opt_set_pkinit(context, opt, 441c19800e8SDoug Rabson principal, 442c19800e8SDoug Rabson pk_user_id, 443c19800e8SDoug Rabson pk_x509_anchors, 444c19800e8SDoug Rabson NULL, 445c19800e8SDoug Rabson NULL, 446*ae771770SStanislav Sedov pk_use_enckey ? 2 : 0 | 447*ae771770SStanislav Sedov anonymous_flag ? 4 : 0, 448c19800e8SDoug Rabson krb5_prompter_posix, 449c19800e8SDoug Rabson NULL, 450c19800e8SDoug Rabson passwd); 451c19800e8SDoug Rabson if (ret) 452c19800e8SDoug Rabson krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit"); 453*ae771770SStanislav Sedov if (ent_user_id) 454*ae771770SStanislav Sedov krb5_get_init_creds_opt_set_pkinit_user_certs(context, opt, ent_user_id); 455b528cefcSMark Murray } 456b528cefcSMark Murray 457c19800e8SDoug Rabson if (addrs_flag != -1) 458c19800e8SDoug Rabson krb5_get_init_creds_opt_set_addressless(context, opt, 459c19800e8SDoug Rabson addrs_flag ? FALSE : TRUE); 460b528cefcSMark Murray 461c19800e8SDoug Rabson if (renew_life == NULL && renewable_flag) 462c19800e8SDoug Rabson renewstr = "1 month"; 463c19800e8SDoug Rabson if (renew_life) 464c19800e8SDoug Rabson renewstr = renew_life; 465c19800e8SDoug Rabson if (renewstr) { 466c19800e8SDoug Rabson renew = parse_time (renewstr, "s"); 467c19800e8SDoug Rabson if (renew < 0) 468c19800e8SDoug Rabson errx (1, "unparsable time: %s", renewstr); 469c19800e8SDoug Rabson 470c19800e8SDoug Rabson krb5_get_init_creds_opt_set_renew_life (opt, renew); 4711c43270aSJacques Vidrine } 4728373020dSJacques Vidrine 473b528cefcSMark Murray if(ticket_life != 0) 474c19800e8SDoug Rabson krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life); 475b528cefcSMark Murray 476b528cefcSMark Murray if(start_str) { 477b528cefcSMark Murray int tmp = parse_time (start_str, "s"); 478b528cefcSMark Murray if (tmp < 0) 479*ae771770SStanislav Sedov errx (1, N_("unparsable time: %s", ""), start_str); 480b528cefcSMark Murray 481b528cefcSMark Murray start_time = tmp; 482b528cefcSMark Murray } 483b528cefcSMark Murray 484b528cefcSMark Murray if(etype_str.num_strings) { 485b528cefcSMark Murray int i; 486c19800e8SDoug Rabson 487b528cefcSMark Murray enctype = malloc(etype_str.num_strings * sizeof(*enctype)); 488b528cefcSMark Murray if(enctype == NULL) 489b528cefcSMark Murray errx(1, "out of memory"); 490b528cefcSMark Murray for(i = 0; i < etype_str.num_strings; i++) { 491b528cefcSMark Murray ret = krb5_string_to_enctype(context, 492b528cefcSMark Murray etype_str.strings[i], 493b528cefcSMark Murray &enctype[i]); 494b528cefcSMark Murray if(ret) 495b528cefcSMark Murray errx(1, "unrecognized enctype: %s", etype_str.strings[i]); 496b528cefcSMark Murray } 497c19800e8SDoug Rabson krb5_get_init_creds_opt_set_etype_list(opt, enctype, 498b528cefcSMark Murray etype_str.num_strings); 499b528cefcSMark Murray } 500b528cefcSMark Murray 501b528cefcSMark Murray if(use_keytab || keytab_str) { 502b528cefcSMark Murray krb5_keytab kt; 503b528cefcSMark Murray if(keytab_str) 504b528cefcSMark Murray ret = krb5_kt_resolve(context, keytab_str, &kt); 505b528cefcSMark Murray else 506b528cefcSMark Murray ret = krb5_kt_default(context, &kt); 507b528cefcSMark Murray if (ret) 508b528cefcSMark Murray krb5_err (context, 1, ret, "resolving keytab"); 509b528cefcSMark Murray ret = krb5_get_init_creds_keytab (context, 510b528cefcSMark Murray &cred, 511b528cefcSMark Murray principal, 512b528cefcSMark Murray kt, 513b528cefcSMark Murray start_time, 514c19800e8SDoug Rabson server_str, 515c19800e8SDoug Rabson opt); 516b528cefcSMark Murray krb5_kt_close(context, kt); 517*ae771770SStanislav Sedov } else if (pk_user_id || ent_user_id || anonymous_flag) { 518c19800e8SDoug Rabson ret = krb5_get_init_creds_password (context, 519c19800e8SDoug Rabson &cred, 520c19800e8SDoug Rabson principal, 521c19800e8SDoug Rabson passwd, 522c19800e8SDoug Rabson krb5_prompter_posix, 523c19800e8SDoug Rabson NULL, 524c19800e8SDoug Rabson start_time, 525c19800e8SDoug Rabson server_str, 526c19800e8SDoug Rabson opt); 527c19800e8SDoug Rabson } else if (!interactive) { 528c19800e8SDoug Rabson krb5_warnx(context, "Not interactive, failed to get initial ticket"); 529c19800e8SDoug Rabson krb5_get_init_creds_opt_free(context, opt); 530c19800e8SDoug Rabson return 0; 5315e9cd1aeSAssar Westerlund } else { 532c19800e8SDoug Rabson 533c19800e8SDoug Rabson if (passwd[0] == '\0') { 5345e9cd1aeSAssar Westerlund char *p, *prompt; 5355e9cd1aeSAssar Westerlund 5365e9cd1aeSAssar Westerlund krb5_unparse_name (context, principal, &p); 537*ae771770SStanislav Sedov asprintf (&prompt, N_("%s's Password: ", ""), p); 5385e9cd1aeSAssar Westerlund free (p); 5395e9cd1aeSAssar Westerlund 540c19800e8SDoug Rabson if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){ 5415e9cd1aeSAssar Westerlund memset(passwd, 0, sizeof(passwd)); 5425e9cd1aeSAssar Westerlund exit(1); 5435e9cd1aeSAssar Westerlund } 5445e9cd1aeSAssar Westerlund free (prompt); 545c19800e8SDoug Rabson } 546c19800e8SDoug Rabson 5475e9cd1aeSAssar Westerlund 548b528cefcSMark Murray ret = krb5_get_init_creds_password (context, 549b528cefcSMark Murray &cred, 550b528cefcSMark Murray principal, 5515e9cd1aeSAssar Westerlund passwd, 552b528cefcSMark Murray krb5_prompter_posix, 553b528cefcSMark Murray NULL, 554b528cefcSMark Murray start_time, 555c19800e8SDoug Rabson server_str, 556c19800e8SDoug Rabson opt); 5575e9cd1aeSAssar Westerlund } 558c19800e8SDoug Rabson krb5_get_init_creds_opt_free(context, opt); 559*ae771770SStanislav Sedov #ifndef NO_NTLM 560c19800e8SDoug Rabson if (ntlm_domain && passwd[0]) 561c19800e8SDoug Rabson heim_ntlm_nt_key(passwd, &ntlmkey); 562*ae771770SStanislav Sedov #endif 5635e9cd1aeSAssar Westerlund memset(passwd, 0, sizeof(passwd)); 5645e9cd1aeSAssar Westerlund 565b528cefcSMark Murray switch(ret){ 566b528cefcSMark Murray case 0: 567b528cefcSMark Murray break; 568b528cefcSMark Murray case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */ 569b528cefcSMark Murray exit(1); 570b528cefcSMark Murray case KRB5KRB_AP_ERR_BAD_INTEGRITY: 571b528cefcSMark Murray case KRB5KRB_AP_ERR_MODIFIED: 572c19800e8SDoug Rabson case KRB5KDC_ERR_PREAUTH_FAILED: 573*ae771770SStanislav Sedov krb5_errx(context, 1, N_("Password incorrect", "")); 574b528cefcSMark Murray break; 575c19800e8SDoug Rabson case KRB5KRB_AP_ERR_V4_REPLY: 576*ae771770SStanislav Sedov krb5_errx(context, 1, N_("Looks like a Kerberos 4 reply", "")); 577c19800e8SDoug Rabson break; 578b528cefcSMark Murray default: 579b528cefcSMark Murray krb5_err(context, 1, ret, "krb5_get_init_creds"); 580b528cefcSMark Murray } 581b528cefcSMark Murray 5828373020dSJacques Vidrine if(ticket_life != 0) { 5838373020dSJacques Vidrine if(abs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) { 584c19800e8SDoug Rabson char life[64]; 585c19800e8SDoug Rabson unparse_time_approx(cred.times.endtime - cred.times.starttime, 5868373020dSJacques Vidrine life, sizeof(life)); 587*ae771770SStanislav Sedov krb5_warnx(context, N_("NOTICE: ticket lifetime is %s", ""), life); 5888373020dSJacques Vidrine } 5898373020dSJacques Vidrine } 590c19800e8SDoug Rabson if(renew_life) { 5918373020dSJacques Vidrine if(abs(cred.times.renew_till - cred.times.starttime - renew) > 30) { 592c19800e8SDoug Rabson char life[64]; 593c19800e8SDoug Rabson unparse_time_approx(cred.times.renew_till - cred.times.starttime, 5948373020dSJacques Vidrine life, sizeof(life)); 595*ae771770SStanislav Sedov krb5_warnx(context, 596*ae771770SStanislav Sedov N_("NOTICE: ticket renewable lifetime is %s", ""), 5978373020dSJacques Vidrine life); 5988373020dSJacques Vidrine } 5998373020dSJacques Vidrine } 6008373020dSJacques Vidrine 601c19800e8SDoug Rabson ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache), 602c19800e8SDoug Rabson NULL, &tempccache); 603c19800e8SDoug Rabson if (ret) 604c19800e8SDoug Rabson krb5_err (context, 1, ret, "krb5_cc_new_unique"); 605c19800e8SDoug Rabson 606c19800e8SDoug Rabson ret = krb5_cc_initialize (context, tempccache, cred.client); 607b528cefcSMark Murray if (ret) 608b528cefcSMark Murray krb5_err (context, 1, ret, "krb5_cc_initialize"); 609b528cefcSMark Murray 610c19800e8SDoug Rabson ret = krb5_cc_store_cred (context, tempccache, &cred); 611b528cefcSMark Murray if (ret) 612b528cefcSMark Murray krb5_err (context, 1, ret, "krb5_cc_store_cred"); 613b528cefcSMark Murray 614c19800e8SDoug Rabson krb5_free_cred_contents (context, &cred); 615c19800e8SDoug Rabson 616c19800e8SDoug Rabson ret = krb5_cc_move(context, tempccache, ccache); 617c19800e8SDoug Rabson if (ret) 618c19800e8SDoug Rabson krb5_err (context, 1, ret, "krb5_cc_move"); 619c19800e8SDoug Rabson 620*ae771770SStanislav Sedov if (switch_cache_flags) 621*ae771770SStanislav Sedov krb5_cc_switch(context, ccache); 622*ae771770SStanislav Sedov 623*ae771770SStanislav Sedov #ifndef NO_NTLM 624c19800e8SDoug Rabson if (ntlm_domain && ntlmkey.data) 625*ae771770SStanislav Sedov store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey); 626*ae771770SStanislav Sedov #endif 627*ae771770SStanislav Sedov 628*ae771770SStanislav Sedov if (ok_as_delegate_flag || windows_flag || use_referrals_flag) { 629*ae771770SStanislav Sedov unsigned char d = 0; 630*ae771770SStanislav Sedov krb5_data data; 631*ae771770SStanislav Sedov 632*ae771770SStanislav Sedov if (ok_as_delegate_flag || windows_flag) 633*ae771770SStanislav Sedov d |= 1; 634*ae771770SStanislav Sedov if (use_referrals_flag || windows_flag) 635*ae771770SStanislav Sedov d |= 2; 636*ae771770SStanislav Sedov 637*ae771770SStanislav Sedov data.length = 1; 638*ae771770SStanislav Sedov data.data = &d; 639*ae771770SStanislav Sedov 640*ae771770SStanislav Sedov krb5_cc_set_config(context, ccache, NULL, "realm-config", &data); 641*ae771770SStanislav Sedov } 642*ae771770SStanislav Sedov 643c19800e8SDoug Rabson 644c19800e8SDoug Rabson if (enctype) 645c19800e8SDoug Rabson free(enctype); 6464137ff4cSJacques Vidrine 6474137ff4cSJacques Vidrine return 0; 648b528cefcSMark Murray } 6494137ff4cSJacques Vidrine 650c19800e8SDoug Rabson static time_t 651c19800e8SDoug Rabson ticket_lifetime(krb5_context context, krb5_ccache cache, 652c19800e8SDoug Rabson krb5_principal client, const char *server) 653c19800e8SDoug Rabson { 654c19800e8SDoug Rabson krb5_creds in_cred, *cred; 655c19800e8SDoug Rabson krb5_error_code ret; 656c19800e8SDoug Rabson time_t timeout; 657c19800e8SDoug Rabson 658c19800e8SDoug Rabson memset(&in_cred, 0, sizeof(in_cred)); 659c19800e8SDoug Rabson 660c19800e8SDoug Rabson ret = krb5_cc_get_principal(context, cache, &in_cred.client); 661c19800e8SDoug Rabson if(ret) { 662c19800e8SDoug Rabson krb5_warn(context, ret, "krb5_cc_get_principal"); 663c19800e8SDoug Rabson return 0; 664c19800e8SDoug Rabson } 665c19800e8SDoug Rabson ret = get_server(context, in_cred.client, server, &in_cred.server); 666c19800e8SDoug Rabson if(ret) { 667c19800e8SDoug Rabson krb5_free_principal(context, in_cred.client); 668c19800e8SDoug Rabson krb5_warn(context, ret, "get_server"); 669c19800e8SDoug Rabson return 0; 670c19800e8SDoug Rabson } 671c19800e8SDoug Rabson 672c19800e8SDoug Rabson ret = krb5_get_credentials(context, KRB5_GC_CACHED, 673c19800e8SDoug Rabson cache, &in_cred, &cred); 674c19800e8SDoug Rabson krb5_free_principal(context, in_cred.client); 675c19800e8SDoug Rabson krb5_free_principal(context, in_cred.server); 676c19800e8SDoug Rabson if(ret) { 677c19800e8SDoug Rabson krb5_warn(context, ret, "krb5_get_credentials"); 678c19800e8SDoug Rabson return 0; 679c19800e8SDoug Rabson } 680c19800e8SDoug Rabson timeout = cred->times.endtime - cred->times.starttime; 681c19800e8SDoug Rabson if (timeout < 0) 682c19800e8SDoug Rabson timeout = 0; 683c19800e8SDoug Rabson krb5_free_creds(context, cred); 684c19800e8SDoug Rabson return timeout; 685c19800e8SDoug Rabson } 686c19800e8SDoug Rabson 687c19800e8SDoug Rabson struct renew_ctx { 688c19800e8SDoug Rabson krb5_context context; 689c19800e8SDoug Rabson krb5_ccache ccache; 690c19800e8SDoug Rabson krb5_principal principal; 691c19800e8SDoug Rabson krb5_deltat ticket_life; 692c19800e8SDoug Rabson }; 693c19800e8SDoug Rabson 694c19800e8SDoug Rabson static time_t 695c19800e8SDoug Rabson renew_func(void *ptr) 696c19800e8SDoug Rabson { 697c19800e8SDoug Rabson struct renew_ctx *ctx = ptr; 698c19800e8SDoug Rabson krb5_error_code ret; 699c19800e8SDoug Rabson time_t expire; 700c19800e8SDoug Rabson int new_tickets = 0; 701c19800e8SDoug Rabson 702c19800e8SDoug Rabson if (renewable_flag) { 703c19800e8SDoug Rabson ret = renew_validate(ctx->context, renewable_flag, validate_flag, 704c19800e8SDoug Rabson ctx->ccache, server_str, ctx->ticket_life); 705c19800e8SDoug Rabson if (ret) 706c19800e8SDoug Rabson new_tickets = 1; 707c19800e8SDoug Rabson } else 708c19800e8SDoug Rabson new_tickets = 1; 709c19800e8SDoug Rabson 710c19800e8SDoug Rabson if (new_tickets) 711c19800e8SDoug Rabson get_new_tickets(ctx->context, ctx->principal, 712c19800e8SDoug Rabson ctx->ccache, ctx->ticket_life, 0); 713c19800e8SDoug Rabson 714*ae771770SStanislav Sedov #ifndef NO_AFS 715c19800e8SDoug Rabson if(do_afslog && k_hasafs()) 716c19800e8SDoug Rabson krb5_afslog(ctx->context, ctx->ccache, NULL, NULL); 717*ae771770SStanislav Sedov #endif 718c19800e8SDoug Rabson 719c19800e8SDoug Rabson expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal, 720c19800e8SDoug Rabson server_str) / 2; 721c19800e8SDoug Rabson return expire + 1; 722c19800e8SDoug Rabson } 723c19800e8SDoug Rabson 7244137ff4cSJacques Vidrine int 7254137ff4cSJacques Vidrine main (int argc, char **argv) 7264137ff4cSJacques Vidrine { 7274137ff4cSJacques Vidrine krb5_error_code ret; 7284137ff4cSJacques Vidrine krb5_context context; 7294137ff4cSJacques Vidrine krb5_ccache ccache; 7304137ff4cSJacques Vidrine krb5_principal principal; 731c19800e8SDoug Rabson int optidx = 0; 7324137ff4cSJacques Vidrine krb5_deltat ticket_life = 0; 733c19800e8SDoug Rabson int parseflags = 0; 7344137ff4cSJacques Vidrine 7354137ff4cSJacques Vidrine setprogname (argv[0]); 7364137ff4cSJacques Vidrine 737*ae771770SStanislav Sedov setlocale (LC_ALL, ""); 738*ae771770SStanislav Sedov bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); 739*ae771770SStanislav Sedov textdomain("heimdal_kuser"); 740*ae771770SStanislav Sedov 7414137ff4cSJacques Vidrine ret = krb5_init_context (&context); 742c19800e8SDoug Rabson if (ret == KRB5_CONFIG_BADFORMAT) 743c19800e8SDoug Rabson errx (1, "krb5_init_context failed to parse configuration file"); 744c19800e8SDoug Rabson else if (ret) 7454137ff4cSJacques Vidrine errx(1, "krb5_init_context failed: %d", ret); 7464137ff4cSJacques Vidrine 747c19800e8SDoug Rabson if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) 7484137ff4cSJacques Vidrine usage(1); 7494137ff4cSJacques Vidrine 7504137ff4cSJacques Vidrine if (help_flag) 7514137ff4cSJacques Vidrine usage (0); 7524137ff4cSJacques Vidrine 7534137ff4cSJacques Vidrine if(version_flag) { 7544137ff4cSJacques Vidrine print_version(NULL); 7554137ff4cSJacques Vidrine exit(0); 7564137ff4cSJacques Vidrine } 7574137ff4cSJacques Vidrine 758c19800e8SDoug Rabson argc -= optidx; 759c19800e8SDoug Rabson argv += optidx; 760c19800e8SDoug Rabson 761*ae771770SStanislav Sedov if (canonicalize_flag || enterprise_flag) 762c19800e8SDoug Rabson parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE; 7634137ff4cSJacques Vidrine 764*ae771770SStanislav Sedov if (pk_enterprise_flag) { 765*ae771770SStanislav Sedov ret = krb5_pk_enterprise_cert(context, pk_user_id, 766*ae771770SStanislav Sedov argv[0], &principal, 767*ae771770SStanislav Sedov &ent_user_id); 768*ae771770SStanislav Sedov if (ret) 769*ae771770SStanislav Sedov krb5_err(context, 1, ret, "krb5_pk_enterprise_certs"); 770*ae771770SStanislav Sedov 771*ae771770SStanislav Sedov pk_user_id = NULL; 772*ae771770SStanislav Sedov 773*ae771770SStanislav Sedov } else if (anonymous_flag) { 774*ae771770SStanislav Sedov 775*ae771770SStanislav Sedov ret = krb5_make_principal(context, &principal, argv[0], 776*ae771770SStanislav Sedov KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME, 777*ae771770SStanislav Sedov NULL); 778*ae771770SStanislav Sedov if (ret) 779*ae771770SStanislav Sedov krb5_err(context, 1, ret, "krb5_make_principal"); 780*ae771770SStanislav Sedov krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN); 781*ae771770SStanislav Sedov 782*ae771770SStanislav Sedov } else { 7834137ff4cSJacques Vidrine if (argv[0]) { 784*ae771770SStanislav Sedov ret = krb5_parse_name_flags (context, argv[0], parseflags, 785*ae771770SStanislav Sedov &principal); 7864137ff4cSJacques Vidrine if (ret) 7874137ff4cSJacques Vidrine krb5_err (context, 1, ret, "krb5_parse_name"); 7884137ff4cSJacques Vidrine } else { 789c19800e8SDoug Rabson ret = krb5_get_default_principal (context, &principal); 7904137ff4cSJacques Vidrine if (ret) 7914137ff4cSJacques Vidrine krb5_err (context, 1, ret, "krb5_get_default_principal"); 7924137ff4cSJacques Vidrine } 793*ae771770SStanislav Sedov } 7944137ff4cSJacques Vidrine 7954137ff4cSJacques Vidrine if(fcache_version) 7964137ff4cSJacques Vidrine krb5_set_fcache_version(context, fcache_version); 7974137ff4cSJacques Vidrine 798c19800e8SDoug Rabson if(renewable_flag == -1) 799c19800e8SDoug Rabson /* this seems somewhat pointless, but whatever */ 800c19800e8SDoug Rabson krb5_appdefault_boolean(context, "kinit", 801c19800e8SDoug Rabson krb5_principal_get_realm(context, principal), 802c19800e8SDoug Rabson "renewable", FALSE, &renewable_flag); 803c19800e8SDoug Rabson if(do_afslog == -1) 804c19800e8SDoug Rabson krb5_appdefault_boolean(context, "kinit", 805c19800e8SDoug Rabson krb5_principal_get_realm(context, principal), 806c19800e8SDoug Rabson "afslog", TRUE, &do_afslog); 807c19800e8SDoug Rabson 8084137ff4cSJacques Vidrine if(cred_cache) 8094137ff4cSJacques Vidrine ret = krb5_cc_resolve(context, cred_cache, &ccache); 8104137ff4cSJacques Vidrine else { 8114137ff4cSJacques Vidrine if(argc > 1) { 8124137ff4cSJacques Vidrine char s[1024]; 813*ae771770SStanislav Sedov ret = krb5_cc_new_unique(context, NULL, NULL, &ccache); 8144137ff4cSJacques Vidrine if(ret) 8154137ff4cSJacques Vidrine krb5_err(context, 1, ret, "creating cred cache"); 8164137ff4cSJacques Vidrine snprintf(s, sizeof(s), "%s:%s", 8174137ff4cSJacques Vidrine krb5_cc_get_type(context, ccache), 8184137ff4cSJacques Vidrine krb5_cc_get_name(context, ccache)); 8194137ff4cSJacques Vidrine setenv("KRB5CCNAME", s, 1); 820c19800e8SDoug Rabson } else { 821*ae771770SStanislav Sedov ret = krb5_cc_cache_match(context, principal, &ccache); 822*ae771770SStanislav Sedov if (ret) { 823*ae771770SStanislav Sedov const char *type; 8244137ff4cSJacques Vidrine ret = krb5_cc_default (context, &ccache); 825*ae771770SStanislav Sedov if (ret) 826*ae771770SStanislav Sedov krb5_err (context, 1, ret, N_("resolving credentials cache", "")); 827*ae771770SStanislav Sedov 828*ae771770SStanislav Sedov /* 829*ae771770SStanislav Sedov * Check if the type support switching, and we do, 830*ae771770SStanislav Sedov * then do that instead over overwriting the current 831*ae771770SStanislav Sedov * default credential 832*ae771770SStanislav Sedov */ 833*ae771770SStanislav Sedov type = krb5_cc_get_type(context, ccache); 834*ae771770SStanislav Sedov if (krb5_cc_support_switch(context, type)) { 835*ae771770SStanislav Sedov krb5_cc_close(context, ccache); 836*ae771770SStanislav Sedov ret = krb5_cc_new_unique(context, type, NULL, &ccache); 837*ae771770SStanislav Sedov } 838*ae771770SStanislav Sedov } 8394137ff4cSJacques Vidrine } 840c19800e8SDoug Rabson } 8414137ff4cSJacques Vidrine if (ret) 842*ae771770SStanislav Sedov krb5_err (context, 1, ret, N_("resolving credentials cache", "")); 8434137ff4cSJacques Vidrine 844*ae771770SStanislav Sedov #ifndef NO_AFS 8458d4ba808SJacques Vidrine if(argc > 1 && k_hasafs ()) 8468d4ba808SJacques Vidrine k_setpag(); 847*ae771770SStanislav Sedov #endif 8488d4ba808SJacques Vidrine 8494137ff4cSJacques Vidrine if (lifetime) { 8504137ff4cSJacques Vidrine int tmp = parse_time (lifetime, "s"); 8514137ff4cSJacques Vidrine if (tmp < 0) 852*ae771770SStanislav Sedov errx (1, N_("unparsable time: %s", ""), lifetime); 8534137ff4cSJacques Vidrine 8544137ff4cSJacques Vidrine ticket_life = tmp; 8554137ff4cSJacques Vidrine } 8564137ff4cSJacques Vidrine 857c19800e8SDoug Rabson if(addrs_flag == 0 && extra_addresses.num_strings > 0) 858*ae771770SStanislav Sedov krb5_errx(context, 1, 859*ae771770SStanislav Sedov N_("specifying both extra addresses and " 860*ae771770SStanislav Sedov "no addresses makes no sense", "")); 8618373020dSJacques Vidrine { 8628373020dSJacques Vidrine int i; 8638373020dSJacques Vidrine krb5_addresses addresses; 8648373020dSJacques Vidrine memset(&addresses, 0, sizeof(addresses)); 8658373020dSJacques Vidrine for(i = 0; i < extra_addresses.num_strings; i++) { 8668373020dSJacques Vidrine ret = krb5_parse_address(context, extra_addresses.strings[i], 8678373020dSJacques Vidrine &addresses); 8688373020dSJacques Vidrine if (ret == 0) { 8698373020dSJacques Vidrine krb5_add_extra_addresses(context, &addresses); 8708373020dSJacques Vidrine krb5_free_addresses(context, &addresses); 8718373020dSJacques Vidrine } 8728373020dSJacques Vidrine } 8738373020dSJacques Vidrine free_getarg_strings(&extra_addresses); 8748373020dSJacques Vidrine } 8758373020dSJacques Vidrine 8764137ff4cSJacques Vidrine if(renew_flag || validate_flag) { 8774137ff4cSJacques Vidrine ret = renew_validate(context, renew_flag, validate_flag, 878c19800e8SDoug Rabson ccache, server_str, ticket_life); 8794137ff4cSJacques Vidrine exit(ret != 0); 8804137ff4cSJacques Vidrine } 8814137ff4cSJacques Vidrine 882c19800e8SDoug Rabson get_new_tickets(context, principal, ccache, ticket_life, 1); 8834137ff4cSJacques Vidrine 884*ae771770SStanislav Sedov #ifndef NO_AFS 885b528cefcSMark Murray if(do_afslog && k_hasafs()) 886b528cefcSMark Murray krb5_afslog(context, ccache, NULL, NULL); 887*ae771770SStanislav Sedov #endif 888adb0ddaeSAssar Westerlund if(argc > 1) { 889c19800e8SDoug Rabson struct renew_ctx ctx; 890c19800e8SDoug Rabson time_t timeout; 891c19800e8SDoug Rabson 892c19800e8SDoug Rabson timeout = ticket_lifetime(context, ccache, principal, server_str) / 2; 893c19800e8SDoug Rabson 894c19800e8SDoug Rabson ctx.context = context; 895c19800e8SDoug Rabson ctx.ccache = ccache; 896c19800e8SDoug Rabson ctx.principal = principal; 897c19800e8SDoug Rabson ctx.ticket_life = ticket_life; 898c19800e8SDoug Rabson 899c19800e8SDoug Rabson ret = simple_execvp_timed(argv[1], argv+1, 900c19800e8SDoug Rabson renew_func, &ctx, timeout); 901c19800e8SDoug Rabson #define EX_NOEXEC 126 902c19800e8SDoug Rabson #define EX_NOTFOUND 127 903c19800e8SDoug Rabson if(ret == EX_NOEXEC) 904*ae771770SStanislav Sedov krb5_warnx(context, N_("permission denied: %s", ""), argv[1]); 905c19800e8SDoug Rabson else if(ret == EX_NOTFOUND) 906*ae771770SStanislav Sedov krb5_warnx(context, N_("command not found: %s", ""), argv[1]); 907c19800e8SDoug Rabson 908adb0ddaeSAssar Westerlund krb5_cc_destroy(context, ccache); 909*ae771770SStanislav Sedov #ifndef NO_AFS 910adb0ddaeSAssar Westerlund if(k_hasafs()) 911adb0ddaeSAssar Westerlund k_unlog(); 912*ae771770SStanislav Sedov #endif 9131c43270aSJacques Vidrine } else { 914b528cefcSMark Murray krb5_cc_close (context, ccache); 9151c43270aSJacques Vidrine ret = 0; 9161c43270aSJacques Vidrine } 9174137ff4cSJacques Vidrine krb5_free_principal(context, principal); 918b528cefcSMark Murray krb5_free_context (context); 9191c43270aSJacques Vidrine return ret; 920b528cefcSMark Murray } 921