1b528cefcSMark Murray /* 28373020dSJacques Vidrine * Copyright (c) 1997-2002 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 "kuser_locl.h" 351c43270aSJacques Vidrine RCSID("$Id: kinit.c,v 1.90.4.4 2004/01/13 10:13:55 lha Exp $"); 365e9cd1aeSAssar Westerlund 375e9cd1aeSAssar Westerlund int forwardable_flag = -1; 385e9cd1aeSAssar Westerlund int proxiable_flag = -1; 395e9cd1aeSAssar Westerlund int renewable_flag = -1; 40b528cefcSMark Murray int renew_flag = 0; 41b528cefcSMark Murray int validate_flag = 0; 42b528cefcSMark Murray int version_flag = 0; 43b528cefcSMark Murray int help_flag = 0; 4413e3f4d6SMark Murray int addrs_flag = 1; 458373020dSJacques Vidrine struct getarg_strings extra_addresses; 465e9cd1aeSAssar Westerlund int anonymous_flag = 0; 47b528cefcSMark Murray char *lifetime = NULL; 48b528cefcSMark Murray char *renew_life = NULL; 49b528cefcSMark Murray char *server = NULL; 50b528cefcSMark Murray char *cred_cache = NULL; 51b528cefcSMark Murray char *start_str = NULL; 52b528cefcSMark Murray struct getarg_strings etype_str; 53b528cefcSMark Murray int use_keytab = 0; 54b528cefcSMark Murray char *keytab_str = NULL; 55bbd80c28SJacques Vidrine int do_afslog = -1; 56b528cefcSMark Murray #ifdef KRB4 574137ff4cSJacques Vidrine int get_v4_tgt = -1; 584137ff4cSJacques Vidrine int convert_524; 59b528cefcSMark Murray #endif 60b528cefcSMark Murray int fcache_version; 61b528cefcSMark Murray 625e9cd1aeSAssar Westerlund static struct getargs args[] = { 63b528cefcSMark Murray #ifdef KRB4 64b528cefcSMark Murray { "524init", '4', arg_flag, &get_v4_tgt, 65b528cefcSMark Murray "obtain version 4 TGT" }, 66b528cefcSMark Murray 674137ff4cSJacques Vidrine { "524convert", '9', arg_flag, &convert_524, 684137ff4cSJacques Vidrine "only convert ticket to version 4" }, 69bbd80c28SJacques Vidrine #endif 70b528cefcSMark Murray { "afslog", 0 , arg_flag, &do_afslog, 71b528cefcSMark Murray "obtain afs tokens" }, 72bbd80c28SJacques Vidrine 73b528cefcSMark Murray { "cache", 'c', arg_string, &cred_cache, 74b528cefcSMark Murray "credentials cache", "cachename" }, 75b528cefcSMark Murray 765e9cd1aeSAssar Westerlund { "forwardable", 'f', arg_flag, &forwardable_flag, 77b528cefcSMark Murray "get forwardable tickets"}, 78b528cefcSMark Murray 79b528cefcSMark Murray { "keytab", 't', arg_string, &keytab_str, 80b528cefcSMark Murray "keytab to use", "keytabname" }, 81b528cefcSMark Murray 82b528cefcSMark Murray { "lifetime", 'l', arg_string, &lifetime, 835e9cd1aeSAssar Westerlund "lifetime of tickets", "time"}, 84b528cefcSMark Murray 855e9cd1aeSAssar Westerlund { "proxiable", 'p', arg_flag, &proxiable_flag, 86b528cefcSMark Murray "get proxiable tickets" }, 87b528cefcSMark Murray 88b528cefcSMark Murray { "renew", 'R', arg_flag, &renew_flag, 89b528cefcSMark Murray "renew TGT" }, 90b528cefcSMark Murray 915e9cd1aeSAssar Westerlund { "renewable", 0, arg_flag, &renewable_flag, 92b528cefcSMark Murray "get renewable tickets" }, 93b528cefcSMark Murray 94b528cefcSMark Murray { "renewable-life", 'r', arg_string, &renew_life, 955e9cd1aeSAssar Westerlund "renewable lifetime of tickets", "time" }, 96b528cefcSMark Murray 97b528cefcSMark Murray { "server", 'S', arg_string, &server, 98b528cefcSMark Murray "server to get ticket for", "principal" }, 99b528cefcSMark Murray 100b528cefcSMark Murray { "start-time", 's', arg_string, &start_str, 1015e9cd1aeSAssar Westerlund "when ticket gets valid", "time" }, 102b528cefcSMark Murray 103b528cefcSMark Murray { "use-keytab", 'k', arg_flag, &use_keytab, 104b528cefcSMark Murray "get key from keytab" }, 105b528cefcSMark Murray 106b528cefcSMark Murray { "validate", 'v', arg_flag, &validate_flag, 107b528cefcSMark Murray "validate TGT" }, 108b528cefcSMark Murray 109b528cefcSMark Murray { "enctypes", 'e', arg_strings, &etype_str, 1105e9cd1aeSAssar Westerlund "encryption types to use", "enctypes" }, 111b528cefcSMark Murray 112b528cefcSMark Murray { "fcache-version", 0, arg_integer, &fcache_version, 113b528cefcSMark Murray "file cache version to create" }, 114b528cefcSMark Murray 11513e3f4d6SMark Murray { "addresses", 0, arg_negative_flag, &addrs_flag, 116b528cefcSMark Murray "request a ticket with no addresses" }, 117b528cefcSMark Murray 1188373020dSJacques Vidrine { "extra-addresses",'a', arg_strings, &extra_addresses, 1198373020dSJacques Vidrine "include these extra addresses", "addresses" }, 1208373020dSJacques Vidrine 1215e9cd1aeSAssar Westerlund { "anonymous", 0, arg_flag, &anonymous_flag, 1225e9cd1aeSAssar Westerlund "request an anonymous ticket" }, 1235e9cd1aeSAssar Westerlund 124b528cefcSMark Murray { "version", 0, arg_flag, &version_flag }, 125b528cefcSMark Murray { "help", 0, arg_flag, &help_flag } 126b528cefcSMark Murray }; 127b528cefcSMark Murray 128b528cefcSMark Murray static void 129b528cefcSMark Murray usage (int ret) 130b528cefcSMark Murray { 131b528cefcSMark Murray arg_printusage (args, 132b528cefcSMark Murray sizeof(args)/sizeof(*args), 133b528cefcSMark Murray NULL, 134adb0ddaeSAssar Westerlund "[principal [command]]"); 135b528cefcSMark Murray exit (ret); 136b528cefcSMark Murray } 137b528cefcSMark Murray 1384137ff4cSJacques Vidrine #ifdef KRB4 1394137ff4cSJacques Vidrine /* for when the KDC tells us it's a v4 one, we try to talk that */ 1404137ff4cSJacques Vidrine 1414137ff4cSJacques Vidrine static int 1424137ff4cSJacques Vidrine key_to_key(const char *user, 1434137ff4cSJacques Vidrine char *instance, 1444137ff4cSJacques Vidrine const char *realm, 1454137ff4cSJacques Vidrine const void *arg, 1464137ff4cSJacques Vidrine des_cblock *key) 1474137ff4cSJacques Vidrine { 1484137ff4cSJacques Vidrine memcpy(key, arg, sizeof(des_cblock)); 1494137ff4cSJacques Vidrine return 0; 1504137ff4cSJacques Vidrine } 1514137ff4cSJacques Vidrine 1524137ff4cSJacques Vidrine static int 1534137ff4cSJacques Vidrine do_v4_fallback (krb5_context context, 1544137ff4cSJacques Vidrine const krb5_principal principal, 1554137ff4cSJacques Vidrine int lifetime, 1564137ff4cSJacques Vidrine int use_srvtab, const char *srvtab_str, 1574137ff4cSJacques Vidrine const char *passwd) 1584137ff4cSJacques Vidrine { 1594137ff4cSJacques Vidrine int ret; 1604137ff4cSJacques Vidrine krb_principal princ; 1614137ff4cSJacques Vidrine des_cblock key; 1624137ff4cSJacques Vidrine krb5_error_code kret; 1634137ff4cSJacques Vidrine 1644137ff4cSJacques Vidrine if (lifetime == 0) 1654137ff4cSJacques Vidrine lifetime = DEFAULT_TKT_LIFE; 1664137ff4cSJacques Vidrine else 1674137ff4cSJacques Vidrine lifetime = krb_time_to_life (0, lifetime); 1684137ff4cSJacques Vidrine 1694137ff4cSJacques Vidrine kret = krb5_524_conv_principal (context, principal, 1704137ff4cSJacques Vidrine princ.name, 1714137ff4cSJacques Vidrine princ.instance, 1724137ff4cSJacques Vidrine princ.realm); 1734137ff4cSJacques Vidrine if (kret) { 1744137ff4cSJacques Vidrine krb5_warn (context, kret, "krb5_524_conv_principal"); 1754137ff4cSJacques Vidrine return 1; 1764137ff4cSJacques Vidrine } 1774137ff4cSJacques Vidrine 1784137ff4cSJacques Vidrine if (use_srvtab || srvtab_str) { 1794137ff4cSJacques Vidrine if (srvtab_str == NULL) 1804137ff4cSJacques Vidrine srvtab_str = KEYFILE; 1814137ff4cSJacques Vidrine 1824137ff4cSJacques Vidrine ret = read_service_key (princ.name, princ.instance, princ.realm, 1834137ff4cSJacques Vidrine 0, srvtab_str, (char *)&key); 1844137ff4cSJacques Vidrine if (ret) { 1854137ff4cSJacques Vidrine warnx ("read_service_key %s: %s", srvtab_str, 1864137ff4cSJacques Vidrine krb_get_err_text (ret)); 1874137ff4cSJacques Vidrine return 1; 1884137ff4cSJacques Vidrine } 1894137ff4cSJacques Vidrine ret = krb_get_in_tkt (princ.name, princ.instance, princ.realm, 1904137ff4cSJacques Vidrine KRB_TICKET_GRANTING_TICKET, princ.realm, 1914137ff4cSJacques Vidrine lifetime, key_to_key, NULL, key); 1924137ff4cSJacques Vidrine } else { 1938373020dSJacques Vidrine ret = krb_get_pw_in_tkt(princ.name, princ.instance, princ.realm, 1944137ff4cSJacques Vidrine KRB_TICKET_GRANTING_TICKET, princ.realm, 1958373020dSJacques Vidrine lifetime, passwd); 1964137ff4cSJacques Vidrine } 1974137ff4cSJacques Vidrine memset (key, 0, sizeof(key)); 1984137ff4cSJacques Vidrine if (ret) { 1994137ff4cSJacques Vidrine warnx ("%s", krb_get_err_text(ret)); 2004137ff4cSJacques Vidrine return 1; 2014137ff4cSJacques Vidrine } 2024137ff4cSJacques Vidrine if (do_afslog && k_hasafs()) { 2034137ff4cSJacques Vidrine if ((ret = krb_afslog(NULL, NULL)) != 0 && ret != KDC_PR_UNKNOWN) { 2044137ff4cSJacques Vidrine if(ret > 0) 2054137ff4cSJacques Vidrine warnx ("%s", krb_get_err_text(ret)); 2064137ff4cSJacques Vidrine else 2074137ff4cSJacques Vidrine warnx ("failed to store AFS token"); 2084137ff4cSJacques Vidrine } 2094137ff4cSJacques Vidrine } 2104137ff4cSJacques Vidrine return 0; 2114137ff4cSJacques Vidrine } 2124137ff4cSJacques Vidrine 2134137ff4cSJacques Vidrine 2144137ff4cSJacques Vidrine /* 2154137ff4cSJacques Vidrine * the special version of get_default_principal that takes v4 into account 2164137ff4cSJacques Vidrine */ 2174137ff4cSJacques Vidrine 2184137ff4cSJacques Vidrine static krb5_error_code 2194137ff4cSJacques Vidrine kinit_get_default_principal (krb5_context context, 2204137ff4cSJacques Vidrine krb5_principal *princ) 2214137ff4cSJacques Vidrine { 2224137ff4cSJacques Vidrine krb5_error_code ret; 2234137ff4cSJacques Vidrine krb5_ccache id; 2244137ff4cSJacques Vidrine krb_principal v4_princ; 2254137ff4cSJacques Vidrine int kret; 2264137ff4cSJacques Vidrine 2274137ff4cSJacques Vidrine ret = krb5_cc_default (context, &id); 2284137ff4cSJacques Vidrine if (ret == 0) { 2294137ff4cSJacques Vidrine ret = krb5_cc_get_principal (context, id, princ); 2304137ff4cSJacques Vidrine krb5_cc_close (context, id); 2314137ff4cSJacques Vidrine if (ret == 0) 2324137ff4cSJacques Vidrine return 0; 2334137ff4cSJacques Vidrine } 2344137ff4cSJacques Vidrine 2354137ff4cSJacques Vidrine kret = krb_get_tf_fullname (tkt_string(), 2364137ff4cSJacques Vidrine v4_princ.name, 2374137ff4cSJacques Vidrine v4_princ.instance, 2384137ff4cSJacques Vidrine v4_princ.realm); 2394137ff4cSJacques Vidrine if (kret == KSUCCESS) { 2404137ff4cSJacques Vidrine ret = krb5_425_conv_principal (context, 2414137ff4cSJacques Vidrine v4_princ.name, 2424137ff4cSJacques Vidrine v4_princ.instance, 2434137ff4cSJacques Vidrine v4_princ.realm, 2444137ff4cSJacques Vidrine princ); 2454137ff4cSJacques Vidrine if (ret == 0) 2464137ff4cSJacques Vidrine return 0; 2474137ff4cSJacques Vidrine } 2484137ff4cSJacques Vidrine return krb5_get_default_principal (context, princ); 2494137ff4cSJacques Vidrine } 2504137ff4cSJacques Vidrine 2514137ff4cSJacques Vidrine #else /* !KRB4 */ 2524137ff4cSJacques Vidrine 2534137ff4cSJacques Vidrine static krb5_error_code 2544137ff4cSJacques Vidrine kinit_get_default_principal (krb5_context context, 2554137ff4cSJacques Vidrine krb5_principal *princ) 2564137ff4cSJacques Vidrine { 2574137ff4cSJacques Vidrine return krb5_get_default_principal (context, princ); 2584137ff4cSJacques Vidrine } 2594137ff4cSJacques Vidrine 2604137ff4cSJacques Vidrine #endif /* !KRB4 */ 2614137ff4cSJacques Vidrine 2624137ff4cSJacques Vidrine static krb5_error_code 2634137ff4cSJacques Vidrine get_server(krb5_context context, 2644137ff4cSJacques Vidrine krb5_principal client, 2654137ff4cSJacques Vidrine const char *server, 2664137ff4cSJacques Vidrine krb5_principal *princ) 2674137ff4cSJacques Vidrine { 2684137ff4cSJacques Vidrine krb5_realm *client_realm; 2694137ff4cSJacques Vidrine if(server) 2704137ff4cSJacques Vidrine return krb5_parse_name(context, server, princ); 2714137ff4cSJacques Vidrine 2724137ff4cSJacques Vidrine client_realm = krb5_princ_realm (context, client); 2734137ff4cSJacques Vidrine return krb5_make_principal(context, princ, *client_realm, 2744137ff4cSJacques Vidrine KRB5_TGS_NAME, *client_realm, NULL); 2754137ff4cSJacques Vidrine } 2764137ff4cSJacques Vidrine 2774137ff4cSJacques Vidrine #ifdef KRB4 2784137ff4cSJacques Vidrine static krb5_error_code 2794137ff4cSJacques Vidrine do_524init(krb5_context context, krb5_ccache ccache, 2804137ff4cSJacques Vidrine krb5_creds *creds, const char *server) 2814137ff4cSJacques Vidrine { 2824137ff4cSJacques Vidrine krb5_error_code ret; 2834137ff4cSJacques Vidrine CREDENTIALS c; 2844137ff4cSJacques Vidrine krb5_creds in_creds, *real_creds; 2854137ff4cSJacques Vidrine 2864137ff4cSJacques Vidrine if(creds != NULL) 2874137ff4cSJacques Vidrine real_creds = creds; 2884137ff4cSJacques Vidrine else { 2894137ff4cSJacques Vidrine krb5_principal client; 2904137ff4cSJacques Vidrine krb5_cc_get_principal(context, ccache, &client); 2914137ff4cSJacques Vidrine memset(&in_creds, 0, sizeof(in_creds)); 2924137ff4cSJacques Vidrine ret = get_server(context, client, server, &in_creds.server); 2931c43270aSJacques Vidrine if(ret) { 2940cadf2f4SJacques Vidrine krb5_free_principal(context, client); 2954137ff4cSJacques Vidrine return ret; 2961c43270aSJacques Vidrine } 2971c43270aSJacques Vidrine in_creds.client = client; 2984137ff4cSJacques Vidrine ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds); 2991c43270aSJacques Vidrine krb5_free_principal(context, client); 3000cadf2f4SJacques Vidrine krb5_free_principal(context, in_creds.server); 3014137ff4cSJacques Vidrine if(ret) 3024137ff4cSJacques Vidrine return ret; 3034137ff4cSJacques Vidrine } 3044137ff4cSJacques Vidrine ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c); 3054137ff4cSJacques Vidrine if(ret) 3064137ff4cSJacques Vidrine krb5_warn(context, ret, "converting creds"); 3074137ff4cSJacques Vidrine else { 3084137ff4cSJacques Vidrine int tret = tf_setup(&c, c.pname, c.pinst); 3094137ff4cSJacques Vidrine if(tret) 3104137ff4cSJacques Vidrine krb5_warnx(context, "saving v4 creds: %s", krb_get_err_text(tret)); 3114137ff4cSJacques Vidrine } 3124137ff4cSJacques Vidrine 3134137ff4cSJacques Vidrine if(creds == NULL) 3144137ff4cSJacques Vidrine krb5_free_creds(context, real_creds); 3154137ff4cSJacques Vidrine memset(&c, 0, sizeof(c)); 3164137ff4cSJacques Vidrine 3174137ff4cSJacques Vidrine return ret; 3184137ff4cSJacques Vidrine } 3194137ff4cSJacques Vidrine #endif 3204137ff4cSJacques Vidrine 321b528cefcSMark Murray static int 322b528cefcSMark Murray renew_validate(krb5_context context, 323b528cefcSMark Murray int renew, 324b528cefcSMark Murray int validate, 325b528cefcSMark Murray krb5_ccache cache, 326b528cefcSMark Murray const char *server, 327b528cefcSMark Murray krb5_deltat life) 328b528cefcSMark Murray { 329b528cefcSMark Murray krb5_error_code ret; 330b528cefcSMark Murray krb5_creds in, *out; 331b528cefcSMark Murray krb5_kdc_flags flags; 332b528cefcSMark Murray 333b528cefcSMark Murray memset(&in, 0, sizeof(in)); 334b528cefcSMark Murray 335b528cefcSMark Murray ret = krb5_cc_get_principal(context, cache, &in.client); 336b528cefcSMark Murray if(ret) { 337b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_get_principal"); 338b528cefcSMark Murray return ret; 339b528cefcSMark Murray } 3404137ff4cSJacques Vidrine ret = get_server(context, in.client, server, &in.server); 341b528cefcSMark Murray if(ret) { 3424137ff4cSJacques Vidrine krb5_warn(context, ret, "get_server"); 343b528cefcSMark Murray goto out; 344b528cefcSMark Murray } 345b528cefcSMark Murray flags.i = 0; 346b528cefcSMark Murray flags.b.renewable = flags.b.renew = renew; 347b528cefcSMark Murray flags.b.validate = validate; 348adb0ddaeSAssar Westerlund if (forwardable_flag != -1) 3495e9cd1aeSAssar Westerlund flags.b.forwardable = forwardable_flag; 350adb0ddaeSAssar Westerlund if (proxiable_flag != -1) 3515e9cd1aeSAssar Westerlund flags.b.proxiable = proxiable_flag; 352adb0ddaeSAssar Westerlund if (anonymous_flag != -1) 3535e9cd1aeSAssar Westerlund flags.b.request_anonymous = anonymous_flag; 354b528cefcSMark Murray if(life) 355b528cefcSMark Murray in.times.endtime = time(NULL) + life; 356b528cefcSMark Murray 357b528cefcSMark Murray ret = krb5_get_kdc_cred(context, 358b528cefcSMark Murray cache, 359b528cefcSMark Murray flags, 360b528cefcSMark Murray NULL, 361b528cefcSMark Murray NULL, 362b528cefcSMark Murray &in, 363b528cefcSMark Murray &out); 364b528cefcSMark Murray if(ret) { 365b528cefcSMark Murray krb5_warn(context, ret, "krb5_get_kdc_cred"); 366b528cefcSMark Murray goto out; 367b528cefcSMark Murray } 368b528cefcSMark Murray ret = krb5_cc_initialize(context, cache, in.client); 369b528cefcSMark Murray if(ret) { 370b528cefcSMark Murray krb5_free_creds (context, out); 371b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_initialize"); 372b528cefcSMark Murray goto out; 373b528cefcSMark Murray } 374b528cefcSMark Murray ret = krb5_cc_store_cred(context, cache, out); 3754137ff4cSJacques Vidrine 3764137ff4cSJacques Vidrine if(ret == 0 && server == NULL) { 377bbd80c28SJacques Vidrine #ifdef KRB4 3784137ff4cSJacques Vidrine /* only do this if it's a general renew-my-tgt request */ 3794137ff4cSJacques Vidrine if(get_v4_tgt) 3804137ff4cSJacques Vidrine do_524init(context, cache, out, NULL); 381bbd80c28SJacques Vidrine #endif 3824137ff4cSJacques Vidrine if(do_afslog && k_hasafs()) 3834137ff4cSJacques Vidrine krb5_afslog(context, cache, NULL, NULL); 3844137ff4cSJacques Vidrine } 3854137ff4cSJacques Vidrine 386b528cefcSMark Murray krb5_free_creds (context, out); 387b528cefcSMark Murray if(ret) { 388b528cefcSMark Murray krb5_warn(context, ret, "krb5_cc_store_cred"); 389b528cefcSMark Murray goto out; 390b528cefcSMark Murray } 391b528cefcSMark Murray out: 392b528cefcSMark Murray krb5_free_creds_contents(context, &in); 393b528cefcSMark Murray return ret; 394b528cefcSMark Murray } 395b528cefcSMark Murray 3964137ff4cSJacques Vidrine static krb5_error_code 3974137ff4cSJacques Vidrine get_new_tickets(krb5_context context, 3984137ff4cSJacques Vidrine krb5_principal principal, 3994137ff4cSJacques Vidrine krb5_ccache ccache, 4004137ff4cSJacques Vidrine krb5_deltat ticket_life) 401b528cefcSMark Murray { 402b528cefcSMark Murray krb5_error_code ret; 403b528cefcSMark Murray krb5_get_init_creds_opt opt; 404b528cefcSMark Murray krb5_addresses no_addrs; 4054137ff4cSJacques Vidrine krb5_creds cred; 4065e9cd1aeSAssar Westerlund char passwd[256]; 4074137ff4cSJacques Vidrine krb5_deltat start_time = 0; 4088373020dSJacques Vidrine krb5_deltat renew = 0; 409b528cefcSMark Murray 410b528cefcSMark Murray memset(&cred, 0, sizeof(cred)); 411b528cefcSMark Murray 412b528cefcSMark Murray krb5_get_init_creds_opt_init (&opt); 413b528cefcSMark Murray 4145e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_default_flags(context, "kinit", 4155e9cd1aeSAssar Westerlund /* XXX */principal->realm, &opt); 4165e9cd1aeSAssar Westerlund 4175e9cd1aeSAssar Westerlund if(forwardable_flag != -1) 4185e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_forwardable (&opt, forwardable_flag); 4195e9cd1aeSAssar Westerlund if(proxiable_flag != -1) 4205e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_proxiable (&opt, proxiable_flag); 4215e9cd1aeSAssar Westerlund if(anonymous_flag != -1) 4225e9cd1aeSAssar Westerlund krb5_get_init_creds_opt_set_anonymous (&opt, anonymous_flag); 423b528cefcSMark Murray 42413e3f4d6SMark Murray if (!addrs_flag) { 425b528cefcSMark Murray no_addrs.len = 0; 426b528cefcSMark Murray no_addrs.val = NULL; 427b528cefcSMark Murray 428b528cefcSMark Murray krb5_get_init_creds_opt_set_address_list (&opt, &no_addrs); 429b528cefcSMark Murray } 430b528cefcSMark Murray 4311c43270aSJacques Vidrine if (renew_life == NULL && renewable_flag) 4321c43270aSJacques Vidrine renew_life = "1 month"; 433b528cefcSMark Murray if(renew_life) { 4348373020dSJacques Vidrine renew = parse_time (renew_life, "s"); 4358373020dSJacques Vidrine if (renew < 0) 436b528cefcSMark Murray errx (1, "unparsable time: %s", renew_life); 437b528cefcSMark Murray 4388373020dSJacques Vidrine krb5_get_init_creds_opt_set_renew_life (&opt, renew); 4391c43270aSJacques Vidrine } 4408373020dSJacques Vidrine 441b528cefcSMark Murray if(ticket_life != 0) 442b528cefcSMark Murray krb5_get_init_creds_opt_set_tkt_life (&opt, ticket_life); 443b528cefcSMark Murray 444b528cefcSMark Murray if(start_str) { 445b528cefcSMark Murray int tmp = parse_time (start_str, "s"); 446b528cefcSMark Murray if (tmp < 0) 447b528cefcSMark Murray errx (1, "unparsable time: %s", start_str); 448b528cefcSMark Murray 449b528cefcSMark Murray start_time = tmp; 450b528cefcSMark Murray } 451b528cefcSMark Murray 452b528cefcSMark Murray if(etype_str.num_strings) { 453b528cefcSMark Murray krb5_enctype *enctype = NULL; 454b528cefcSMark Murray int i; 455b528cefcSMark Murray enctype = malloc(etype_str.num_strings * sizeof(*enctype)); 456b528cefcSMark Murray if(enctype == NULL) 457b528cefcSMark Murray errx(1, "out of memory"); 458b528cefcSMark Murray for(i = 0; i < etype_str.num_strings; i++) { 459b528cefcSMark Murray ret = krb5_string_to_enctype(context, 460b528cefcSMark Murray etype_str.strings[i], 461b528cefcSMark Murray &enctype[i]); 462b528cefcSMark Murray if(ret) 463b528cefcSMark Murray errx(1, "unrecognized enctype: %s", etype_str.strings[i]); 464b528cefcSMark Murray } 465b528cefcSMark Murray krb5_get_init_creds_opt_set_etype_list(&opt, enctype, 466b528cefcSMark Murray etype_str.num_strings); 467b528cefcSMark Murray } 468b528cefcSMark Murray 469b528cefcSMark Murray if(use_keytab || keytab_str) { 470b528cefcSMark Murray krb5_keytab kt; 471b528cefcSMark Murray if(keytab_str) 472b528cefcSMark Murray ret = krb5_kt_resolve(context, keytab_str, &kt); 473b528cefcSMark Murray else 474b528cefcSMark Murray ret = krb5_kt_default(context, &kt); 475b528cefcSMark Murray if (ret) 476b528cefcSMark Murray krb5_err (context, 1, ret, "resolving keytab"); 477b528cefcSMark Murray ret = krb5_get_init_creds_keytab (context, 478b528cefcSMark Murray &cred, 479b528cefcSMark Murray principal, 480b528cefcSMark Murray kt, 481b528cefcSMark Murray start_time, 482b528cefcSMark Murray server, 483b528cefcSMark Murray &opt); 484b528cefcSMark Murray krb5_kt_close(context, kt); 4855e9cd1aeSAssar Westerlund } else { 4865e9cd1aeSAssar Westerlund char *p, *prompt; 4875e9cd1aeSAssar Westerlund 4885e9cd1aeSAssar Westerlund krb5_unparse_name (context, principal, &p); 4895e9cd1aeSAssar Westerlund asprintf (&prompt, "%s's Password: ", p); 4905e9cd1aeSAssar Westerlund free (p); 4915e9cd1aeSAssar Westerlund 4925e9cd1aeSAssar Westerlund if (des_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){ 4935e9cd1aeSAssar Westerlund memset(passwd, 0, sizeof(passwd)); 4945e9cd1aeSAssar Westerlund exit(1); 4955e9cd1aeSAssar Westerlund } 4965e9cd1aeSAssar Westerlund 4975e9cd1aeSAssar Westerlund free (prompt); 4985e9cd1aeSAssar Westerlund 499b528cefcSMark Murray ret = krb5_get_init_creds_password (context, 500b528cefcSMark Murray &cred, 501b528cefcSMark Murray principal, 5025e9cd1aeSAssar Westerlund passwd, 503b528cefcSMark Murray krb5_prompter_posix, 504b528cefcSMark Murray NULL, 505b528cefcSMark Murray start_time, 506b528cefcSMark Murray server, 507b528cefcSMark Murray &opt); 5085e9cd1aeSAssar Westerlund } 5095e9cd1aeSAssar Westerlund #ifdef KRB4 5105e9cd1aeSAssar Westerlund if (ret == KRB5KRB_AP_ERR_V4_REPLY || ret == KRB5_KDC_UNREACH) { 5115e9cd1aeSAssar Westerlund int exit_val; 5125e9cd1aeSAssar Westerlund 5135e9cd1aeSAssar Westerlund exit_val = do_v4_fallback (context, principal, ticket_life, 5144137ff4cSJacques Vidrine use_keytab, keytab_str, passwd); 5154137ff4cSJacques Vidrine get_v4_tgt = 0; 5164137ff4cSJacques Vidrine do_afslog = 0; 5175e9cd1aeSAssar Westerlund memset(passwd, 0, sizeof(passwd)); 5184137ff4cSJacques Vidrine if (exit_val == 0 || ret == KRB5KRB_AP_ERR_V4_REPLY) 5195e9cd1aeSAssar Westerlund return exit_val; 5205e9cd1aeSAssar Westerlund } 5215e9cd1aeSAssar Westerlund #endif 5225e9cd1aeSAssar Westerlund memset(passwd, 0, sizeof(passwd)); 5235e9cd1aeSAssar Westerlund 524b528cefcSMark Murray switch(ret){ 525b528cefcSMark Murray case 0: 526b528cefcSMark Murray break; 527b528cefcSMark Murray case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */ 528b528cefcSMark Murray exit(1); 529b528cefcSMark Murray case KRB5KRB_AP_ERR_BAD_INTEGRITY: 530b528cefcSMark Murray case KRB5KRB_AP_ERR_MODIFIED: 531b528cefcSMark Murray krb5_errx(context, 1, "Password incorrect"); 532b528cefcSMark Murray break; 533b528cefcSMark Murray default: 534b528cefcSMark Murray krb5_err(context, 1, ret, "krb5_get_init_creds"); 535b528cefcSMark Murray } 536b528cefcSMark Murray 5378373020dSJacques Vidrine if(ticket_life != 0) { 5388373020dSJacques Vidrine if(abs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) { 5398373020dSJacques Vidrine char life[32]; 5408373020dSJacques Vidrine unparse_time(cred.times.endtime - cred.times.starttime, 5418373020dSJacques Vidrine life, sizeof(life)); 5428373020dSJacques Vidrine krb5_warnx(context, "NOTICE: ticket lifetime is %s", life); 5438373020dSJacques Vidrine } 5448373020dSJacques Vidrine } 5458373020dSJacques Vidrine if(renew != 0) { 5468373020dSJacques Vidrine if(abs(cred.times.renew_till - cred.times.starttime - renew) > 30) { 5478373020dSJacques Vidrine char life[32]; 5488373020dSJacques Vidrine unparse_time(cred.times.renew_till - cred.times.starttime, 5498373020dSJacques Vidrine life, sizeof(life)); 5508373020dSJacques Vidrine krb5_warnx(context, "NOTICE: ticket renewable lifetime is %s", 5518373020dSJacques Vidrine life); 5528373020dSJacques Vidrine } 5538373020dSJacques Vidrine } 5548373020dSJacques Vidrine 555b528cefcSMark Murray ret = krb5_cc_initialize (context, ccache, cred.client); 556b528cefcSMark Murray if (ret) 557b528cefcSMark Murray krb5_err (context, 1, ret, "krb5_cc_initialize"); 558b528cefcSMark Murray 559b528cefcSMark Murray ret = krb5_cc_store_cred (context, ccache, &cred); 560b528cefcSMark Murray if (ret) 561b528cefcSMark Murray krb5_err (context, 1, ret, "krb5_cc_store_cred"); 562b528cefcSMark Murray 5634137ff4cSJacques Vidrine krb5_free_creds_contents (context, &cred); 5644137ff4cSJacques Vidrine 5654137ff4cSJacques Vidrine return 0; 566b528cefcSMark Murray } 5674137ff4cSJacques Vidrine 5684137ff4cSJacques Vidrine int 5694137ff4cSJacques Vidrine main (int argc, char **argv) 5704137ff4cSJacques Vidrine { 5714137ff4cSJacques Vidrine krb5_error_code ret; 5724137ff4cSJacques Vidrine krb5_context context; 5734137ff4cSJacques Vidrine krb5_ccache ccache; 5744137ff4cSJacques Vidrine krb5_principal principal; 5754137ff4cSJacques Vidrine int optind = 0; 5764137ff4cSJacques Vidrine krb5_deltat ticket_life = 0; 5774137ff4cSJacques Vidrine 5784137ff4cSJacques Vidrine setprogname (argv[0]); 5794137ff4cSJacques Vidrine 5804137ff4cSJacques Vidrine ret = krb5_init_context (&context); 5814137ff4cSJacques Vidrine if (ret) 5824137ff4cSJacques Vidrine errx(1, "krb5_init_context failed: %d", ret); 5834137ff4cSJacques Vidrine 5844137ff4cSJacques Vidrine if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) 5854137ff4cSJacques Vidrine usage(1); 5864137ff4cSJacques Vidrine 5874137ff4cSJacques Vidrine if (help_flag) 5884137ff4cSJacques Vidrine usage (0); 5894137ff4cSJacques Vidrine 5904137ff4cSJacques Vidrine if(version_flag) { 5914137ff4cSJacques Vidrine print_version(NULL); 5924137ff4cSJacques Vidrine exit(0); 5934137ff4cSJacques Vidrine } 5944137ff4cSJacques Vidrine 5954137ff4cSJacques Vidrine argc -= optind; 5964137ff4cSJacques Vidrine argv += optind; 5974137ff4cSJacques Vidrine 5984137ff4cSJacques Vidrine if (argv[0]) { 5994137ff4cSJacques Vidrine ret = krb5_parse_name (context, argv[0], &principal); 6004137ff4cSJacques Vidrine if (ret) 6014137ff4cSJacques Vidrine krb5_err (context, 1, ret, "krb5_parse_name"); 6024137ff4cSJacques Vidrine } else { 6034137ff4cSJacques Vidrine ret = kinit_get_default_principal (context, &principal); 6044137ff4cSJacques Vidrine if (ret) 6054137ff4cSJacques Vidrine krb5_err (context, 1, ret, "krb5_get_default_principal"); 6064137ff4cSJacques Vidrine } 6074137ff4cSJacques Vidrine 6084137ff4cSJacques Vidrine if(fcache_version) 6094137ff4cSJacques Vidrine krb5_set_fcache_version(context, fcache_version); 6104137ff4cSJacques Vidrine 6114137ff4cSJacques Vidrine if(cred_cache) 6124137ff4cSJacques Vidrine ret = krb5_cc_resolve(context, cred_cache, &ccache); 6134137ff4cSJacques Vidrine else { 6144137ff4cSJacques Vidrine if(argc > 1) { 6154137ff4cSJacques Vidrine char s[1024]; 6164137ff4cSJacques Vidrine ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache); 6174137ff4cSJacques Vidrine if(ret) 6184137ff4cSJacques Vidrine krb5_err(context, 1, ret, "creating cred cache"); 6194137ff4cSJacques Vidrine snprintf(s, sizeof(s), "%s:%s", 6204137ff4cSJacques Vidrine krb5_cc_get_type(context, ccache), 6214137ff4cSJacques Vidrine krb5_cc_get_name(context, ccache)); 6224137ff4cSJacques Vidrine setenv("KRB5CCNAME", s, 1); 6234137ff4cSJacques Vidrine #ifdef KRB4 6244137ff4cSJacques Vidrine { 6254137ff4cSJacques Vidrine int fd; 6264137ff4cSJacques Vidrine snprintf(s, sizeof(s), "%s_XXXXXX", TKT_ROOT); 6274137ff4cSJacques Vidrine if((fd = mkstemp(s)) >= 0) { 6284137ff4cSJacques Vidrine close(fd); 6294137ff4cSJacques Vidrine setenv("KRBTKFILE", s, 1); 6304137ff4cSJacques Vidrine if (k_hasafs ()) 6314137ff4cSJacques Vidrine k_setpag(); 6324137ff4cSJacques Vidrine } 6334137ff4cSJacques Vidrine } 6344137ff4cSJacques Vidrine #endif 6354137ff4cSJacques Vidrine } else 6364137ff4cSJacques Vidrine ret = krb5_cc_default (context, &ccache); 6374137ff4cSJacques Vidrine } 6384137ff4cSJacques Vidrine if (ret) 6394137ff4cSJacques Vidrine krb5_err (context, 1, ret, "resolving credentials cache"); 6404137ff4cSJacques Vidrine 6414137ff4cSJacques Vidrine if (lifetime) { 6424137ff4cSJacques Vidrine int tmp = parse_time (lifetime, "s"); 6434137ff4cSJacques Vidrine if (tmp < 0) 6444137ff4cSJacques Vidrine errx (1, "unparsable time: %s", lifetime); 6454137ff4cSJacques Vidrine 6464137ff4cSJacques Vidrine ticket_life = tmp; 6474137ff4cSJacques Vidrine } 6484137ff4cSJacques Vidrine #ifdef KRB4 6494137ff4cSJacques Vidrine if(get_v4_tgt == -1) 6504137ff4cSJacques Vidrine krb5_appdefault_boolean(context, "kinit", 6514137ff4cSJacques Vidrine krb5_principal_get_realm(context, principal), 6524137ff4cSJacques Vidrine "krb4_get_tickets", TRUE, &get_v4_tgt); 653bbd80c28SJacques Vidrine #endif 6544137ff4cSJacques Vidrine if(do_afslog == -1) 6554137ff4cSJacques Vidrine krb5_appdefault_boolean(context, "kinit", 6564137ff4cSJacques Vidrine krb5_principal_get_realm(context, principal), 6574137ff4cSJacques Vidrine "afslog", TRUE, &do_afslog); 6584137ff4cSJacques Vidrine 6598373020dSJacques Vidrine if(!addrs_flag && extra_addresses.num_strings > 0) 6608373020dSJacques Vidrine krb5_errx(context, 1, "specifying both extra addresses and " 6618373020dSJacques Vidrine "no addresses makes no sense"); 6628373020dSJacques Vidrine { 6638373020dSJacques Vidrine int i; 6648373020dSJacques Vidrine krb5_addresses addresses; 6658373020dSJacques Vidrine memset(&addresses, 0, sizeof(addresses)); 6668373020dSJacques Vidrine for(i = 0; i < extra_addresses.num_strings; i++) { 6678373020dSJacques Vidrine ret = krb5_parse_address(context, extra_addresses.strings[i], 6688373020dSJacques Vidrine &addresses); 6698373020dSJacques Vidrine if (ret == 0) { 6708373020dSJacques Vidrine krb5_add_extra_addresses(context, &addresses); 6718373020dSJacques Vidrine krb5_free_addresses(context, &addresses); 6728373020dSJacques Vidrine } 6738373020dSJacques Vidrine } 6748373020dSJacques Vidrine free_getarg_strings(&extra_addresses); 6758373020dSJacques Vidrine } 6768373020dSJacques Vidrine 6774137ff4cSJacques Vidrine 6784137ff4cSJacques Vidrine if(renew_flag || validate_flag) { 6794137ff4cSJacques Vidrine ret = renew_validate(context, renew_flag, validate_flag, 6804137ff4cSJacques Vidrine ccache, server, ticket_life); 6814137ff4cSJacques Vidrine exit(ret != 0); 6824137ff4cSJacques Vidrine } 6834137ff4cSJacques Vidrine 6844137ff4cSJacques Vidrine #ifdef KRB4 6854137ff4cSJacques Vidrine if(!convert_524) 6864137ff4cSJacques Vidrine #endif 6874137ff4cSJacques Vidrine get_new_tickets(context, principal, ccache, ticket_life); 6884137ff4cSJacques Vidrine 6894137ff4cSJacques Vidrine #ifdef KRB4 6904137ff4cSJacques Vidrine if(get_v4_tgt) 6914137ff4cSJacques Vidrine do_524init(context, ccache, NULL, server); 692bbd80c28SJacques Vidrine #endif 693b528cefcSMark Murray if(do_afslog && k_hasafs()) 694b528cefcSMark Murray krb5_afslog(context, ccache, NULL, NULL); 695adb0ddaeSAssar Westerlund if(argc > 1) { 6961c43270aSJacques Vidrine ret = simple_execvp(argv[1], argv+1); 697adb0ddaeSAssar Westerlund krb5_cc_destroy(context, ccache); 698adb0ddaeSAssar Westerlund #ifdef KRB4 699adb0ddaeSAssar Westerlund dest_tkt(); 700bbd80c28SJacques Vidrine #endif 701adb0ddaeSAssar Westerlund if(k_hasafs()) 702adb0ddaeSAssar Westerlund k_unlog(); 7031c43270aSJacques Vidrine } else { 704b528cefcSMark Murray krb5_cc_close (context, ccache); 7051c43270aSJacques Vidrine ret = 0; 7061c43270aSJacques Vidrine } 7074137ff4cSJacques Vidrine krb5_free_principal(context, principal); 708b528cefcSMark Murray krb5_free_context (context); 7091c43270aSJacques Vidrine return ret; 710b528cefcSMark Murray } 711