17c478bd9Sstevel@tonic-gate /*
2*159d09a2SMark Phalan * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate * clients/kinit/kinit.c
97c478bd9Sstevel@tonic-gate *
107c478bd9Sstevel@tonic-gate * Copyright 1990 by the Massachusetts Institute of Technology.
117c478bd9Sstevel@tonic-gate * All Rights Reserved.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may
147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government.
157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating
167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting.
177c478bd9Sstevel@tonic-gate *
187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and
207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright
217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and
227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that
237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining
247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior
257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label
267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a
277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software.
287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of
297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express
307c478bd9Sstevel@tonic-gate * or implied warranty.
317c478bd9Sstevel@tonic-gate *
327c478bd9Sstevel@tonic-gate *
337c478bd9Sstevel@tonic-gate * Initialize a credentials cache.
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate #include <k5-int.h>
367c478bd9Sstevel@tonic-gate #include <profile/prof_int.h>
377c478bd9Sstevel@tonic-gate #include <com_err.h>
387c478bd9Sstevel@tonic-gate #include <libintl.h>
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate #include <krb5.h>
417c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
427c478bd9Sstevel@tonic-gate #include <kerberosIV/krb.h>
437c478bd9Sstevel@tonic-gate #define HAVE_KRB524
447c478bd9Sstevel@tonic-gate #else
457c478bd9Sstevel@tonic-gate #undef HAVE_KRB524
46*159d09a2SMark Phalan #endif
477c478bd9Sstevel@tonic-gate #include <string.h>
487c478bd9Sstevel@tonic-gate #include <stdio.h>
497c478bd9Sstevel@tonic-gate #include <time.h>
50*159d09a2SMark Phalan #include <errno.h>
51*159d09a2SMark Phalan #include <com_err.h>
527c478bd9Sstevel@tonic-gate #include <netdb.h>
537c478bd9Sstevel@tonic-gate #include <locale.h>
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
567c478bd9Sstevel@tonic-gate #include <getopt.h>
57*159d09a2SMark Phalan #else
587c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H
597c478bd9Sstevel@tonic-gate #include <unistd.h>
60*159d09a2SMark Phalan #ifdef sun
61*159d09a2SMark Phalan /* SunOS4 unistd didn't declare these; okay to make unconditional? */
62*159d09a2SMark Phalan extern int optind;
63*159d09a2SMark Phalan extern char *optarg;
64*159d09a2SMark Phalan #endif /* sun */
65*159d09a2SMark Phalan #else
667c478bd9Sstevel@tonic-gate extern int optind;
677c478bd9Sstevel@tonic-gate extern char *optarg;
687c478bd9Sstevel@tonic-gate extern int getopt();
697c478bd9Sstevel@tonic-gate #endif /* HAVE_UNISTD_H */
707c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #ifndef _WIN32
737c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
74*159d09a2SMark Phalan #else
757c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
76*159d09a2SMark Phalan #endif
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate #ifdef HAVE_PWD_H
797c478bd9Sstevel@tonic-gate #include <pwd.h>
8056a424ccSmp153739 static
get_name_from_os()817c478bd9Sstevel@tonic-gate char * get_name_from_os()
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate struct passwd *pw;
8456a424ccSmp153739 if ((pw = getpwuid((int) getuid())))
857c478bd9Sstevel@tonic-gate return pw->pw_name;
867c478bd9Sstevel@tonic-gate return 0;
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate #else /* HAVE_PWD_H */
897c478bd9Sstevel@tonic-gate #ifdef _WIN32
9056a424ccSmp153739 static
get_name_from_os()917c478bd9Sstevel@tonic-gate char * get_name_from_os()
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate static char name[1024];
947c478bd9Sstevel@tonic-gate DWORD name_size = sizeof(name);
957c478bd9Sstevel@tonic-gate if (GetUserName(name, &name_size)) {
967c478bd9Sstevel@tonic-gate name[sizeof(name)-1] = 0; /* Just to be extra safe */
977c478bd9Sstevel@tonic-gate return name;
987c478bd9Sstevel@tonic-gate } else {
997c478bd9Sstevel@tonic-gate return 0;
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate #else /* _WIN32 */
10356a424ccSmp153739 static
get_name_from_os()1047c478bd9Sstevel@tonic-gate char * get_name_from_os()
1057c478bd9Sstevel@tonic-gate {
1067c478bd9Sstevel@tonic-gate return 0;
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate #endif /* _WIN32 */
1097c478bd9Sstevel@tonic-gate #endif /* HAVE_PWD_H */
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate static char* progname_v5 = 0;
1127c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1137c478bd9Sstevel@tonic-gate static char* progname_v4 = 0;
1147c478bd9Sstevel@tonic-gate static char* progname_v524 = 0;
115*159d09a2SMark Phalan #endif
1167c478bd9Sstevel@tonic-gate #include <locale.h>
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate static int got_k5 = 0;
1197c478bd9Sstevel@tonic-gate static int got_k4 = 0;
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate static int default_k5 = 1;
1227c478bd9Sstevel@tonic-gate #if defined(KRB5_KRB4_COMPAT) && defined(KINIT_DEFAULT_BOTH)
1237c478bd9Sstevel@tonic-gate static int default_k4 = 1;
124*159d09a2SMark Phalan #else
1257c478bd9Sstevel@tonic-gate static int default_k4 = 0;
126*159d09a2SMark Phalan #endif
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate static int authed_k5 = 0;
1297c478bd9Sstevel@tonic-gate static int authed_k4 = 0;
1307c478bd9Sstevel@tonic-gate
13156a424ccSmp153739 #define KRB4_BACKUP_DEFAULT_LIFE_SECS 24*60*60 /* 1 day */
1327c478bd9Sstevel@tonic-gate #define ROOT_UNAME "root"
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate struct k_opts
1377c478bd9Sstevel@tonic-gate {
1387c478bd9Sstevel@tonic-gate /* in seconds */
1397c478bd9Sstevel@tonic-gate krb5_deltat starttime;
1407c478bd9Sstevel@tonic-gate krb5_deltat lifetime;
1417c478bd9Sstevel@tonic-gate krb5_deltat rlife;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate int forwardable;
1447c478bd9Sstevel@tonic-gate int proxiable;
1457c478bd9Sstevel@tonic-gate int addresses;
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate int not_forwardable;
1487c478bd9Sstevel@tonic-gate int not_proxiable;
1497c478bd9Sstevel@tonic-gate int no_addresses;
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate int verbose;
1527c478bd9Sstevel@tonic-gate
1537c478bd9Sstevel@tonic-gate char* principal_name;
1547c478bd9Sstevel@tonic-gate char* service_name;
1557c478bd9Sstevel@tonic-gate char* keytab_name;
1567c478bd9Sstevel@tonic-gate char* k5_cache_name;
1577c478bd9Sstevel@tonic-gate char* k4_cache_name;
1587c478bd9Sstevel@tonic-gate
1597c478bd9Sstevel@tonic-gate action_type action;
160*159d09a2SMark Phalan
161*159d09a2SMark Phalan int num_pa_opts;
162*159d09a2SMark Phalan krb5_gic_opt_pa_data *pa_opts;
1637c478bd9Sstevel@tonic-gate };
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate int forwardable_flag = 0;
1667c478bd9Sstevel@tonic-gate int renewable_flag = 0;
1677c478bd9Sstevel@tonic-gate int proxiable_flag = 0;
1687c478bd9Sstevel@tonic-gate int no_address_flag = 0;
1697c478bd9Sstevel@tonic-gate profile_options_boolean config_option[] = {
1707c478bd9Sstevel@tonic-gate { "forwardable", &forwardable_flag, 0 },
1717c478bd9Sstevel@tonic-gate { "renewable", &renewable_flag, 0 },
1727c478bd9Sstevel@tonic-gate { "proxiable", &proxiable_flag, 0 },
1737c478bd9Sstevel@tonic-gate { "no_addresses", &no_address_flag, 0 },
1747c478bd9Sstevel@tonic-gate { NULL, NULL, 0 }
1757c478bd9Sstevel@tonic-gate };
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate char *renew_timeval=NULL;
1787c478bd9Sstevel@tonic-gate char *life_timeval=NULL;
1797c478bd9Sstevel@tonic-gate int lifetime_specified;
1807c478bd9Sstevel@tonic-gate int renewtime_specified;
1817c478bd9Sstevel@tonic-gate profile_option_strings config_times[] = {
1827c478bd9Sstevel@tonic-gate { "max_life", &life_timeval, 0 },
1837c478bd9Sstevel@tonic-gate { "max_renewable_life", &renew_timeval, 0 },
1847c478bd9Sstevel@tonic-gate { NULL, NULL, 0 }
1857c478bd9Sstevel@tonic-gate };
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate struct k5_data
1887c478bd9Sstevel@tonic-gate {
1897c478bd9Sstevel@tonic-gate krb5_context ctx;
1907c478bd9Sstevel@tonic-gate krb5_ccache cc;
1917c478bd9Sstevel@tonic-gate krb5_principal me;
1927c478bd9Sstevel@tonic-gate char* name;
1937c478bd9Sstevel@tonic-gate };
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate struct k4_data
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate krb5_deltat lifetime;
1987c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1997c478bd9Sstevel@tonic-gate char aname[ANAME_SZ + 1];
2007c478bd9Sstevel@tonic-gate char inst[INST_SZ + 1];
2017c478bd9Sstevel@tonic-gate char realm[REALM_SZ + 1];
2027c478bd9Sstevel@tonic-gate char name[ANAME_SZ + 1 + INST_SZ + 1 + REALM_SZ + 1];
203*159d09a2SMark Phalan #endif
2047c478bd9Sstevel@tonic-gate };
2057c478bd9Sstevel@tonic-gate
2067c478bd9Sstevel@tonic-gate char *realmdef[] = { "realms", NULL, "kinit", NULL };
2077c478bd9Sstevel@tonic-gate char *appdef[] = { "appdefaults", "kinit", NULL };
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate #define krb_realm (*(realmdef + 1))
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate #define lifetime_specified config_times[0].found
2127c478bd9Sstevel@tonic-gate #define renewtime_specified config_times[1].found
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate * Try no preauthentication first; then try the encrypted timestamp
2167c478bd9Sstevel@tonic-gate */
2177c478bd9Sstevel@tonic-gate krb5_preauthtype * preauth = NULL;
2187c478bd9Sstevel@tonic-gate krb5_preauthtype preauth_list[2] = { 0, -1 };
2197c478bd9Sstevel@tonic-gate
220*159d09a2SMark Phalan static void _kwarnd_add_warning(char *, char *, time_t);
221*159d09a2SMark Phalan static void _kwarnd_del_warning(char *, char *);
2227c478bd9Sstevel@tonic-gate
2237c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
2247c478bd9Sstevel@tonic-gate /* if struct[2] == NULL, then long_getopt acts as if the short flag
2257c478bd9Sstevel@tonic-gate struct[3] was specified. If struct[2] != NULL, then struct[3] is
2267c478bd9Sstevel@tonic-gate stored in *(struct[2]), the array index which was specified is
2277c478bd9Sstevel@tonic-gate stored in *index, and long_getopt() returns 0. */
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate struct option long_options[] = {
2307c478bd9Sstevel@tonic-gate { "noforwardable", 0, NULL, 'F' },
2317c478bd9Sstevel@tonic-gate { "noproxiable", 0, NULL, 'P' },
2327c478bd9Sstevel@tonic-gate { "addresses", 0, NULL, 'a'},
2337c478bd9Sstevel@tonic-gate { "forwardable", 0, NULL, 'f' },
2347c478bd9Sstevel@tonic-gate { "proxiable", 0, NULL, 'p' },
2357c478bd9Sstevel@tonic-gate { "noaddresses", 0, NULL, 'A' },
2367c478bd9Sstevel@tonic-gate { NULL, 0, NULL, 0 }
2377c478bd9Sstevel@tonic-gate };
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt_long(argc, argv, str, long_options, 0)
240*159d09a2SMark Phalan #else
2417c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt(argc, argv, str)
242*159d09a2SMark Phalan #endif
2437c478bd9Sstevel@tonic-gate
24456a424ccSmp153739 static void
usage(progname)24556a424ccSmp153739 usage(progname)
246*159d09a2SMark Phalan char *progname;
2477c478bd9Sstevel@tonic-gate {
2487c478bd9Sstevel@tonic-gate #define USAGE_BREAK "\n\t"
24956a424ccSmp153739
2507c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
2517c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable"
2527c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable"
2537c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses"
2547c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG USAGE_BREAK
255*159d09a2SMark Phalan #else
2567c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE ""
2577c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE ""
2587c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES ""
2597c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG ""
260*159d09a2SMark Phalan #endif
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate fprintf(stderr, "%s : %s [-V] "
2637c478bd9Sstevel@tonic-gate "[-l lifetime] [-s start_time] "
2647c478bd9Sstevel@tonic-gate USAGE_BREAK
2657c478bd9Sstevel@tonic-gate "[-r renewable_life] "
2667c478bd9Sstevel@tonic-gate "[-f | -F" USAGE_LONG_FORWARDABLE "] "
2677c478bd9Sstevel@tonic-gate USAGE_BREAK_LONG
2687c478bd9Sstevel@tonic-gate "[-p | -P" USAGE_LONG_PROXIABLE "] "
2697c478bd9Sstevel@tonic-gate USAGE_BREAK_LONG
27056a424ccSmp153739 "[-a | -A" USAGE_LONG_ADDRESSES "] "
2717c478bd9Sstevel@tonic-gate USAGE_BREAK
2727c478bd9Sstevel@tonic-gate "[-v] [-R] "
2737c478bd9Sstevel@tonic-gate "[-k [-t keytab_file]] "
2747c478bd9Sstevel@tonic-gate "[-c cachename] "
275*159d09a2SMark Phalan USAGE_BREAK
276*159d09a2SMark Phalan "[-S service_name]"
277*159d09a2SMark Phalan "[-X <attribute>[=<value>]] [principal]"
2787c478bd9Sstevel@tonic-gate "\n\n",
2797c478bd9Sstevel@tonic-gate gettext("Usage"), progname);
2807c478bd9Sstevel@tonic-gate
2817c478bd9Sstevel@tonic-gate #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available"))
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB5 "5"
2847c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB4 "4"
2857c478bd9Sstevel@tonic-gate #define OPTTYPE_EITHER "Either 4 or 5"
2867c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
2877c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5, or both 5 and 4"
2887c478bd9Sstevel@tonic-gate #else
2897c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5"
2907c478bd9Sstevel@tonic-gate #endif
2917c478bd9Sstevel@tonic-gate
2927c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
2937c478bd9Sstevel@tonic-gate #define USAGE_OPT_FMT "%s%-50s%s\n"
2947c478bd9Sstevel@tonic-gate #define ULINE(indent, col1, col2) \
2957c478bd9Sstevel@tonic-gate fprintf(stderr, USAGE_OPT_FMT, indent, col1, col2)
29656a424ccSmp153739 #else
29756a424ccSmp153739 #define USAGE_OPT_FMT "%s%s\n"
29856a424ccSmp153739 #define ULINE(indent, col1, col2) \
29956a424ccSmp153739 fprintf(stderr, USAGE_OPT_FMT, indent, col1)
30056a424ccSmp153739 #endif
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate ULINE(" ", "options:", "valid with Kerberos:");
3037c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5));
3047c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4));
3057c478bd9Sstevel@tonic-gate fprintf(stderr, "\t (Default behavior is to try %s%s%s%s)\n",
3067c478bd9Sstevel@tonic-gate default_k5?"Kerberos 5":"",
3077c478bd9Sstevel@tonic-gate (default_k5 && default_k4)?gettext(" and "):"",
3087c478bd9Sstevel@tonic-gate default_k4?"Kerberos 4":"",
3097c478bd9Sstevel@tonic-gate (!default_k5 && !default_k4)?gettext("neither"):"");
3107c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-V verbose"), OPTTYPE_EITHER);
3117c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-l lifetime"), OPTTYPE_EITHER);
3127c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-s start time"), OPTTYPE_KRB5);
3137c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-r renewable lifetime"), OPTTYPE_KRB5);
3147c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-f forwardable"), OPTTYPE_KRB5);
3157c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-F not forwardable"), OPTTYPE_KRB5);
3167c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-p proxiable"), OPTTYPE_KRB5);
3177c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-P not proxiable"), OPTTYPE_KRB5);
3187c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-A do not include addresses"), OPTTYPE_KRB5);
31956a424ccSmp153739 ULINE("\t", gettext("-a include addresses"), OPTTYPE_KRB5);
3207c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-v validate"), OPTTYPE_KRB5);
3217c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-R renew"), OPTTYPE_BOTH);
3227c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-k use keytab"), OPTTYPE_BOTH);
3237c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-t filename of keytab to use"), OPTTYPE_BOTH);
3247c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-c Kerberos 5 cache name"), OPTTYPE_KRB5);
3257c478bd9Sstevel@tonic-gate /* This options is not yet available: */
3267c478bd9Sstevel@tonic-gate /* ULINE("\t", "-C Kerberos 4 cache name", OPTTYPE_KRB4); */
3277c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-S service"), OPTTYPE_BOTH);
328*159d09a2SMark Phalan ULINE("\t", gettext("-X <attribute>[=<value>]"), OPTTYPE_KRB5);
3297c478bd9Sstevel@tonic-gate exit(2);
3307c478bd9Sstevel@tonic-gate }
3317c478bd9Sstevel@tonic-gate
332*159d09a2SMark Phalan static krb5_context errctx;
extended_com_err_fn(const char * myprog,errcode_t code,const char * fmt,va_list args)333*159d09a2SMark Phalan static void extended_com_err_fn (const char *myprog, errcode_t code,
334*159d09a2SMark Phalan const char *fmt, va_list args)
335*159d09a2SMark Phalan {
336*159d09a2SMark Phalan const char *emsg;
337*159d09a2SMark Phalan emsg = krb5_get_error_message (errctx, code);
338*159d09a2SMark Phalan fprintf (stderr, "%s: %s ", myprog, emsg);
339*159d09a2SMark Phalan krb5_free_error_message (errctx, emsg);
340*159d09a2SMark Phalan vfprintf (stderr, fmt, args);
341*159d09a2SMark Phalan fprintf (stderr, "\n");
342*159d09a2SMark Phalan }
343*159d09a2SMark Phalan
344*159d09a2SMark Phalan static int
add_preauth_opt(struct k_opts * opts,char * av)345*159d09a2SMark Phalan add_preauth_opt(struct k_opts *opts, char *av)
346*159d09a2SMark Phalan {
347*159d09a2SMark Phalan char *sep, *v;
348*159d09a2SMark Phalan krb5_gic_opt_pa_data *p, *x;
349*159d09a2SMark Phalan
350*159d09a2SMark Phalan if (opts->num_pa_opts == 0) {
351*159d09a2SMark Phalan opts->pa_opts = malloc(sizeof(krb5_gic_opt_pa_data));
352*159d09a2SMark Phalan if (opts->pa_opts == NULL)
353*159d09a2SMark Phalan return ENOMEM;
354*159d09a2SMark Phalan } else {
355*159d09a2SMark Phalan size_t newsize = (opts->num_pa_opts + 1) * sizeof(krb5_gic_opt_pa_data);
356*159d09a2SMark Phalan x = realloc(opts->pa_opts, newsize);
357*159d09a2SMark Phalan if (x == NULL)
358*159d09a2SMark Phalan return ENOMEM;
359*159d09a2SMark Phalan opts->pa_opts = x;
360*159d09a2SMark Phalan }
361*159d09a2SMark Phalan p = &opts->pa_opts[opts->num_pa_opts];
362*159d09a2SMark Phalan sep = strchr(av, '=');
363*159d09a2SMark Phalan if (sep) {
364*159d09a2SMark Phalan *sep = '\0';
365*159d09a2SMark Phalan v = ++sep;
366*159d09a2SMark Phalan p->value = v;
367*159d09a2SMark Phalan } else {
368*159d09a2SMark Phalan p->value = "yes";
369*159d09a2SMark Phalan }
370*159d09a2SMark Phalan p->attr = av;
371*159d09a2SMark Phalan opts->num_pa_opts++;
372*159d09a2SMark Phalan return 0;
373*159d09a2SMark Phalan }
374*159d09a2SMark Phalan
37556a424ccSmp153739 static char *
parse_options(argc,argv,opts,progname)37656a424ccSmp153739 parse_options(argc, argv, opts, progname)
3777c478bd9Sstevel@tonic-gate int argc;
3787c478bd9Sstevel@tonic-gate char **argv;
3797c478bd9Sstevel@tonic-gate struct k_opts* opts;
38056a424ccSmp153739 char *progname;
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate krb5_error_code code;
3837c478bd9Sstevel@tonic-gate int errflg = 0;
3847c478bd9Sstevel@tonic-gate int use_k4 = 0;
3857c478bd9Sstevel@tonic-gate int use_k5 = 0;
3867c478bd9Sstevel@tonic-gate int i;
3877c478bd9Sstevel@tonic-gate
388*159d09a2SMark Phalan while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:vX:"))
3897c478bd9Sstevel@tonic-gate != -1) {
3907c478bd9Sstevel@tonic-gate switch (i) {
3917c478bd9Sstevel@tonic-gate case 'V':
3927c478bd9Sstevel@tonic-gate opts->verbose = 1;
3937c478bd9Sstevel@tonic-gate break;
3947c478bd9Sstevel@tonic-gate case 'l':
3957c478bd9Sstevel@tonic-gate /* Lifetime */
3967c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->lifetime);
3977c478bd9Sstevel@tonic-gate if (code != 0 || opts->lifetime == 0) {
3987c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg);
3997c478bd9Sstevel@tonic-gate errflg++;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate break;
4027c478bd9Sstevel@tonic-gate case 'r':
4037c478bd9Sstevel@tonic-gate /* Renewable Time */
4047c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->rlife);
4057c478bd9Sstevel@tonic-gate if (code != 0 || opts->rlife == 0) {
4067c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg);
4077c478bd9Sstevel@tonic-gate errflg++;
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate break;
4107c478bd9Sstevel@tonic-gate case 'f':
4117c478bd9Sstevel@tonic-gate opts->forwardable = 1;
4127c478bd9Sstevel@tonic-gate break;
4137c478bd9Sstevel@tonic-gate case 'F':
4147c478bd9Sstevel@tonic-gate opts->not_forwardable = 1;
4157c478bd9Sstevel@tonic-gate break;
4167c478bd9Sstevel@tonic-gate case 'p':
4177c478bd9Sstevel@tonic-gate opts->proxiable = 1;
4187c478bd9Sstevel@tonic-gate break;
4197c478bd9Sstevel@tonic-gate case 'P':
4207c478bd9Sstevel@tonic-gate opts->not_proxiable = 1;
4217c478bd9Sstevel@tonic-gate break;
4227c478bd9Sstevel@tonic-gate case 'a':
4237c478bd9Sstevel@tonic-gate /* Note: This is supported only with GETOPT_LONG */
4247c478bd9Sstevel@tonic-gate opts->addresses = 1;
4257c478bd9Sstevel@tonic-gate break;
4267c478bd9Sstevel@tonic-gate case 'A':
4277c478bd9Sstevel@tonic-gate opts->no_addresses = 1;
4287c478bd9Sstevel@tonic-gate break;
4297c478bd9Sstevel@tonic-gate case 's':
4307c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->starttime);
4317c478bd9Sstevel@tonic-gate if (code != 0 || opts->starttime == 0) {
4327c478bd9Sstevel@tonic-gate krb5_timestamp abs_starttime;
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate code = krb5_string_to_timestamp(optarg, &abs_starttime);
4357c478bd9Sstevel@tonic-gate if (code != 0 || abs_starttime == 0) {
4367c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad start time value %s\n"), optarg);
4377c478bd9Sstevel@tonic-gate errflg++;
4387c478bd9Sstevel@tonic-gate } else {
4397c478bd9Sstevel@tonic-gate opts->starttime = abs_starttime - time(0);
4407c478bd9Sstevel@tonic-gate }
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate break;
4437c478bd9Sstevel@tonic-gate case 'S':
4447c478bd9Sstevel@tonic-gate opts->service_name = optarg;
4457c478bd9Sstevel@tonic-gate break;
4467c478bd9Sstevel@tonic-gate case 'k':
4477c478bd9Sstevel@tonic-gate opts->action = INIT_KT;
4487c478bd9Sstevel@tonic-gate break;
4497c478bd9Sstevel@tonic-gate case 't':
4507c478bd9Sstevel@tonic-gate if (opts->keytab_name)
4517c478bd9Sstevel@tonic-gate {
4527c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one -t option allowed.\n"));
4537c478bd9Sstevel@tonic-gate errflg++;
4547c478bd9Sstevel@tonic-gate } else {
4557c478bd9Sstevel@tonic-gate opts->keytab_name = optarg;
4567c478bd9Sstevel@tonic-gate }
4577c478bd9Sstevel@tonic-gate break;
4587c478bd9Sstevel@tonic-gate case 'R':
4597c478bd9Sstevel@tonic-gate opts->action = RENEW;
4607c478bd9Sstevel@tonic-gate break;
4617c478bd9Sstevel@tonic-gate case 'v':
4627c478bd9Sstevel@tonic-gate opts->action = VALIDATE;
4637c478bd9Sstevel@tonic-gate break;
4647c478bd9Sstevel@tonic-gate case 'c':
4657c478bd9Sstevel@tonic-gate if (opts->k5_cache_name)
4667c478bd9Sstevel@tonic-gate {
4677c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one -c option allowed\n"));
4687c478bd9Sstevel@tonic-gate errflg++;
4697c478bd9Sstevel@tonic-gate } else {
4707c478bd9Sstevel@tonic-gate opts->k5_cache_name = optarg;
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate break;
473*159d09a2SMark Phalan case 'X':
474*159d09a2SMark Phalan code = add_preauth_opt(opts, optarg);
475*159d09a2SMark Phalan if (code)
476*159d09a2SMark Phalan {
477*159d09a2SMark Phalan com_err(progname, code, "while adding preauth option");
478*159d09a2SMark Phalan errflg++;
479*159d09a2SMark Phalan }
480*159d09a2SMark Phalan break;
4817c478bd9Sstevel@tonic-gate #if 0
4827c478bd9Sstevel@tonic-gate /*
4837c478bd9Sstevel@tonic-gate A little more work is needed before we can enable this
4847c478bd9Sstevel@tonic-gate option.
4857c478bd9Sstevel@tonic-gate */
4867c478bd9Sstevel@tonic-gate case 'C':
4877c478bd9Sstevel@tonic-gate if (opts->k4_cache_name)
4887c478bd9Sstevel@tonic-gate {
4897c478bd9Sstevel@tonic-gate fprintf(stderr, "Only one -C option allowed\n");
4907c478bd9Sstevel@tonic-gate errflg++;
4917c478bd9Sstevel@tonic-gate } else {
4927c478bd9Sstevel@tonic-gate opts->k4_cache_name = optarg;
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate break;
4957c478bd9Sstevel@tonic-gate #endif
4967c478bd9Sstevel@tonic-gate case '4':
4977c478bd9Sstevel@tonic-gate if (!got_k4)
4987c478bd9Sstevel@tonic-gate {
4997c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
5007c478bd9Sstevel@tonic-gate fprintf(stderr, "Kerberos 4 support could not be loaded\n");
5017c478bd9Sstevel@tonic-gate #else
5027c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("This was not built with Kerberos 4 support\n"));
5037c478bd9Sstevel@tonic-gate #endif
5047c478bd9Sstevel@tonic-gate exit(3);
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate use_k4 = 1;
5077c478bd9Sstevel@tonic-gate break;
5087c478bd9Sstevel@tonic-gate case '5':
5097c478bd9Sstevel@tonic-gate if (!got_k5)
5107c478bd9Sstevel@tonic-gate {
5117c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n"));
5127c478bd9Sstevel@tonic-gate exit(3);
5137c478bd9Sstevel@tonic-gate }
5147c478bd9Sstevel@tonic-gate use_k5 = 1;
5157c478bd9Sstevel@tonic-gate break;
5167c478bd9Sstevel@tonic-gate default:
5177c478bd9Sstevel@tonic-gate errflg++;
5187c478bd9Sstevel@tonic-gate break;
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate if (opts->forwardable && opts->not_forwardable)
5237c478bd9Sstevel@tonic-gate {
5247c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -f and -F allowed\n"));
5257c478bd9Sstevel@tonic-gate errflg++;
5267c478bd9Sstevel@tonic-gate }
5277c478bd9Sstevel@tonic-gate if (opts->proxiable && opts->not_proxiable)
5287c478bd9Sstevel@tonic-gate {
5297c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -p and -P allowed\n"));
5307c478bd9Sstevel@tonic-gate errflg++;
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate if (opts->addresses && opts->no_addresses)
5337c478bd9Sstevel@tonic-gate {
5347c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -a and -A allowed\n"));
5357c478bd9Sstevel@tonic-gate errflg++;
5367c478bd9Sstevel@tonic-gate }
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate if (argc - optind > 1) {
5397c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Extra arguments (starting with \"%s\").\n"),
5407c478bd9Sstevel@tonic-gate argv[optind+1]);
5417c478bd9Sstevel@tonic-gate errflg++;
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate /* At this point, if errorless, we know we only have one option
5457c478bd9Sstevel@tonic-gate selection */
5467c478bd9Sstevel@tonic-gate if (!use_k5 && !use_k4) {
5477c478bd9Sstevel@tonic-gate use_k5 = default_k5;
5487c478bd9Sstevel@tonic-gate use_k4 = default_k4;
5497c478bd9Sstevel@tonic-gate }
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate /* Now, we encode the OPTTYPE stuff here... */
5527c478bd9Sstevel@tonic-gate if (!use_k5 &&
5537c478bd9Sstevel@tonic-gate (opts->starttime || opts->rlife || opts->forwardable ||
5547c478bd9Sstevel@tonic-gate opts->proxiable || opts->addresses || opts->not_forwardable ||
5557c478bd9Sstevel@tonic-gate opts->not_proxiable || opts->no_addresses ||
5567c478bd9Sstevel@tonic-gate (opts->action == VALIDATE) || opts->k5_cache_name))
5577c478bd9Sstevel@tonic-gate {
5587c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that requires Kerberos 5\n"));
5597c478bd9Sstevel@tonic-gate errflg++;
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate if (!use_k4 &&
5627c478bd9Sstevel@tonic-gate opts->k4_cache_name)
5637c478bd9Sstevel@tonic-gate {
5647c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that require Kerberos 4\n"));
5657c478bd9Sstevel@tonic-gate errflg++;
5667c478bd9Sstevel@tonic-gate }
5677c478bd9Sstevel@tonic-gate if (
5687c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
5697c478bd9Sstevel@tonic-gate !use_k5
5707c478bd9Sstevel@tonic-gate #else
5717c478bd9Sstevel@tonic-gate use_k4
5727c478bd9Sstevel@tonic-gate #endif
5737c478bd9Sstevel@tonic-gate && (opts->service_name || opts->keytab_name ||
5747c478bd9Sstevel@tonic-gate (opts->action == INIT_KT) || (opts->action == RENEW))
5757c478bd9Sstevel@tonic-gate )
5767c478bd9Sstevel@tonic-gate {
5777c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that requires Kerberos 5\n"));
5787c478bd9Sstevel@tonic-gate errflg++;
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate if (errflg) {
58256a424ccSmp153739 usage(progname);
5837c478bd9Sstevel@tonic-gate }
5847c478bd9Sstevel@tonic-gate
5857c478bd9Sstevel@tonic-gate got_k5 = got_k5 && use_k5;
5867c478bd9Sstevel@tonic-gate got_k4 = got_k4 && use_k4;
5877c478bd9Sstevel@tonic-gate
5887c478bd9Sstevel@tonic-gate opts->principal_name = (optind == argc-1) ? argv[optind] : 0;
5897c478bd9Sstevel@tonic-gate return opts->principal_name;
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate
59256a424ccSmp153739 static int
k5_begin(opts,k5,k4)5937c478bd9Sstevel@tonic-gate k5_begin(opts, k5, k4)
5947c478bd9Sstevel@tonic-gate struct k_opts* opts;
5957c478bd9Sstevel@tonic-gate struct k5_data* k5;
5967c478bd9Sstevel@tonic-gate struct k4_data* k4;
5977c478bd9Sstevel@tonic-gate {
5987c478bd9Sstevel@tonic-gate char* progname = progname_v5;
5997c478bd9Sstevel@tonic-gate krb5_error_code code = 0;
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate if (!got_k5)
6027c478bd9Sstevel@tonic-gate return 0;
6037c478bd9Sstevel@tonic-gate
60456a424ccSmp153739 code = krb5_init_context(&k5->ctx);
60556a424ccSmp153739 if (code) {
6067c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while initializing Kerberos 5 library"));
6077c478bd9Sstevel@tonic-gate return 0;
6087c478bd9Sstevel@tonic-gate }
609*159d09a2SMark Phalan errctx = k5->ctx;
6107c478bd9Sstevel@tonic-gate if (opts->k5_cache_name)
6117c478bd9Sstevel@tonic-gate {
6127c478bd9Sstevel@tonic-gate code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
6137c478bd9Sstevel@tonic-gate if (code != 0) {
6147c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("resolving ccache %s"),
6157c478bd9Sstevel@tonic-gate opts->k5_cache_name);
6167c478bd9Sstevel@tonic-gate return 0;
6177c478bd9Sstevel@tonic-gate }
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate else
6207c478bd9Sstevel@tonic-gate {
6217c478bd9Sstevel@tonic-gate if ((code = krb5_cc_default(k5->ctx, &k5->cc))) {
6227c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while getting default ccache"));
6237c478bd9Sstevel@tonic-gate return 0;
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate if (opts->principal_name)
6287c478bd9Sstevel@tonic-gate {
6297c478bd9Sstevel@tonic-gate /* Use specified name */
6307c478bd9Sstevel@tonic-gate if ((code = krb5_parse_name(k5->ctx, opts->principal_name,
6317c478bd9Sstevel@tonic-gate &k5->me))) {
6327c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when parsing name %s"),
6337c478bd9Sstevel@tonic-gate opts->principal_name);
6347c478bd9Sstevel@tonic-gate return 0;
6357c478bd9Sstevel@tonic-gate }
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate else
6387c478bd9Sstevel@tonic-gate {
6397c478bd9Sstevel@tonic-gate /* No principal name specified */
6407c478bd9Sstevel@tonic-gate if (opts->action == INIT_KT) {
6417c478bd9Sstevel@tonic-gate /* Use the default host/service name */
64256a424ccSmp153739 code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
64356a424ccSmp153739 KRB5_NT_SRV_HST, &k5->me);
64456a424ccSmp153739 if (code) {
6457c478bd9Sstevel@tonic-gate com_err(progname, code, gettext(
6467c478bd9Sstevel@tonic-gate "when creating default server principal name"));
6477c478bd9Sstevel@tonic-gate return 0;
6487c478bd9Sstevel@tonic-gate }
6497c478bd9Sstevel@tonic-gate } else {
6507c478bd9Sstevel@tonic-gate /* Get default principal from cache if one exists */
65156a424ccSmp153739 code = krb5_cc_get_principal(k5->ctx, k5->cc,
65256a424ccSmp153739 &k5->me);
65356a424ccSmp153739 if (code)
65456a424ccSmp153739 {
6557c478bd9Sstevel@tonic-gate char *name = get_name_from_os();
6567c478bd9Sstevel@tonic-gate if (!name)
6577c478bd9Sstevel@tonic-gate {
6587c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Unable to identify user\n"));
6597c478bd9Sstevel@tonic-gate return 0;
6607c478bd9Sstevel@tonic-gate }
6617c478bd9Sstevel@tonic-gate /* use strcmp to ensure only "root" is matched */
6627c478bd9Sstevel@tonic-gate if (strcmp(name, ROOT_UNAME) == 0)
6637c478bd9Sstevel@tonic-gate {
6647c478bd9Sstevel@tonic-gate if (code = krb5_sname_to_principal(k5->ctx, NULL, ROOT_UNAME,
6657c478bd9Sstevel@tonic-gate KRB5_NT_SRV_HST, &k5->me)) {
6667c478bd9Sstevel@tonic-gate com_err(progname, code, gettext(
6677c478bd9Sstevel@tonic-gate "when creating default server principal name"));
6687c478bd9Sstevel@tonic-gate return 0;
6697c478bd9Sstevel@tonic-gate }
67056a424ccSmp153739 } else
67156a424ccSmp153739 if ((code = krb5_parse_name(k5->ctx, name,
67256a424ccSmp153739 &k5->me)))
67356a424ccSmp153739 {
6747c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when parsing name %s"),
6757c478bd9Sstevel@tonic-gate name);
6767c478bd9Sstevel@tonic-gate return 0;
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate }
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate }
68156a424ccSmp153739
68256a424ccSmp153739 code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
68356a424ccSmp153739 if (code) {
6847c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when unparsing name"));
6857c478bd9Sstevel@tonic-gate return 0;
6867c478bd9Sstevel@tonic-gate }
6877c478bd9Sstevel@tonic-gate opts->principal_name = k5->name;
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6907c478bd9Sstevel@tonic-gate if (got_k4)
6917c478bd9Sstevel@tonic-gate {
6927c478bd9Sstevel@tonic-gate /* Translate to a Kerberos 4 principal */
6937c478bd9Sstevel@tonic-gate code = krb5_524_conv_principal(k5->ctx, k5->me,
6947c478bd9Sstevel@tonic-gate k4->aname, k4->inst, k4->realm);
6957c478bd9Sstevel@tonic-gate if (code) {
6967c478bd9Sstevel@tonic-gate k4->aname[0] = 0;
6977c478bd9Sstevel@tonic-gate k4->inst[0] = 0;
6987c478bd9Sstevel@tonic-gate k4->realm[0] = 0;
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate }
7017c478bd9Sstevel@tonic-gate #endif
7027c478bd9Sstevel@tonic-gate return 1;
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate
70556a424ccSmp153739 static void
k5_end(k5)7067c478bd9Sstevel@tonic-gate k5_end(k5)
7077c478bd9Sstevel@tonic-gate struct k5_data* k5;
7087c478bd9Sstevel@tonic-gate {
7097c478bd9Sstevel@tonic-gate if (k5->name)
7107c478bd9Sstevel@tonic-gate krb5_free_unparsed_name(k5->ctx, k5->name);
7117c478bd9Sstevel@tonic-gate if (k5->me)
7127c478bd9Sstevel@tonic-gate krb5_free_principal(k5->ctx, k5->me);
7137c478bd9Sstevel@tonic-gate if (k5->cc)
7147c478bd9Sstevel@tonic-gate krb5_cc_close(k5->ctx, k5->cc);
7157c478bd9Sstevel@tonic-gate if (k5->ctx)
7167c478bd9Sstevel@tonic-gate krb5_free_context(k5->ctx);
717*159d09a2SMark Phalan errctx = NULL;
7187c478bd9Sstevel@tonic-gate memset(k5, 0, sizeof(*k5));
7197c478bd9Sstevel@tonic-gate }
7207c478bd9Sstevel@tonic-gate
72156a424ccSmp153739 static int
k4_begin(opts,k4)7227c478bd9Sstevel@tonic-gate k4_begin(opts, k4)
7237c478bd9Sstevel@tonic-gate struct k_opts* opts;
7247c478bd9Sstevel@tonic-gate struct k4_data* k4;
7257c478bd9Sstevel@tonic-gate {
7267c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
7277c478bd9Sstevel@tonic-gate char* progname = progname_v4;
7287c478bd9Sstevel@tonic-gate int k_errno = 0;
7297c478bd9Sstevel@tonic-gate #endif
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate if (!got_k4)
7327c478bd9Sstevel@tonic-gate return 0;
7337c478bd9Sstevel@tonic-gate
7347c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
7357c478bd9Sstevel@tonic-gate if (k4->aname[0])
7367c478bd9Sstevel@tonic-gate goto skip;
7377c478bd9Sstevel@tonic-gate
7387c478bd9Sstevel@tonic-gate if (opts->principal_name)
7397c478bd9Sstevel@tonic-gate {
7407c478bd9Sstevel@tonic-gate /* Use specified name */
74156a424ccSmp153739 k_errno = kname_parse(k4->aname, k4->inst, k4->realm,
74256a424ccSmp153739 opts->principal_name);
74356a424ccSmp153739 if (k_errno)
7447c478bd9Sstevel@tonic-gate {
7457c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname,
7467c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno));
7477c478bd9Sstevel@tonic-gate return 0;
7487c478bd9Sstevel@tonic-gate }
7497c478bd9Sstevel@tonic-gate } else {
7507c478bd9Sstevel@tonic-gate /* No principal name specified */
7517c478bd9Sstevel@tonic-gate if (opts->action == INIT_KT) {
7527c478bd9Sstevel@tonic-gate /* Use the default host/service name */
7537c478bd9Sstevel@tonic-gate /* XXX - need to add this functionality */
7547c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Kerberos 4 srvtab support is not "
7557c478bd9Sstevel@tonic-gate "implemented\n", progname);
7567c478bd9Sstevel@tonic-gate return 0;
7577c478bd9Sstevel@tonic-gate } else {
7587c478bd9Sstevel@tonic-gate /* Get default principal from cache if one exists */
75956a424ccSmp153739 k_errno = krb_get_tf_fullname(tkt_string(), k4->aname,
76056a424ccSmp153739 k4->inst, k4->realm);
76156a424ccSmp153739 if (k_errno)
7627c478bd9Sstevel@tonic-gate {
7637c478bd9Sstevel@tonic-gate char *name = get_name_from_os();
7647c478bd9Sstevel@tonic-gate if (!name)
7657c478bd9Sstevel@tonic-gate {
7667c478bd9Sstevel@tonic-gate fprintf(stderr, "Unable to identify user\n");
7677c478bd9Sstevel@tonic-gate return 0;
7687c478bd9Sstevel@tonic-gate }
76956a424ccSmp153739 k_errno = kname_parse(k4->aname, k4->inst, k4->realm,
77056a424ccSmp153739 name);
77156a424ccSmp153739 if (k_errno)
7727c478bd9Sstevel@tonic-gate {
7737c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname,
7747c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno));
7757c478bd9Sstevel@tonic-gate return 0;
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate }
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate }
7807c478bd9Sstevel@tonic-gate
7817c478bd9Sstevel@tonic-gate if (!k4->realm[0])
7827c478bd9Sstevel@tonic-gate krb_get_lrealm(k4->realm, 1);
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate if (k4->inst[0])
7857c478bd9Sstevel@tonic-gate sprintf(k4->name, "%s.%s@%s", k4->aname, k4->inst, k4->realm);
7867c478bd9Sstevel@tonic-gate else
7877c478bd9Sstevel@tonic-gate sprintf(k4->name, "%s@%s", k4->aname, k4->realm);
7887c478bd9Sstevel@tonic-gate opts->principal_name = k4->name;
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate skip:
7917c478bd9Sstevel@tonic-gate if (k4->aname[0] && !k_isname(k4->aname))
7927c478bd9Sstevel@tonic-gate {
7937c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 name format\n", progname);
7947c478bd9Sstevel@tonic-gate return 0;
7957c478bd9Sstevel@tonic-gate }
7967c478bd9Sstevel@tonic-gate
7977c478bd9Sstevel@tonic-gate if (k4->inst[0] && !k_isinst(k4->inst))
7987c478bd9Sstevel@tonic-gate {
7997c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 instance format\n", progname);
8007c478bd9Sstevel@tonic-gate return 0;
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate
8037c478bd9Sstevel@tonic-gate if (k4->realm[0] && !k_isrealm(k4->realm))
8047c478bd9Sstevel@tonic-gate {
8057c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 realm format\n", progname);
8067c478bd9Sstevel@tonic-gate return 0;
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
8097c478bd9Sstevel@tonic-gate return 1;
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate
81256a424ccSmp153739 static void
k4_end(k4)8137c478bd9Sstevel@tonic-gate k4_end(k4)
8147c478bd9Sstevel@tonic-gate struct k4_data* k4;
8157c478bd9Sstevel@tonic-gate {
8167c478bd9Sstevel@tonic-gate memset(k4, 0, sizeof(*k4));
8177c478bd9Sstevel@tonic-gate }
8187c478bd9Sstevel@tonic-gate
8197c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
8207c478bd9Sstevel@tonic-gate static char stash_password[1024];
8217c478bd9Sstevel@tonic-gate static int got_password = 0;
8227c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
8237c478bd9Sstevel@tonic-gate
82456a424ccSmp153739 static krb5_error_code
8257c478bd9Sstevel@tonic-gate KRB5_CALLCONV
kinit_prompter(krb5_context ctx,void * data,const char * name,const char * banner,int num_prompts,krb5_prompt prompts[])8267c478bd9Sstevel@tonic-gate kinit_prompter(
8277c478bd9Sstevel@tonic-gate krb5_context ctx,
8287c478bd9Sstevel@tonic-gate void *data,
8297c478bd9Sstevel@tonic-gate const char *name,
8307c478bd9Sstevel@tonic-gate const char *banner,
8317c478bd9Sstevel@tonic-gate int num_prompts,
8327c478bd9Sstevel@tonic-gate krb5_prompt prompts[]
8337c478bd9Sstevel@tonic-gate )
8347c478bd9Sstevel@tonic-gate {
8357c478bd9Sstevel@tonic-gate int i;
8367c478bd9Sstevel@tonic-gate krb5_prompt_type *types;
8377c478bd9Sstevel@tonic-gate krb5_error_code rc =
8387c478bd9Sstevel@tonic-gate krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts);
8397c478bd9Sstevel@tonic-gate if (!rc && (types = krb5_get_prompt_types(ctx)))
8407c478bd9Sstevel@tonic-gate for (i = 0; i < num_prompts; i++)
8417c478bd9Sstevel@tonic-gate if ((types[i] == KRB5_PROMPT_TYPE_PASSWORD) ||
8427c478bd9Sstevel@tonic-gate (types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN))
8437c478bd9Sstevel@tonic-gate {
8447c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
8457c478bd9Sstevel@tonic-gate strncpy(stash_password, prompts[i].reply->data,
8467c478bd9Sstevel@tonic-gate sizeof(stash_password));
8477c478bd9Sstevel@tonic-gate got_password = 1;
8487c478bd9Sstevel@tonic-gate #endif
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate return rc;
8517c478bd9Sstevel@tonic-gate }
8527c478bd9Sstevel@tonic-gate
85356a424ccSmp153739 static int
k5_kinit(opts,k5)8547c478bd9Sstevel@tonic-gate k5_kinit(opts, k5)
8557c478bd9Sstevel@tonic-gate struct k_opts* opts;
8567c478bd9Sstevel@tonic-gate struct k5_data* k5;
8577c478bd9Sstevel@tonic-gate {
8587c478bd9Sstevel@tonic-gate char* progname = progname_v5;
8597c478bd9Sstevel@tonic-gate int notix = 1;
8607c478bd9Sstevel@tonic-gate krb5_keytab keytab = 0;
8617c478bd9Sstevel@tonic-gate krb5_creds my_creds;
8627c478bd9Sstevel@tonic-gate krb5_error_code code = 0;
863*159d09a2SMark Phalan krb5_get_init_creds_opt *options = NULL;
864*159d09a2SMark Phalan int i;
8657c478bd9Sstevel@tonic-gate krb5_timestamp now;
8667c478bd9Sstevel@tonic-gate krb5_deltat lifetime = 0, rlife = 0, krb5_max_duration;
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate if (!got_k5)
8697c478bd9Sstevel@tonic-gate return 0;
8707c478bd9Sstevel@tonic-gate
871*159d09a2SMark Phalan code = krb5_get_init_creds_opt_alloc(k5->ctx, &options);
872*159d09a2SMark Phalan if (code)
873*159d09a2SMark Phalan goto cleanup;
8747c478bd9Sstevel@tonic-gate memset(&my_creds, 0, sizeof(my_creds));
8757c478bd9Sstevel@tonic-gate
8767c478bd9Sstevel@tonic-gate /*
8777c478bd9Sstevel@tonic-gate * Solaris Kerberos: added support for max_life and max_renewable_life
8787c478bd9Sstevel@tonic-gate * which should be removed in the next minor release. See PSARC 2003/545
8797c478bd9Sstevel@tonic-gate * for more info.
8807c478bd9Sstevel@tonic-gate *
8817c478bd9Sstevel@tonic-gate * Also, check krb5.conf for proxiable/forwardable/renewable/no_address
8827c478bd9Sstevel@tonic-gate * parameter values.
8837c478bd9Sstevel@tonic-gate */
8847c478bd9Sstevel@tonic-gate /* If either tkt life or renew life weren't set earlier take common steps to
8857c478bd9Sstevel@tonic-gate * get the krb5.conf parameter values.
8867c478bd9Sstevel@tonic-gate */
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate if ((code = krb5_timeofday(k5->ctx, &now))) {
8897c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while getting time of day"));
8907c478bd9Sstevel@tonic-gate exit(1);
8917c478bd9Sstevel@tonic-gate }
8927c478bd9Sstevel@tonic-gate krb5_max_duration = KRB5_KDB_EXPIRATION - now - 60*60;
8937c478bd9Sstevel@tonic-gate
8947c478bd9Sstevel@tonic-gate if (opts->lifetime == 0 || opts->rlife == 0) {
8957c478bd9Sstevel@tonic-gate
8967c478bd9Sstevel@tonic-gate krb_realm = krb5_princ_realm(k5->ctx, k5->me)->data;
8977c478bd9Sstevel@tonic-gate /* realm params take precedence */
8987c478bd9Sstevel@tonic-gate profile_get_options_string(k5->ctx->profile, realmdef, config_times);
8997c478bd9Sstevel@tonic-gate profile_get_options_string(k5->ctx->profile, appdef, config_times);
9007c478bd9Sstevel@tonic-gate
9017c478bd9Sstevel@tonic-gate /* if the input opts doesn't have lifetime set and the krb5.conf
9027c478bd9Sstevel@tonic-gate * parameter has been set, use that.
9037c478bd9Sstevel@tonic-gate */
9047c478bd9Sstevel@tonic-gate if (opts->lifetime == 0 && life_timeval != NULL) {
9057c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(life_timeval, &lifetime);
9067c478bd9Sstevel@tonic-gate if (code != 0 || lifetime == 0 || lifetime > krb5_max_duration) {
9077c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad max_life "
9087c478bd9Sstevel@tonic-gate "value in Kerberos config file %s\n"),
9097c478bd9Sstevel@tonic-gate life_timeval);
9107c478bd9Sstevel@tonic-gate exit(1);
9117c478bd9Sstevel@tonic-gate }
9127c478bd9Sstevel@tonic-gate opts->lifetime = lifetime;
9137c478bd9Sstevel@tonic-gate }
9147c478bd9Sstevel@tonic-gate if (opts->rlife == 0 && renew_timeval != NULL) {
9157c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(renew_timeval, &rlife);
9167c478bd9Sstevel@tonic-gate if (code != 0 || rlife == 0 || rlife > krb5_max_duration) {
9177c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad max_renewable_life "
9187c478bd9Sstevel@tonic-gate "value in Kerberos config file %s\n"),
9197c478bd9Sstevel@tonic-gate renew_timeval);
9207c478bd9Sstevel@tonic-gate exit(1);
9217c478bd9Sstevel@tonic-gate }
9227c478bd9Sstevel@tonic-gate opts->rlife = rlife;
9237c478bd9Sstevel@tonic-gate }
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate /*
9277c478bd9Sstevel@tonic-gate * If lifetime is not set on the cmdline or in the krb5.conf
9287c478bd9Sstevel@tonic-gate * file, default to max.
9297c478bd9Sstevel@tonic-gate */
9307c478bd9Sstevel@tonic-gate if (opts->lifetime == 0)
9317c478bd9Sstevel@tonic-gate opts->lifetime = krb5_max_duration;
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate
9347c478bd9Sstevel@tonic-gate profile_get_options_boolean(k5->ctx->profile,
9357c478bd9Sstevel@tonic-gate realmdef, config_option);
9367c478bd9Sstevel@tonic-gate profile_get_options_boolean(k5->ctx->profile,
9377c478bd9Sstevel@tonic-gate appdef, config_option);
9387c478bd9Sstevel@tonic-gate
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate /* cmdline opts take precedence over krb5.conf file values */
9417c478bd9Sstevel@tonic-gate if (!opts->not_proxiable && proxiable_flag) {
942*159d09a2SMark Phalan krb5_get_init_creds_opt_set_proxiable(options, 1);
9437c478bd9Sstevel@tonic-gate }
9447c478bd9Sstevel@tonic-gate if (!opts->not_forwardable && forwardable_flag) {
945*159d09a2SMark Phalan krb5_get_init_creds_opt_set_forwardable(options, 1);
9467c478bd9Sstevel@tonic-gate }
9477c478bd9Sstevel@tonic-gate if (renewable_flag) {
9487c478bd9Sstevel@tonic-gate /*
9497c478bd9Sstevel@tonic-gate * If this flag is set in krb5.conf, but rlife is 0, then
9507c478bd9Sstevel@tonic-gate * set it to the max (and let the KDC sort it out).
9517c478bd9Sstevel@tonic-gate */
9527c478bd9Sstevel@tonic-gate opts->rlife = opts->rlife ? opts->rlife : krb5_max_duration;
9537c478bd9Sstevel@tonic-gate }
9547c478bd9Sstevel@tonic-gate if (no_address_flag) {
9557c478bd9Sstevel@tonic-gate /* cmdline opts will overwrite this below if needbe */
956*159d09a2SMark Phalan krb5_get_init_creds_opt_set_address_list(options, NULL);
9577c478bd9Sstevel@tonic-gate }
9587c478bd9Sstevel@tonic-gate
9597c478bd9Sstevel@tonic-gate
9607c478bd9Sstevel@tonic-gate /*
9617c478bd9Sstevel@tonic-gate From this point on, we can goto cleanup because my_creds is
9627c478bd9Sstevel@tonic-gate initialized.
9637c478bd9Sstevel@tonic-gate */
9647c478bd9Sstevel@tonic-gate
9657c478bd9Sstevel@tonic-gate if (opts->lifetime)
966*159d09a2SMark Phalan krb5_get_init_creds_opt_set_tkt_life(options, opts->lifetime);
9677c478bd9Sstevel@tonic-gate if (opts->rlife)
968*159d09a2SMark Phalan krb5_get_init_creds_opt_set_renew_life(options, opts->rlife);
9697c478bd9Sstevel@tonic-gate if (opts->forwardable)
970*159d09a2SMark Phalan krb5_get_init_creds_opt_set_forwardable(options, 1);
9717c478bd9Sstevel@tonic-gate if (opts->not_forwardable)
972*159d09a2SMark Phalan krb5_get_init_creds_opt_set_forwardable(options, 0);
9737c478bd9Sstevel@tonic-gate if (opts->proxiable)
974*159d09a2SMark Phalan krb5_get_init_creds_opt_set_proxiable(options, 1);
9757c478bd9Sstevel@tonic-gate if (opts->not_proxiable)
976*159d09a2SMark Phalan krb5_get_init_creds_opt_set_proxiable(options, 0);
9777c478bd9Sstevel@tonic-gate if (opts->addresses)
9787c478bd9Sstevel@tonic-gate {
9797c478bd9Sstevel@tonic-gate krb5_address **addresses = NULL;
9807c478bd9Sstevel@tonic-gate code = krb5_os_localaddr(k5->ctx, &addresses);
9817c478bd9Sstevel@tonic-gate if (code != 0) {
9827c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("getting local addresses"));
9837c478bd9Sstevel@tonic-gate goto cleanup;
9847c478bd9Sstevel@tonic-gate }
985*159d09a2SMark Phalan krb5_get_init_creds_opt_set_address_list(options, addresses);
9867c478bd9Sstevel@tonic-gate }
9877c478bd9Sstevel@tonic-gate if (opts->no_addresses)
988*159d09a2SMark Phalan krb5_get_init_creds_opt_set_address_list(options, NULL);
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate if ((opts->action == INIT_KT) && opts->keytab_name)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
9937c478bd9Sstevel@tonic-gate if (code != 0) {
9947c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("resolving keytab %s"),
9957c478bd9Sstevel@tonic-gate opts->keytab_name);
9967c478bd9Sstevel@tonic-gate goto cleanup;
9977c478bd9Sstevel@tonic-gate }
9987c478bd9Sstevel@tonic-gate }
9997c478bd9Sstevel@tonic-gate
1000*159d09a2SMark Phalan for (i = 0; i < opts->num_pa_opts; i++) {
1001*159d09a2SMark Phalan code = krb5_get_init_creds_opt_set_pa(k5->ctx, options,
1002*159d09a2SMark Phalan opts->pa_opts[i].attr,
1003*159d09a2SMark Phalan opts->pa_opts[i].value);
1004*159d09a2SMark Phalan if (code != 0) {
1005*159d09a2SMark Phalan com_err(progname, code, "while setting '%s'='%s'",
1006*159d09a2SMark Phalan opts->pa_opts[i].attr, opts->pa_opts[i].value);
1007*159d09a2SMark Phalan goto cleanup;
1008*159d09a2SMark Phalan }
1009*159d09a2SMark Phalan }
1010*159d09a2SMark Phalan
10117c478bd9Sstevel@tonic-gate switch (opts->action) {
10127c478bd9Sstevel@tonic-gate case INIT_PW:
10137c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
10147c478bd9Sstevel@tonic-gate 0, kinit_prompter, 0,
10157c478bd9Sstevel@tonic-gate opts->starttime,
10167c478bd9Sstevel@tonic-gate opts->service_name,
1017*159d09a2SMark Phalan options);
10187c478bd9Sstevel@tonic-gate break;
10197c478bd9Sstevel@tonic-gate case INIT_KT:
10207c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
10217c478bd9Sstevel@tonic-gate keytab,
10227c478bd9Sstevel@tonic-gate opts->starttime,
10237c478bd9Sstevel@tonic-gate opts->service_name,
1024*159d09a2SMark Phalan options);
10257c478bd9Sstevel@tonic-gate break;
10267c478bd9Sstevel@tonic-gate case VALIDATE:
10277c478bd9Sstevel@tonic-gate code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
10287c478bd9Sstevel@tonic-gate opts->service_name);
10297c478bd9Sstevel@tonic-gate break;
10307c478bd9Sstevel@tonic-gate case RENEW:
10317c478bd9Sstevel@tonic-gate code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc,
10327c478bd9Sstevel@tonic-gate opts->service_name);
10337c478bd9Sstevel@tonic-gate break;
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate
10367c478bd9Sstevel@tonic-gate if (code) {
10377c478bd9Sstevel@tonic-gate char *doing = 0;
10387c478bd9Sstevel@tonic-gate switch (opts->action) {
10397c478bd9Sstevel@tonic-gate case INIT_PW:
10407c478bd9Sstevel@tonic-gate case INIT_KT:
10417c478bd9Sstevel@tonic-gate doing = gettext("getting initial credentials");
10427c478bd9Sstevel@tonic-gate break;
10437c478bd9Sstevel@tonic-gate case VALIDATE:
10447c478bd9Sstevel@tonic-gate doing = gettext("validating credentials");
10457c478bd9Sstevel@tonic-gate break;
10467c478bd9Sstevel@tonic-gate case RENEW:
10477c478bd9Sstevel@tonic-gate doing = gettext("renewing credentials");
10487c478bd9Sstevel@tonic-gate break;
10497c478bd9Sstevel@tonic-gate }
10507c478bd9Sstevel@tonic-gate
10517c478bd9Sstevel@tonic-gate /* If got code == KRB5_AP_ERR_V4_REPLY && got_k4, we should
10527c478bd9Sstevel@tonic-gate let the user know that maybe he/she wants -4. */
10537c478bd9Sstevel@tonic-gate if (code == KRB5KRB_AP_ERR_V4_REPLY && got_k4)
10547c478bd9Sstevel@tonic-gate com_err(progname, code, "while %s\n"
10557c478bd9Sstevel@tonic-gate "The KDC doesn't support v5. "
10567c478bd9Sstevel@tonic-gate "You may want the -4 option in the future",
10577c478bd9Sstevel@tonic-gate doing);
10587c478bd9Sstevel@tonic-gate else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
10597c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: Password incorrect while %s\n"), progname,
10607c478bd9Sstevel@tonic-gate doing);
10617c478bd9Sstevel@tonic-gate else
10627c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while %s"), doing);
10637c478bd9Sstevel@tonic-gate goto cleanup;
10647c478bd9Sstevel@tonic-gate }
10657c478bd9Sstevel@tonic-gate
10667c478bd9Sstevel@tonic-gate if (!opts->lifetime) {
10677c478bd9Sstevel@tonic-gate /* We need to figure out what lifetime to use for Kerberos 4. */
10687c478bd9Sstevel@tonic-gate opts->lifetime = my_creds.times.endtime - my_creds.times.authtime;
10697c478bd9Sstevel@tonic-gate }
10707c478bd9Sstevel@tonic-gate
107156a424ccSmp153739 code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me);
107256a424ccSmp153739 if (code) {
10737c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when initializing cache %s"),
10747c478bd9Sstevel@tonic-gate opts->k5_cache_name?opts->k5_cache_name:"");
10757c478bd9Sstevel@tonic-gate goto cleanup;
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate
107856a424ccSmp153739 code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);
107956a424ccSmp153739 if (code) {
10807c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while storing credentials"));
10817c478bd9Sstevel@tonic-gate goto cleanup;
10827c478bd9Sstevel@tonic-gate }
10837c478bd9Sstevel@tonic-gate
10847c478bd9Sstevel@tonic-gate if (opts->action == RENEW) {
1085*159d09a2SMark Phalan _kwarnd_del_warning(progname, opts->principal_name);
1086*159d09a2SMark Phalan _kwarnd_add_warning(progname, opts->principal_name, my_creds.times.endtime);
10877c478bd9Sstevel@tonic-gate } else if ((opts->action == INIT_KT) || (opts->action == INIT_PW)) {
1088*159d09a2SMark Phalan _kwarnd_add_warning(progname, opts->principal_name, my_creds.times.endtime);
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate
10917c478bd9Sstevel@tonic-gate notix = 0;
10927c478bd9Sstevel@tonic-gate
10937c478bd9Sstevel@tonic-gate cleanup:
1094*159d09a2SMark Phalan if (options)
1095*159d09a2SMark Phalan krb5_get_init_creds_opt_free(k5->ctx, options);
10967c478bd9Sstevel@tonic-gate if (my_creds.client == k5->me) {
10977c478bd9Sstevel@tonic-gate my_creds.client = 0;
10987c478bd9Sstevel@tonic-gate }
1099*159d09a2SMark Phalan if (opts->pa_opts) {
1100*159d09a2SMark Phalan free(opts->pa_opts);
1101*159d09a2SMark Phalan opts->pa_opts = NULL;
1102*159d09a2SMark Phalan opts->num_pa_opts = 0;
1103*159d09a2SMark Phalan }
11047c478bd9Sstevel@tonic-gate krb5_free_cred_contents(k5->ctx, &my_creds);
11057c478bd9Sstevel@tonic-gate if (keytab)
11067c478bd9Sstevel@tonic-gate krb5_kt_close(k5->ctx, keytab);
11077c478bd9Sstevel@tonic-gate return notix?0:1;
11087c478bd9Sstevel@tonic-gate }
11097c478bd9Sstevel@tonic-gate
111056a424ccSmp153739 static int
k4_kinit(opts,k4,ctx)11117c478bd9Sstevel@tonic-gate k4_kinit(opts, k4, ctx)
11127c478bd9Sstevel@tonic-gate struct k_opts* opts;
11137c478bd9Sstevel@tonic-gate struct k4_data* k4;
11147c478bd9Sstevel@tonic-gate krb5_context ctx;
11157c478bd9Sstevel@tonic-gate {
11167c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
11177c478bd9Sstevel@tonic-gate char* progname = progname_v4;
11187c478bd9Sstevel@tonic-gate int k_errno = 0;
11197c478bd9Sstevel@tonic-gate #endif
11207c478bd9Sstevel@tonic-gate
11217c478bd9Sstevel@tonic-gate if (!got_k4)
11227c478bd9Sstevel@tonic-gate return 0;
11237c478bd9Sstevel@tonic-gate
11247c478bd9Sstevel@tonic-gate if (opts->starttime)
11257c478bd9Sstevel@tonic-gate return 0;
11267c478bd9Sstevel@tonic-gate
11277c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
11287c478bd9Sstevel@tonic-gate if (!k4->lifetime)
11297c478bd9Sstevel@tonic-gate k4->lifetime = opts->lifetime;
11307c478bd9Sstevel@tonic-gate if (!k4->lifetime)
11317c478bd9Sstevel@tonic-gate k4->lifetime = KRB4_BACKUP_DEFAULT_LIFE_SECS;
11327c478bd9Sstevel@tonic-gate
113356a424ccSmp153739 k4->lifetime = krb_time_to_life(0, k4->lifetime);
11347c478bd9Sstevel@tonic-gate
11357c478bd9Sstevel@tonic-gate switch (opts->action)
11367c478bd9Sstevel@tonic-gate {
11377c478bd9Sstevel@tonic-gate case INIT_PW:
11387c478bd9Sstevel@tonic-gate if (!got_password) {
113956a424ccSmp153739 unsigned int pwsize = sizeof(stash_password);
11407c478bd9Sstevel@tonic-gate krb5_error_code code;
11417c478bd9Sstevel@tonic-gate char prompt[1024];
11427c478bd9Sstevel@tonic-gate
11437c478bd9Sstevel@tonic-gate sprintf(prompt, gettext("Password for %s: "), opts->principal_name);
11447c478bd9Sstevel@tonic-gate stash_password[0] = 0;
11457c478bd9Sstevel@tonic-gate /*
11467c478bd9Sstevel@tonic-gate Note: krb5_read_password does not actually look at the
11477c478bd9Sstevel@tonic-gate context, so we're ok even if we don't have a context. If
11487c478bd9Sstevel@tonic-gate we cannot dynamically load krb5, we can substitute any
11497c478bd9Sstevel@tonic-gate decent read password function instead of the krb5 one.
11507c478bd9Sstevel@tonic-gate */
11517c478bd9Sstevel@tonic-gate code = krb5_read_password(ctx, prompt, 0, stash_password, &pwsize);
11527c478bd9Sstevel@tonic-gate if (code || pwsize == 0)
11537c478bd9Sstevel@tonic-gate {
11547c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Error while reading password for '%s'\n"),
11557c478bd9Sstevel@tonic-gate opts->principal_name);
11567c478bd9Sstevel@tonic-gate memset(stash_password, 0, sizeof(stash_password));
11577c478bd9Sstevel@tonic-gate return 0;
11587c478bd9Sstevel@tonic-gate }
11597c478bd9Sstevel@tonic-gate got_password = 1;
11607c478bd9Sstevel@tonic-gate }
11617c478bd9Sstevel@tonic-gate k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt",
11627c478bd9Sstevel@tonic-gate k4->realm, k4->lifetime, stash_password);
11637c478bd9Sstevel@tonic-gate
11647c478bd9Sstevel@tonic-gate if (k_errno) {
11657c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname,
11667c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno));
11677c478bd9Sstevel@tonic-gate if (authed_k5)
11687c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Maybe your KDC does not support v4. "
11697c478bd9Sstevel@tonic-gate "Try the -5 option next time.\n"));
11707c478bd9Sstevel@tonic-gate return 0;
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate return 1;
11737c478bd9Sstevel@tonic-gate #ifndef HAVE_KRB524
11747c478bd9Sstevel@tonic-gate case INIT_KT:
11757c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: srvtabs are not supported\n"), progname);
11767c478bd9Sstevel@tonic-gate return 0;
11777c478bd9Sstevel@tonic-gate case RENEW:
11787c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: renewal of krb4 tickets is not supported\n"),
11797c478bd9Sstevel@tonic-gate progname);
11807c478bd9Sstevel@tonic-gate return 0;
118156a424ccSmp153739 #else
118256a424ccSmp153739 /* These cases are handled by the 524 code - this prevents the compiler
118356a424ccSmp153739 warnings of not using all the enumerated types.
118456a424ccSmp153739 */
118556a424ccSmp153739 case INIT_KT:
118656a424ccSmp153739 case RENEW:
118756a424ccSmp153739 case VALIDATE:
118856a424ccSmp153739 return 0;
11897c478bd9Sstevel@tonic-gate #endif
11907c478bd9Sstevel@tonic-gate }
11917c478bd9Sstevel@tonic-gate #endif
11927c478bd9Sstevel@tonic-gate return 0;
11937c478bd9Sstevel@tonic-gate }
11947c478bd9Sstevel@tonic-gate
119556a424ccSmp153739 static char*
getvprogname(v,progname)119656a424ccSmp153739 getvprogname(v, progname)
119756a424ccSmp153739 char *v, *progname;
11987c478bd9Sstevel@tonic-gate {
119956a424ccSmp153739 unsigned int len = strlen(progname) + 2 + strlen(v) + 2;
12007c478bd9Sstevel@tonic-gate char *ret = malloc(len);
12017c478bd9Sstevel@tonic-gate if (ret)
12027c478bd9Sstevel@tonic-gate sprintf(ret, "%s(v%s)", progname, v);
12037c478bd9Sstevel@tonic-gate else
12047c478bd9Sstevel@tonic-gate ret = progname;
12057c478bd9Sstevel@tonic-gate return ret;
12067c478bd9Sstevel@tonic-gate }
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
12097c478bd9Sstevel@tonic-gate /* Convert krb5 tickets to krb4. */
try_convert524(k5)121056a424ccSmp153739 static int try_convert524(k5)
12117c478bd9Sstevel@tonic-gate struct k5_data* k5;
12127c478bd9Sstevel@tonic-gate {
12137c478bd9Sstevel@tonic-gate char * progname = progname_v524;
12147c478bd9Sstevel@tonic-gate krb5_error_code code = 0;
12157c478bd9Sstevel@tonic-gate int icode = 0;
12167c478bd9Sstevel@tonic-gate krb5_principal kpcserver = 0;
12177c478bd9Sstevel@tonic-gate krb5_creds *v5creds = 0;
12187c478bd9Sstevel@tonic-gate krb5_creds increds;
12197c478bd9Sstevel@tonic-gate CREDENTIALS v4creds;
12207c478bd9Sstevel@tonic-gate
12217c478bd9Sstevel@tonic-gate if (!got_k4 || !got_k5)
12227c478bd9Sstevel@tonic-gate return 0;
12237c478bd9Sstevel@tonic-gate
12247c478bd9Sstevel@tonic-gate memset((char *) &increds, 0, sizeof(increds));
12257c478bd9Sstevel@tonic-gate /*
12267c478bd9Sstevel@tonic-gate From this point on, we can goto cleanup because increds is
12277c478bd9Sstevel@tonic-gate initialized.
12287c478bd9Sstevel@tonic-gate */
12297c478bd9Sstevel@tonic-gate
12307c478bd9Sstevel@tonic-gate if ((code = krb5_build_principal(k5->ctx,
12317c478bd9Sstevel@tonic-gate &kpcserver,
12327c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->length,
12337c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->data,
12347c478bd9Sstevel@tonic-gate "krbtgt",
12357c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->data,
12367c478bd9Sstevel@tonic-gate NULL))) {
12377c478bd9Sstevel@tonic-gate com_err(progname, code, gettext(
12387c478bd9Sstevel@tonic-gate "while creating service principal name"));
12397c478bd9Sstevel@tonic-gate goto cleanup;
12407c478bd9Sstevel@tonic-gate }
12417c478bd9Sstevel@tonic-gate
12427c478bd9Sstevel@tonic-gate increds.client = k5->me;
12437c478bd9Sstevel@tonic-gate increds.server = kpcserver;
12447c478bd9Sstevel@tonic-gate /* Prevent duplicate free calls. */
12457c478bd9Sstevel@tonic-gate kpcserver = 0;
12467c478bd9Sstevel@tonic-gate
12477c478bd9Sstevel@tonic-gate increds.times.endtime = 0;
12487c478bd9Sstevel@tonic-gate increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
12497c478bd9Sstevel@tonic-gate if ((code = krb5_get_credentials(k5->ctx, 0,
12507c478bd9Sstevel@tonic-gate k5->cc,
12517c478bd9Sstevel@tonic-gate &increds,
12527c478bd9Sstevel@tonic-gate &v5creds))) {
12537c478bd9Sstevel@tonic-gate com_err(progname, code,
12547c478bd9Sstevel@tonic-gate gettext("getting V5 credentials"));
12557c478bd9Sstevel@tonic-gate goto cleanup;
12567c478bd9Sstevel@tonic-gate }
12577c478bd9Sstevel@tonic-gate if ((icode = krb524_convert_creds_kdc(k5->ctx,
12587c478bd9Sstevel@tonic-gate v5creds,
12597c478bd9Sstevel@tonic-gate &v4creds))) {
12607c478bd9Sstevel@tonic-gate com_err(progname, icode,
12617c478bd9Sstevel@tonic-gate gettext("converting to V4 credentials"));
12627c478bd9Sstevel@tonic-gate goto cleanup;
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate /* this is stolen from the v4 kinit */
12657c478bd9Sstevel@tonic-gate /* initialize ticket cache */
12667c478bd9Sstevel@tonic-gate if ((icode = in_tkt(v4creds.pname, v4creds.pinst)
12677c478bd9Sstevel@tonic-gate != KSUCCESS)) {
12687c478bd9Sstevel@tonic-gate com_err(progname, icode, gettext(
12697c478bd9Sstevel@tonic-gate "trying to create the V4 ticket file"));
12707c478bd9Sstevel@tonic-gate goto cleanup;
12717c478bd9Sstevel@tonic-gate }
12727c478bd9Sstevel@tonic-gate /* stash ticket, session key, etc. for future use */
12737c478bd9Sstevel@tonic-gate if ((icode = krb_save_credentials(v4creds.service,
12747c478bd9Sstevel@tonic-gate v4creds.instance,
12757c478bd9Sstevel@tonic-gate v4creds.realm,
12767c478bd9Sstevel@tonic-gate v4creds.session,
12777c478bd9Sstevel@tonic-gate v4creds.lifetime,
12787c478bd9Sstevel@tonic-gate v4creds.kvno,
12797c478bd9Sstevel@tonic-gate &(v4creds.ticket_st),
12807c478bd9Sstevel@tonic-gate v4creds.issue_date))) {
12817c478bd9Sstevel@tonic-gate com_err(progname, icode, gettext(
12827c478bd9Sstevel@tonic-gate "trying to save the V4 ticket"));
12837c478bd9Sstevel@tonic-gate goto cleanup;
12847c478bd9Sstevel@tonic-gate }
12857c478bd9Sstevel@tonic-gate
12867c478bd9Sstevel@tonic-gate cleanup:
12877c478bd9Sstevel@tonic-gate memset(&v4creds, 0, sizeof(v4creds));
12887c478bd9Sstevel@tonic-gate if (v5creds)
12897c478bd9Sstevel@tonic-gate krb5_free_creds(k5->ctx, v5creds);
12907c478bd9Sstevel@tonic-gate increds.client = 0;
12917c478bd9Sstevel@tonic-gate krb5_free_cred_contents(k5->ctx, &increds);
12927c478bd9Sstevel@tonic-gate if (kpcserver)
12937c478bd9Sstevel@tonic-gate krb5_free_principal(k5->ctx, kpcserver);
12947c478bd9Sstevel@tonic-gate return !(code || icode);
12957c478bd9Sstevel@tonic-gate }
12967c478bd9Sstevel@tonic-gate #endif /* HAVE_KRB524 */
12977c478bd9Sstevel@tonic-gate
12987c478bd9Sstevel@tonic-gate int
main(argc,argv)12997c478bd9Sstevel@tonic-gate main(argc, argv)
13007c478bd9Sstevel@tonic-gate int argc;
13017c478bd9Sstevel@tonic-gate char **argv;
13027c478bd9Sstevel@tonic-gate {
13037c478bd9Sstevel@tonic-gate struct k_opts opts;
13047c478bd9Sstevel@tonic-gate struct k5_data k5;
13057c478bd9Sstevel@tonic-gate struct k4_data k4;
1306*159d09a2SMark Phalan char *progname;
13077c478bd9Sstevel@tonic-gate
13087c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
13097c478bd9Sstevel@tonic-gate
13107c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
13117c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST"
13127c478bd9Sstevel@tonic-gate #endif
13137c478bd9Sstevel@tonic-gate
13147c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
13157c478bd9Sstevel@tonic-gate
13167c478bd9Sstevel@tonic-gate progname = GET_PROGNAME(argv[0]);
131756a424ccSmp153739 progname_v5 = getvprogname("5", progname);
13187c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
131956a424ccSmp153739 progname_v4 = getvprogname("4", progname);
132056a424ccSmp153739 progname_v524 = getvprogname("524", progname);
13217c478bd9Sstevel@tonic-gate #endif
13227c478bd9Sstevel@tonic-gate
13237c478bd9Sstevel@tonic-gate /* Ensure we can be driven from a pipe */
13247c478bd9Sstevel@tonic-gate if(!isatty(fileno(stdin)))
13257c478bd9Sstevel@tonic-gate setvbuf(stdin, 0, _IONBF, 0);
13267c478bd9Sstevel@tonic-gate if(!isatty(fileno(stdout)))
13277c478bd9Sstevel@tonic-gate setvbuf(stdout, 0, _IONBF, 0);
13287c478bd9Sstevel@tonic-gate if(!isatty(fileno(stderr)))
13297c478bd9Sstevel@tonic-gate setvbuf(stderr, 0, _IONBF, 0);
13307c478bd9Sstevel@tonic-gate
13317c478bd9Sstevel@tonic-gate /*
13327c478bd9Sstevel@tonic-gate This is where we would put in code to dynamically load Kerberos
13337c478bd9Sstevel@tonic-gate libraries. Currenlty, we just get them implicitly.
13347c478bd9Sstevel@tonic-gate */
13357c478bd9Sstevel@tonic-gate got_k5 = 1;
13367c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
13377c478bd9Sstevel@tonic-gate got_k4 = 1;
13387c478bd9Sstevel@tonic-gate #endif
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate memset(&opts, 0, sizeof(opts));
13417c478bd9Sstevel@tonic-gate opts.action = INIT_PW;
13427c478bd9Sstevel@tonic-gate
13437c478bd9Sstevel@tonic-gate memset(&k5, 0, sizeof(k5));
13447c478bd9Sstevel@tonic-gate memset(&k4, 0, sizeof(k4));
13457c478bd9Sstevel@tonic-gate
1346*159d09a2SMark Phalan set_com_err_hook (extended_com_err_fn);
1347*159d09a2SMark Phalan
134856a424ccSmp153739 parse_options(argc, argv, &opts, progname);
13497c478bd9Sstevel@tonic-gate
13507c478bd9Sstevel@tonic-gate got_k5 = k5_begin(&opts, &k5, &k4);
13517c478bd9Sstevel@tonic-gate got_k4 = k4_begin(&opts, &k4);
13527c478bd9Sstevel@tonic-gate
13537c478bd9Sstevel@tonic-gate authed_k5 = k5_kinit(&opts, &k5);
13547c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
13557c478bd9Sstevel@tonic-gate if (authed_k5)
13567c478bd9Sstevel@tonic-gate authed_k4 = try_convert524(&k5);
13577c478bd9Sstevel@tonic-gate #endif
13587c478bd9Sstevel@tonic-gate if (!authed_k4)
13597c478bd9Sstevel@tonic-gate authed_k4 = k4_kinit(&opts, &k4, k5.ctx);
13607c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
13617c478bd9Sstevel@tonic-gate memset(stash_password, 0, sizeof(stash_password));
13627c478bd9Sstevel@tonic-gate #endif
13637c478bd9Sstevel@tonic-gate
13647c478bd9Sstevel@tonic-gate if (authed_k5 && opts.verbose)
13657c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Authenticated to Kerberos v5\n"));
13667c478bd9Sstevel@tonic-gate if (authed_k4 && opts.verbose)
13677c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Authenticated to Kerberos v4\n"));
13687c478bd9Sstevel@tonic-gate
13697c478bd9Sstevel@tonic-gate k5_end(&k5);
13707c478bd9Sstevel@tonic-gate k4_end(&k4);
13717c478bd9Sstevel@tonic-gate
137256a424ccSmp153739 if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4) ||
137356a424ccSmp153739 (!got_k5 && !got_k4))
13747c478bd9Sstevel@tonic-gate exit(1);
13757c478bd9Sstevel@tonic-gate return 0;
13767c478bd9Sstevel@tonic-gate }
13777c478bd9Sstevel@tonic-gate
13787c478bd9Sstevel@tonic-gate static void
_kwarnd_add_warning(char * progname,char * me,time_t endtime)1379*159d09a2SMark Phalan _kwarnd_add_warning(char *progname, char *me, time_t endtime)
13807c478bd9Sstevel@tonic-gate {
13817c478bd9Sstevel@tonic-gate if (kwarn_add_warning(me, endtime) != 0)
13827c478bd9Sstevel@tonic-gate fprintf(stderr, gettext(
13837c478bd9Sstevel@tonic-gate "%s: no ktkt_warnd warning possible\n"), progname);
13847c478bd9Sstevel@tonic-gate return;
13857c478bd9Sstevel@tonic-gate }
13867c478bd9Sstevel@tonic-gate
13877c478bd9Sstevel@tonic-gate
13887c478bd9Sstevel@tonic-gate static void
_kwarnd_del_warning(char * progname,char * me)1389*159d09a2SMark Phalan _kwarnd_del_warning(char *progname, char *me)
13907c478bd9Sstevel@tonic-gate {
13917c478bd9Sstevel@tonic-gate if (kwarn_del_warning(me) != 0)
13927c478bd9Sstevel@tonic-gate fprintf(stderr, gettext(
13937c478bd9Sstevel@tonic-gate "%s: unable to delete ktkt_warnd message for %s\n"),
13947c478bd9Sstevel@tonic-gate progname, me);
13957c478bd9Sstevel@tonic-gate return;
13967c478bd9Sstevel@tonic-gate }
1397