xref: /titanic_41/usr/src/cmd/krb5/kinit/kinit.c (revision 159d09a20817016f09b3ea28d1bdada4a336bb91)
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