xref: /titanic_54/usr/src/cmd/krb5/kinit/kinit.c (revision 56a424cca6b3f91f31bdab72a4626c48c779fe8b)
17c478bd9Sstevel@tonic-gate /*
2*56a424ccSmp153739  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate  * clients/kinit/kinit.c
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * Copyright 1990 by the Massachusetts Institute of Technology.
127c478bd9Sstevel@tonic-gate  * All Rights Reserved.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
157c478bd9Sstevel@tonic-gate  *   require a specific license from the United States Government.
167c478bd9Sstevel@tonic-gate  *   It is the responsibility of any person or organization contemplating
177c478bd9Sstevel@tonic-gate  *   export to obtain such a license before exporting.
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
207c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
217c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
227c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
237c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
247c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
257c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
267c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
277c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
287c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
297c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
307c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
317c478bd9Sstevel@tonic-gate  * or implied warranty.
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * Initialize a credentials cache.
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate #include <k5-int.h>
377c478bd9Sstevel@tonic-gate #include <profile/prof_int.h>
387c478bd9Sstevel@tonic-gate #include <com_err.h>
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <krb5.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
447c478bd9Sstevel@tonic-gate #include <kerberosIV/krb.h>
457c478bd9Sstevel@tonic-gate #define HAVE_KRB524
467c478bd9Sstevel@tonic-gate #else
477c478bd9Sstevel@tonic-gate #undef HAVE_KRB524
487c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #include <string.h>
517c478bd9Sstevel@tonic-gate #include <stdio.h>
527c478bd9Sstevel@tonic-gate #include <time.h>
537c478bd9Sstevel@tonic-gate #include <netdb.h>
547c478bd9Sstevel@tonic-gate #include <locale.h>
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
577c478bd9Sstevel@tonic-gate #include <getopt.h>
587c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */
597c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H
607c478bd9Sstevel@tonic-gate #include <unistd.h>
617c478bd9Sstevel@tonic-gate #else /* HAVE_UNISTD_H */
627c478bd9Sstevel@tonic-gate extern int optind;
637c478bd9Sstevel@tonic-gate extern char *optarg;
647c478bd9Sstevel@tonic-gate extern int getopt();
657c478bd9Sstevel@tonic-gate #endif /* HAVE_UNISTD_H */
667c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #ifndef _WIN32
697c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
707c478bd9Sstevel@tonic-gate #else /* _WIN32 */
717c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x))
727c478bd9Sstevel@tonic-gate #endif /* _WIN32 */
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate #ifdef HAVE_PWD_H
757c478bd9Sstevel@tonic-gate #include <pwd.h>
76*56a424ccSmp153739 static
777c478bd9Sstevel@tonic-gate char * get_name_from_os()
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate     struct passwd *pw;
80*56a424ccSmp153739     if ((pw = getpwuid((int) getuid())))
817c478bd9Sstevel@tonic-gate 	return pw->pw_name;
827c478bd9Sstevel@tonic-gate     return 0;
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate #else /* HAVE_PWD_H */
857c478bd9Sstevel@tonic-gate #ifdef _WIN32
86*56a424ccSmp153739 static
877c478bd9Sstevel@tonic-gate char * get_name_from_os()
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate     static char name[1024];
907c478bd9Sstevel@tonic-gate     DWORD name_size = sizeof(name);
917c478bd9Sstevel@tonic-gate     if (GetUserName(name, &name_size)) {
927c478bd9Sstevel@tonic-gate 	name[sizeof(name)-1] = 0; /* Just to be extra safe */
937c478bd9Sstevel@tonic-gate 	return name;
947c478bd9Sstevel@tonic-gate     } else {
957c478bd9Sstevel@tonic-gate 	return 0;
967c478bd9Sstevel@tonic-gate     }
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate #else /* _WIN32 */
99*56a424ccSmp153739 static
1007c478bd9Sstevel@tonic-gate char * get_name_from_os()
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate     return 0;
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate #endif /* _WIN32 */
1057c478bd9Sstevel@tonic-gate #endif /* HAVE_PWD_H */
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate static char* progname_v5 = 0;
1087c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1097c478bd9Sstevel@tonic-gate static char* progname_v4 = 0;
1107c478bd9Sstevel@tonic-gate static char* progname_v524 = 0;
1117c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
1127c478bd9Sstevel@tonic-gate #include <locale.h>
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate static int got_k5 = 0;
1157c478bd9Sstevel@tonic-gate static int got_k4 = 0;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate static int default_k5 = 1;
1187c478bd9Sstevel@tonic-gate #if defined(KRB5_KRB4_COMPAT) && defined(KINIT_DEFAULT_BOTH)
1197c478bd9Sstevel@tonic-gate static int default_k4 = 1;
1207c478bd9Sstevel@tonic-gate #else /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */
1217c478bd9Sstevel@tonic-gate static int default_k4 = 0;
1227c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate static int authed_k5 = 0;
1257c478bd9Sstevel@tonic-gate static int authed_k4 = 0;
1267c478bd9Sstevel@tonic-gate 
127*56a424ccSmp153739 #define KRB4_BACKUP_DEFAULT_LIFE_SECS 24*60*60 /* 1 day */
1287c478bd9Sstevel@tonic-gate #define	ROOT_UNAME	"root"
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate struct k_opts
1337c478bd9Sstevel@tonic-gate {
1347c478bd9Sstevel@tonic-gate     /* in seconds */
1357c478bd9Sstevel@tonic-gate     krb5_deltat starttime;
1367c478bd9Sstevel@tonic-gate     krb5_deltat lifetime;
1377c478bd9Sstevel@tonic-gate     krb5_deltat rlife;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate     int forwardable;
1407c478bd9Sstevel@tonic-gate     int proxiable;
1417c478bd9Sstevel@tonic-gate     int addresses;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate     int not_forwardable;
1447c478bd9Sstevel@tonic-gate     int not_proxiable;
1457c478bd9Sstevel@tonic-gate     int no_addresses;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate     int verbose;
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate     char* principal_name;
1507c478bd9Sstevel@tonic-gate     char* service_name;
1517c478bd9Sstevel@tonic-gate     char* keytab_name;
1527c478bd9Sstevel@tonic-gate     char* k5_cache_name;
1537c478bd9Sstevel@tonic-gate     char* k4_cache_name;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate     action_type action;
1567c478bd9Sstevel@tonic-gate };
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate int	forwardable_flag = 0;
1597c478bd9Sstevel@tonic-gate int	renewable_flag = 0;
1607c478bd9Sstevel@tonic-gate int	proxiable_flag = 0;
1617c478bd9Sstevel@tonic-gate int	no_address_flag = 0;
1627c478bd9Sstevel@tonic-gate profile_options_boolean	config_option[] = {
1637c478bd9Sstevel@tonic-gate 	{ "forwardable",	&forwardable_flag,	0 },
1647c478bd9Sstevel@tonic-gate 	{ "renewable",		&renewable_flag,	0 },
1657c478bd9Sstevel@tonic-gate 	{ "proxiable",		&proxiable_flag,	0 },
1667c478bd9Sstevel@tonic-gate 	{ "no_addresses",	&no_address_flag,	0 },
1677c478bd9Sstevel@tonic-gate 	{ NULL,			NULL,			0 }
1687c478bd9Sstevel@tonic-gate };
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate char	*renew_timeval=NULL;
1717c478bd9Sstevel@tonic-gate char	*life_timeval=NULL;
1727c478bd9Sstevel@tonic-gate int	lifetime_specified;
1737c478bd9Sstevel@tonic-gate int	renewtime_specified;
1747c478bd9Sstevel@tonic-gate profile_option_strings	config_times[] = {
1757c478bd9Sstevel@tonic-gate 	{ "max_life",		&life_timeval,	0 },
1767c478bd9Sstevel@tonic-gate 	{ "max_renewable_life",	&renew_timeval,	0 },
1777c478bd9Sstevel@tonic-gate 	{ NULL,			NULL,		0 }
1787c478bd9Sstevel@tonic-gate };
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate struct k5_data
1817c478bd9Sstevel@tonic-gate {
1827c478bd9Sstevel@tonic-gate     krb5_context ctx;
1837c478bd9Sstevel@tonic-gate     krb5_ccache cc;
1847c478bd9Sstevel@tonic-gate     krb5_principal me;
1857c478bd9Sstevel@tonic-gate     char* name;
1867c478bd9Sstevel@tonic-gate };
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate struct k4_data
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate     krb5_deltat lifetime;
1917c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1927c478bd9Sstevel@tonic-gate     char aname[ANAME_SZ + 1];
1937c478bd9Sstevel@tonic-gate     char inst[INST_SZ + 1];
1947c478bd9Sstevel@tonic-gate     char realm[REALM_SZ + 1];
1957c478bd9Sstevel@tonic-gate     char name[ANAME_SZ + 1 + INST_SZ + 1 + REALM_SZ + 1];
1967c478bd9Sstevel@tonic-gate #endif /*KRB5_KRB4_COMPAT */
1977c478bd9Sstevel@tonic-gate };
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate char	*realmdef[] = { "realms", NULL, "kinit", NULL };
2007c478bd9Sstevel@tonic-gate char	*appdef[] = { "appdefaults", "kinit", NULL };
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate #define	krb_realm		(*(realmdef + 1))
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate #define	lifetime_specified	config_times[0].found
2057c478bd9Sstevel@tonic-gate #define	renewtime_specified	config_times[1].found
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate /*
2087c478bd9Sstevel@tonic-gate  * Try no preauthentication first; then try the encrypted timestamp
2097c478bd9Sstevel@tonic-gate  */
2107c478bd9Sstevel@tonic-gate krb5_preauthtype * preauth = NULL;
2117c478bd9Sstevel@tonic-gate krb5_preauthtype preauth_list[2] = { 0, -1 };
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate static void _kwarnd_add_warning(char *, time_t);
2147c478bd9Sstevel@tonic-gate static void _kwarnd_del_warning(char *);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
2177c478bd9Sstevel@tonic-gate /* if struct[2] == NULL, then long_getopt acts as if the short flag
2187c478bd9Sstevel@tonic-gate    struct[3] was specified.  If struct[2] != NULL, then struct[3] is
2197c478bd9Sstevel@tonic-gate    stored in *(struct[2]), the array index which was specified is
2207c478bd9Sstevel@tonic-gate    stored in *index, and long_getopt() returns 0. */
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate struct option long_options[] = {
2237c478bd9Sstevel@tonic-gate     { "noforwardable", 0, NULL, 'F' },
2247c478bd9Sstevel@tonic-gate     { "noproxiable", 0, NULL, 'P' },
2257c478bd9Sstevel@tonic-gate     { "addresses", 0, NULL, 'a'},
2267c478bd9Sstevel@tonic-gate     { "forwardable", 0, NULL, 'f' },
2277c478bd9Sstevel@tonic-gate     { "proxiable", 0, NULL, 'p' },
2287c478bd9Sstevel@tonic-gate     { "noaddresses", 0, NULL, 'A' },
2297c478bd9Sstevel@tonic-gate     { NULL, 0, NULL, 0 }
2307c478bd9Sstevel@tonic-gate };
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt_long(argc, argv, str, long_options, 0)
2337c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */
2347c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt(argc, argv, str)
2357c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate /* Save the program name for the error messages */
2387c478bd9Sstevel@tonic-gate static char *progname;
2397c478bd9Sstevel@tonic-gate 
240*56a424ccSmp153739 static void
241*56a424ccSmp153739 usage(progname)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate #define USAGE_BREAK "\n\t"
244*56a424ccSmp153739 
2457c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG
2467c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable"
2477c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE   " | --proxiable | --noproxiable"
2487c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES   " | --addresses | --noaddresses"
2497c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG       USAGE_BREAK
2507c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */
2517c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE ""
2527c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE   ""
2537c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES   ""
2547c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG       ""
2557c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate     fprintf(stderr, "%s : %s  [-V] "
2587c478bd9Sstevel@tonic-gate 	    "[-l lifetime] [-s start_time] "
2597c478bd9Sstevel@tonic-gate 	    USAGE_BREAK
2607c478bd9Sstevel@tonic-gate 	    "[-r renewable_life] "
2617c478bd9Sstevel@tonic-gate 	    "[-f | -F" USAGE_LONG_FORWARDABLE "] "
2627c478bd9Sstevel@tonic-gate 	    USAGE_BREAK_LONG
2637c478bd9Sstevel@tonic-gate 	    "[-p | -P" USAGE_LONG_PROXIABLE "] "
2647c478bd9Sstevel@tonic-gate 	    USAGE_BREAK_LONG
265*56a424ccSmp153739 	    "[-a | -A" USAGE_LONG_ADDRESSES "] "
2667c478bd9Sstevel@tonic-gate 	    USAGE_BREAK
2677c478bd9Sstevel@tonic-gate 	    "[-v] [-R] "
2687c478bd9Sstevel@tonic-gate 	    "[-k [-t keytab_file]] "
2697c478bd9Sstevel@tonic-gate 	    USAGE_BREAK
2707c478bd9Sstevel@tonic-gate 	    "[-c cachename] "
2717c478bd9Sstevel@tonic-gate 	    "[-S service_name] [principal]"
2727c478bd9Sstevel@tonic-gate 	    "\n\n",
2737c478bd9Sstevel@tonic-gate 	    gettext("Usage"), progname);
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available"))
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB5   "5"
2787c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB4   "4"
2797c478bd9Sstevel@tonic-gate #define OPTTYPE_EITHER "Either 4 or 5"
2807c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
2817c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5, or both 5 and 4"
2827c478bd9Sstevel@tonic-gate #else
2837c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5"
2847c478bd9Sstevel@tonic-gate #endif
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
2877c478bd9Sstevel@tonic-gate #define USAGE_OPT_FMT "%s%-50s%s\n"
2887c478bd9Sstevel@tonic-gate #define ULINE(indent, col1, col2) \
2897c478bd9Sstevel@tonic-gate fprintf(stderr, USAGE_OPT_FMT, indent, col1, col2)
290*56a424ccSmp153739 #else
291*56a424ccSmp153739 #define USAGE_OPT_FMT "%s%s\n"
292*56a424ccSmp153739 #define ULINE(indent, col1, col2) \
293*56a424ccSmp153739 fprintf(stderr, USAGE_OPT_FMT, indent, col1)
294*56a424ccSmp153739 #endif
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate     ULINE("    ", "options:", "valid with Kerberos:");
2977c478bd9Sstevel@tonic-gate     fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5));
2987c478bd9Sstevel@tonic-gate     fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4));
2997c478bd9Sstevel@tonic-gate     fprintf(stderr, "\t   (Default behavior is to try %s%s%s%s)\n",
3007c478bd9Sstevel@tonic-gate 	    default_k5?"Kerberos 5":"",
3017c478bd9Sstevel@tonic-gate 	    (default_k5 && default_k4)?gettext(" and "):"",
3027c478bd9Sstevel@tonic-gate 	    default_k4?"Kerberos 4":"",
3037c478bd9Sstevel@tonic-gate 	    (!default_k5 && !default_k4)?gettext("neither"):"");
3047c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-V verbose"),                   OPTTYPE_EITHER);
3057c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-l lifetime"),                  OPTTYPE_EITHER);
3067c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-s start time"),                OPTTYPE_KRB5);
3077c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-r renewable lifetime"),        OPTTYPE_KRB5);
3087c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-f forwardable"),               OPTTYPE_KRB5);
3097c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-F not forwardable"),           OPTTYPE_KRB5);
3107c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-p proxiable"),                 OPTTYPE_KRB5);
3117c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-P not proxiable"),             OPTTYPE_KRB5);
3127c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-A do not include addresses"),  OPTTYPE_KRB5);
313*56a424ccSmp153739     ULINE("\t", gettext("-a include addresses"),         OPTTYPE_KRB5);
3147c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-v validate"),                  OPTTYPE_KRB5);
3157c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-R renew"),                     OPTTYPE_BOTH);
3167c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-k use keytab"),                OPTTYPE_BOTH);
3177c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-t filename of keytab to use"), OPTTYPE_BOTH);
3187c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-c Kerberos 5 cache name"),     OPTTYPE_KRB5);
3197c478bd9Sstevel@tonic-gate     /* This options is not yet available: */
3207c478bd9Sstevel@tonic-gate     /* ULINE("\t", "-C Kerberos 4 cache name",     OPTTYPE_KRB4); */
3217c478bd9Sstevel@tonic-gate     ULINE("\t", gettext("-S service"),                   OPTTYPE_BOTH);
3227c478bd9Sstevel@tonic-gate     exit(2);
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate 
325*56a424ccSmp153739 static char *
326*56a424ccSmp153739 parse_options(argc, argv, opts, progname)
3277c478bd9Sstevel@tonic-gate     int argc;
3287c478bd9Sstevel@tonic-gate     char **argv;
3297c478bd9Sstevel@tonic-gate     struct k_opts* opts;
330*56a424ccSmp153739     char *progname;
3317c478bd9Sstevel@tonic-gate {
3327c478bd9Sstevel@tonic-gate     krb5_error_code code;
3337c478bd9Sstevel@tonic-gate     int errflg = 0;
3347c478bd9Sstevel@tonic-gate     int use_k4 = 0;
3357c478bd9Sstevel@tonic-gate     int use_k5 = 0;
3367c478bd9Sstevel@tonic-gate     int i;
3377c478bd9Sstevel@tonic-gate 
338*56a424ccSmp153739     while ((i = GETOPT(argc, argv, "r:fpFP54aAVl:s:c:kt:RS:v"))
3397c478bd9Sstevel@tonic-gate 	   != -1) {
3407c478bd9Sstevel@tonic-gate 	switch (i) {
3417c478bd9Sstevel@tonic-gate 	case 'V':
3427c478bd9Sstevel@tonic-gate 	    opts->verbose = 1;
3437c478bd9Sstevel@tonic-gate 	    break;
3447c478bd9Sstevel@tonic-gate 	case 'l':
3457c478bd9Sstevel@tonic-gate 	    /* Lifetime */
3467c478bd9Sstevel@tonic-gate 	    code = krb5_string_to_deltat(optarg, &opts->lifetime);
3477c478bd9Sstevel@tonic-gate 	    if (code != 0 || opts->lifetime == 0) {
3487c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg);
3497c478bd9Sstevel@tonic-gate 		errflg++;
3507c478bd9Sstevel@tonic-gate 	    }
3517c478bd9Sstevel@tonic-gate 	    break;
3527c478bd9Sstevel@tonic-gate 	case 'r':
3537c478bd9Sstevel@tonic-gate 	    /* Renewable Time */
3547c478bd9Sstevel@tonic-gate 	    code = krb5_string_to_deltat(optarg, &opts->rlife);
3557c478bd9Sstevel@tonic-gate 	    if (code != 0 || opts->rlife == 0) {
3567c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg);
3577c478bd9Sstevel@tonic-gate 		errflg++;
3587c478bd9Sstevel@tonic-gate 	    }
3597c478bd9Sstevel@tonic-gate 	    break;
3607c478bd9Sstevel@tonic-gate 	case 'f':
3617c478bd9Sstevel@tonic-gate 	    opts->forwardable = 1;
3627c478bd9Sstevel@tonic-gate 	    break;
3637c478bd9Sstevel@tonic-gate 	case 'F':
3647c478bd9Sstevel@tonic-gate 	    opts->not_forwardable = 1;
3657c478bd9Sstevel@tonic-gate 	    break;
3667c478bd9Sstevel@tonic-gate 	case 'p':
3677c478bd9Sstevel@tonic-gate 	    opts->proxiable = 1;
3687c478bd9Sstevel@tonic-gate 	    break;
3697c478bd9Sstevel@tonic-gate 	case 'P':
3707c478bd9Sstevel@tonic-gate 	    opts->not_proxiable = 1;
3717c478bd9Sstevel@tonic-gate 	    break;
3727c478bd9Sstevel@tonic-gate 	case 'a':
3737c478bd9Sstevel@tonic-gate 	    /* Note: This is supported only with GETOPT_LONG */
3747c478bd9Sstevel@tonic-gate 	    opts->addresses = 1;
3757c478bd9Sstevel@tonic-gate 	    break;
3767c478bd9Sstevel@tonic-gate 	case 'A':
3777c478bd9Sstevel@tonic-gate 	    opts->no_addresses = 1;
3787c478bd9Sstevel@tonic-gate 	    break;
3797c478bd9Sstevel@tonic-gate        	case 's':
3807c478bd9Sstevel@tonic-gate 	    code = krb5_string_to_deltat(optarg, &opts->starttime);
3817c478bd9Sstevel@tonic-gate 	    if (code != 0 || opts->starttime == 0) {
3827c478bd9Sstevel@tonic-gate 		krb5_timestamp abs_starttime;
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate 		code = krb5_string_to_timestamp(optarg, &abs_starttime);
3857c478bd9Sstevel@tonic-gate 		if (code != 0 || abs_starttime == 0) {
3867c478bd9Sstevel@tonic-gate 		    fprintf(stderr, gettext("Bad start time value %s\n"), optarg);
3877c478bd9Sstevel@tonic-gate 		    errflg++;
3887c478bd9Sstevel@tonic-gate 		} else {
3897c478bd9Sstevel@tonic-gate 		    opts->starttime = abs_starttime - time(0);
3907c478bd9Sstevel@tonic-gate 		}
3917c478bd9Sstevel@tonic-gate 	    }
3927c478bd9Sstevel@tonic-gate 	    break;
3937c478bd9Sstevel@tonic-gate 	case 'S':
3947c478bd9Sstevel@tonic-gate 	    opts->service_name = optarg;
3957c478bd9Sstevel@tonic-gate 	    break;
3967c478bd9Sstevel@tonic-gate 	case 'k':
3977c478bd9Sstevel@tonic-gate 	    opts->action = INIT_KT;
3987c478bd9Sstevel@tonic-gate 	    break;
3997c478bd9Sstevel@tonic-gate 	case 't':
4007c478bd9Sstevel@tonic-gate 	    if (opts->keytab_name)
4017c478bd9Sstevel@tonic-gate 	    {
4027c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Only one -t option allowed.\n"));
4037c478bd9Sstevel@tonic-gate 		errflg++;
4047c478bd9Sstevel@tonic-gate 	    } else {
4057c478bd9Sstevel@tonic-gate 		opts->keytab_name = optarg;
4067c478bd9Sstevel@tonic-gate 	    }
4077c478bd9Sstevel@tonic-gate 	    break;
4087c478bd9Sstevel@tonic-gate 	case 'R':
4097c478bd9Sstevel@tonic-gate 	    opts->action = RENEW;
4107c478bd9Sstevel@tonic-gate 	    break;
4117c478bd9Sstevel@tonic-gate 	case 'v':
4127c478bd9Sstevel@tonic-gate 	    opts->action = VALIDATE;
4137c478bd9Sstevel@tonic-gate 	    break;
4147c478bd9Sstevel@tonic-gate        	case 'c':
4157c478bd9Sstevel@tonic-gate 	    if (opts->k5_cache_name)
4167c478bd9Sstevel@tonic-gate 	    {
4177c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Only one -c option allowed\n"));
4187c478bd9Sstevel@tonic-gate 		errflg++;
4197c478bd9Sstevel@tonic-gate 	    } else {
4207c478bd9Sstevel@tonic-gate 		opts->k5_cache_name = optarg;
4217c478bd9Sstevel@tonic-gate 	    }
4227c478bd9Sstevel@tonic-gate 	    break;
4237c478bd9Sstevel@tonic-gate #if 0
4247c478bd9Sstevel@tonic-gate 	    /*
4257c478bd9Sstevel@tonic-gate 	      A little more work is needed before we can enable this
4267c478bd9Sstevel@tonic-gate 	      option.
4277c478bd9Sstevel@tonic-gate 	    */
4287c478bd9Sstevel@tonic-gate 	case 'C':
4297c478bd9Sstevel@tonic-gate 	    if (opts->k4_cache_name)
4307c478bd9Sstevel@tonic-gate 	    {
4317c478bd9Sstevel@tonic-gate 		fprintf(stderr, "Only one -C option allowed\n");
4327c478bd9Sstevel@tonic-gate 		errflg++;
4337c478bd9Sstevel@tonic-gate 	    } else {
4347c478bd9Sstevel@tonic-gate 		opts->k4_cache_name = optarg;
4357c478bd9Sstevel@tonic-gate 	    }
4367c478bd9Sstevel@tonic-gate 	    break;
4377c478bd9Sstevel@tonic-gate #endif
4387c478bd9Sstevel@tonic-gate 	case '4':
4397c478bd9Sstevel@tonic-gate 	    if (!got_k4)
4407c478bd9Sstevel@tonic-gate 	    {
4417c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
4427c478bd9Sstevel@tonic-gate 		fprintf(stderr, "Kerberos 4 support could not be loaded\n");
4437c478bd9Sstevel@tonic-gate #else
4447c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("This was not built with Kerberos 4 support\n"));
4457c478bd9Sstevel@tonic-gate #endif
4467c478bd9Sstevel@tonic-gate 		exit(3);
4477c478bd9Sstevel@tonic-gate 	    }
4487c478bd9Sstevel@tonic-gate 	    use_k4 = 1;
4497c478bd9Sstevel@tonic-gate 	    break;
4507c478bd9Sstevel@tonic-gate 	case '5':
4517c478bd9Sstevel@tonic-gate 	    if (!got_k5)
4527c478bd9Sstevel@tonic-gate 	    {
4537c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n"));
4547c478bd9Sstevel@tonic-gate 		exit(3);
4557c478bd9Sstevel@tonic-gate 	    }
4567c478bd9Sstevel@tonic-gate 	    use_k5 = 1;
4577c478bd9Sstevel@tonic-gate 	    break;
4587c478bd9Sstevel@tonic-gate 	default:
4597c478bd9Sstevel@tonic-gate 	    errflg++;
4607c478bd9Sstevel@tonic-gate 	    break;
4617c478bd9Sstevel@tonic-gate 	}
4627c478bd9Sstevel@tonic-gate     }
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate     if (opts->forwardable && opts->not_forwardable)
4657c478bd9Sstevel@tonic-gate     {
4667c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Only one of -f and -F allowed\n"));
4677c478bd9Sstevel@tonic-gate 	errflg++;
4687c478bd9Sstevel@tonic-gate     }
4697c478bd9Sstevel@tonic-gate     if (opts->proxiable && opts->not_proxiable)
4707c478bd9Sstevel@tonic-gate     {
4717c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Only one of -p and -P allowed\n"));
4727c478bd9Sstevel@tonic-gate 	errflg++;
4737c478bd9Sstevel@tonic-gate     }
4747c478bd9Sstevel@tonic-gate     if (opts->addresses && opts->no_addresses)
4757c478bd9Sstevel@tonic-gate     {
4767c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Only one of -a and -A allowed\n"));
4777c478bd9Sstevel@tonic-gate 	errflg++;
4787c478bd9Sstevel@tonic-gate     }
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate     if (argc - optind > 1) {
4817c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Extra arguments (starting with \"%s\").\n"),
4827c478bd9Sstevel@tonic-gate 		argv[optind+1]);
4837c478bd9Sstevel@tonic-gate 	errflg++;
4847c478bd9Sstevel@tonic-gate     }
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate     /* At this point, if errorless, we know we only have one option
4877c478bd9Sstevel@tonic-gate        selection */
4887c478bd9Sstevel@tonic-gate     if (!use_k5 && !use_k4) {
4897c478bd9Sstevel@tonic-gate 	use_k5 = default_k5;
4907c478bd9Sstevel@tonic-gate 	use_k4 = default_k4;
4917c478bd9Sstevel@tonic-gate     }
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate     /* Now, we encode the OPTTYPE stuff here... */
4947c478bd9Sstevel@tonic-gate     if (!use_k5 &&
4957c478bd9Sstevel@tonic-gate 	(opts->starttime || opts->rlife || opts->forwardable ||
4967c478bd9Sstevel@tonic-gate 	 opts->proxiable || opts->addresses || opts->not_forwardable ||
4977c478bd9Sstevel@tonic-gate 	 opts->not_proxiable || opts->no_addresses ||
4987c478bd9Sstevel@tonic-gate 	 (opts->action == VALIDATE) || opts->k5_cache_name))
4997c478bd9Sstevel@tonic-gate     {
5007c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Specified option that requires Kerberos 5\n"));
5017c478bd9Sstevel@tonic-gate 	errflg++;
5027c478bd9Sstevel@tonic-gate     }
5037c478bd9Sstevel@tonic-gate     if (!use_k4 &&
5047c478bd9Sstevel@tonic-gate 	opts->k4_cache_name)
5057c478bd9Sstevel@tonic-gate     {
5067c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Specified option that require Kerberos 4\n"));
5077c478bd9Sstevel@tonic-gate 	errflg++;
5087c478bd9Sstevel@tonic-gate     }
5097c478bd9Sstevel@tonic-gate     if (
5107c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
5117c478bd9Sstevel@tonic-gate 	!use_k5
5127c478bd9Sstevel@tonic-gate #else
5137c478bd9Sstevel@tonic-gate 	use_k4
5147c478bd9Sstevel@tonic-gate #endif
5157c478bd9Sstevel@tonic-gate 	&& (opts->service_name || opts->keytab_name ||
5167c478bd9Sstevel@tonic-gate 	    (opts->action == INIT_KT) || (opts->action == RENEW))
5177c478bd9Sstevel@tonic-gate 	)
5187c478bd9Sstevel@tonic-gate     {
5197c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Specified option that requires Kerberos 5\n"));
5207c478bd9Sstevel@tonic-gate 	errflg++;
5217c478bd9Sstevel@tonic-gate     }
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate     if (errflg) {
524*56a424ccSmp153739 	usage(progname);
5257c478bd9Sstevel@tonic-gate     }
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate     got_k5 = got_k5 && use_k5;
5287c478bd9Sstevel@tonic-gate     got_k4 = got_k4 && use_k4;
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate     opts->principal_name = (optind == argc-1) ? argv[optind] : 0;
5317c478bd9Sstevel@tonic-gate     return opts->principal_name;
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate 
534*56a424ccSmp153739 static int
5357c478bd9Sstevel@tonic-gate k5_begin(opts, k5, k4)
5367c478bd9Sstevel@tonic-gate     struct k_opts* opts;
5377c478bd9Sstevel@tonic-gate struct k5_data* k5;
5387c478bd9Sstevel@tonic-gate struct k4_data* k4;
5397c478bd9Sstevel@tonic-gate {
5407c478bd9Sstevel@tonic-gate     char* progname = progname_v5;
5417c478bd9Sstevel@tonic-gate     krb5_error_code code = 0;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate     if (!got_k5)
5447c478bd9Sstevel@tonic-gate 	return 0;
5457c478bd9Sstevel@tonic-gate 
546*56a424ccSmp153739     code = krb5_init_context(&k5->ctx);
547*56a424ccSmp153739     if (code) {
5487c478bd9Sstevel@tonic-gate 	com_err(progname, code, gettext("while initializing Kerberos 5 library"));
5497c478bd9Sstevel@tonic-gate 	return 0;
5507c478bd9Sstevel@tonic-gate     }
5517c478bd9Sstevel@tonic-gate     if (opts->k5_cache_name)
5527c478bd9Sstevel@tonic-gate     {
5537c478bd9Sstevel@tonic-gate 	code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
5547c478bd9Sstevel@tonic-gate 	if (code != 0) {
5557c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("resolving ccache %s"),
5567c478bd9Sstevel@tonic-gate 		    opts->k5_cache_name);
5577c478bd9Sstevel@tonic-gate 	    return 0;
5587c478bd9Sstevel@tonic-gate 	}
5597c478bd9Sstevel@tonic-gate     }
5607c478bd9Sstevel@tonic-gate     else
5617c478bd9Sstevel@tonic-gate     {
5627c478bd9Sstevel@tonic-gate 	if ((code = krb5_cc_default(k5->ctx, &k5->cc))) {
5637c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("while getting default ccache"));
5647c478bd9Sstevel@tonic-gate 	    return 0;
5657c478bd9Sstevel@tonic-gate 	}
5667c478bd9Sstevel@tonic-gate     }
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate     if (opts->principal_name)
5697c478bd9Sstevel@tonic-gate     {
5707c478bd9Sstevel@tonic-gate 	/* Use specified name */
5717c478bd9Sstevel@tonic-gate 	if ((code = krb5_parse_name(k5->ctx, opts->principal_name,
5727c478bd9Sstevel@tonic-gate 				    &k5->me))) {
5737c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("when parsing name %s"),
5747c478bd9Sstevel@tonic-gate 		    opts->principal_name);
5757c478bd9Sstevel@tonic-gate 	    return 0;
5767c478bd9Sstevel@tonic-gate 	}
5777c478bd9Sstevel@tonic-gate     }
5787c478bd9Sstevel@tonic-gate     else
5797c478bd9Sstevel@tonic-gate     {
5807c478bd9Sstevel@tonic-gate 	/* No principal name specified */
5817c478bd9Sstevel@tonic-gate 	if (opts->action == INIT_KT) {
5827c478bd9Sstevel@tonic-gate 	    /* Use the default host/service name */
583*56a424ccSmp153739 	  code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
584*56a424ccSmp153739 					 KRB5_NT_SRV_HST, &k5->me);
585*56a424ccSmp153739 	  if (code) {
5867c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext(
5877c478bd9Sstevel@tonic-gate 		    "when creating default server principal name"));
5887c478bd9Sstevel@tonic-gate 	    return 0;
5897c478bd9Sstevel@tonic-gate 	  }
5907c478bd9Sstevel@tonic-gate 	} else {
5917c478bd9Sstevel@tonic-gate 	  /* Get default principal from cache if one exists */
592*56a424ccSmp153739 	  code = krb5_cc_get_principal(k5->ctx, k5->cc,
593*56a424ccSmp153739 				       &k5->me);
594*56a424ccSmp153739 	  if (code)
595*56a424ccSmp153739 	    {
5967c478bd9Sstevel@tonic-gate 	      char *name = get_name_from_os();
5977c478bd9Sstevel@tonic-gate 	      if (!name)
5987c478bd9Sstevel@tonic-gate 		{
5997c478bd9Sstevel@tonic-gate 		  fprintf(stderr, gettext("Unable to identify user\n"));
6007c478bd9Sstevel@tonic-gate 		  return 0;
6017c478bd9Sstevel@tonic-gate 		}
6027c478bd9Sstevel@tonic-gate                 /* use strcmp to ensure only "root" is matched */
6037c478bd9Sstevel@tonic-gate                 if (strcmp(name, ROOT_UNAME) == 0)
6047c478bd9Sstevel@tonic-gate                 {
6057c478bd9Sstevel@tonic-gate                 	if (code = krb5_sname_to_principal(k5->ctx, NULL, ROOT_UNAME,
6067c478bd9Sstevel@tonic-gate 				    KRB5_NT_SRV_HST, &k5->me)) {
6077c478bd9Sstevel@tonic-gate 			    com_err(progname, code, gettext(
6087c478bd9Sstevel@tonic-gate 				"when creating default server principal name"));
6097c478bd9Sstevel@tonic-gate                                 return 0;
6107c478bd9Sstevel@tonic-gate                         }
611*56a424ccSmp153739                 } else
612*56a424ccSmp153739 	      if ((code = krb5_parse_name(k5->ctx, name,
613*56a424ccSmp153739 					  &k5->me)))
614*56a424ccSmp153739 		{
6157c478bd9Sstevel@tonic-gate 		  com_err(progname, code, gettext("when parsing name %s"),
6167c478bd9Sstevel@tonic-gate 			  name);
6177c478bd9Sstevel@tonic-gate 		  return 0;
6187c478bd9Sstevel@tonic-gate 		}
6197c478bd9Sstevel@tonic-gate 	    }
6207c478bd9Sstevel@tonic-gate 	}
6217c478bd9Sstevel@tonic-gate     }
622*56a424ccSmp153739 
623*56a424ccSmp153739     code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
624*56a424ccSmp153739     if (code) {
6257c478bd9Sstevel@tonic-gate 	com_err(progname, code, gettext("when unparsing name"));
6267c478bd9Sstevel@tonic-gate 	return 0;
6277c478bd9Sstevel@tonic-gate     }
6287c478bd9Sstevel@tonic-gate     opts->principal_name = k5->name;
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6317c478bd9Sstevel@tonic-gate     if (got_k4)
6327c478bd9Sstevel@tonic-gate     {
6337c478bd9Sstevel@tonic-gate 	/* Translate to a Kerberos 4 principal */
6347c478bd9Sstevel@tonic-gate 	code = krb5_524_conv_principal(k5->ctx, k5->me,
6357c478bd9Sstevel@tonic-gate 				       k4->aname, k4->inst, k4->realm);
6367c478bd9Sstevel@tonic-gate 	if (code) {
6377c478bd9Sstevel@tonic-gate 	    k4->aname[0] = 0;
6387c478bd9Sstevel@tonic-gate 	    k4->inst[0] = 0;
6397c478bd9Sstevel@tonic-gate 	    k4->realm[0] = 0;
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate     }
6427c478bd9Sstevel@tonic-gate #endif
6437c478bd9Sstevel@tonic-gate     return 1;
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate 
646*56a424ccSmp153739 static void
6477c478bd9Sstevel@tonic-gate k5_end(k5)
6487c478bd9Sstevel@tonic-gate     struct k5_data* k5;
6497c478bd9Sstevel@tonic-gate {
6507c478bd9Sstevel@tonic-gate     if (k5->name)
6517c478bd9Sstevel@tonic-gate 	krb5_free_unparsed_name(k5->ctx, k5->name);
6527c478bd9Sstevel@tonic-gate     if (k5->me)
6537c478bd9Sstevel@tonic-gate 	krb5_free_principal(k5->ctx, k5->me);
6547c478bd9Sstevel@tonic-gate     if (k5->cc)
6557c478bd9Sstevel@tonic-gate 	krb5_cc_close(k5->ctx, k5->cc);
6567c478bd9Sstevel@tonic-gate     if (k5->ctx)
6577c478bd9Sstevel@tonic-gate 	krb5_free_context(k5->ctx);
6587c478bd9Sstevel@tonic-gate     memset(k5, 0, sizeof(*k5));
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate 
661*56a424ccSmp153739 static int
6627c478bd9Sstevel@tonic-gate k4_begin(opts, k4)
6637c478bd9Sstevel@tonic-gate     struct k_opts* opts;
6647c478bd9Sstevel@tonic-gate     struct k4_data* k4;
6657c478bd9Sstevel@tonic-gate {
6667c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6677c478bd9Sstevel@tonic-gate     char* progname = progname_v4;
6687c478bd9Sstevel@tonic-gate     int k_errno = 0;
6697c478bd9Sstevel@tonic-gate #endif
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate     if (!got_k4)
6727c478bd9Sstevel@tonic-gate 	return 0;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
6757c478bd9Sstevel@tonic-gate     if (k4->aname[0])
6767c478bd9Sstevel@tonic-gate 	goto skip;
6777c478bd9Sstevel@tonic-gate 
6787c478bd9Sstevel@tonic-gate     if (opts->principal_name)
6797c478bd9Sstevel@tonic-gate     {
6807c478bd9Sstevel@tonic-gate 	/* Use specified name */
681*56a424ccSmp153739         k_errno = kname_parse(k4->aname, k4->inst, k4->realm,
682*56a424ccSmp153739 			      opts->principal_name);
683*56a424ccSmp153739 	if (k_errno)
6847c478bd9Sstevel@tonic-gate 	{
6857c478bd9Sstevel@tonic-gate 	    fprintf(stderr, "%s: %s\n", progname,
6867c478bd9Sstevel@tonic-gate 		    krb_get_err_text(k_errno));
6877c478bd9Sstevel@tonic-gate 	    return 0;
6887c478bd9Sstevel@tonic-gate 	}
6897c478bd9Sstevel@tonic-gate     } else {
6907c478bd9Sstevel@tonic-gate 	/* No principal name specified */
6917c478bd9Sstevel@tonic-gate 	if (opts->action == INIT_KT) {
6927c478bd9Sstevel@tonic-gate 	    /* Use the default host/service name */
6937c478bd9Sstevel@tonic-gate 	    /* XXX - need to add this functionality */
6947c478bd9Sstevel@tonic-gate 	    fprintf(stderr, "%s: Kerberos 4 srvtab support is not "
6957c478bd9Sstevel@tonic-gate 		    "implemented\n", progname);
6967c478bd9Sstevel@tonic-gate 	    return 0;
6977c478bd9Sstevel@tonic-gate 	} else {
6987c478bd9Sstevel@tonic-gate 	    /* Get default principal from cache if one exists */
699*56a424ccSmp153739 	    k_errno = krb_get_tf_fullname(tkt_string(), k4->aname,
700*56a424ccSmp153739 					  k4->inst, k4->realm);
701*56a424ccSmp153739 	    if (k_errno)
7027c478bd9Sstevel@tonic-gate 	    {
7037c478bd9Sstevel@tonic-gate 		char *name = get_name_from_os();
7047c478bd9Sstevel@tonic-gate 		if (!name)
7057c478bd9Sstevel@tonic-gate 		{
7067c478bd9Sstevel@tonic-gate 		    fprintf(stderr, "Unable to identify user\n");
7077c478bd9Sstevel@tonic-gate 		    return 0;
7087c478bd9Sstevel@tonic-gate 		}
709*56a424ccSmp153739 		k_errno = kname_parse(k4->aname, k4->inst, k4->realm,
710*56a424ccSmp153739 				      name);
711*56a424ccSmp153739 		if (k_errno)
7127c478bd9Sstevel@tonic-gate 		{
7137c478bd9Sstevel@tonic-gate 		    fprintf(stderr, "%s: %s\n", progname,
7147c478bd9Sstevel@tonic-gate 			    krb_get_err_text(k_errno));
7157c478bd9Sstevel@tonic-gate 		    return 0;
7167c478bd9Sstevel@tonic-gate 		}
7177c478bd9Sstevel@tonic-gate 	    }
7187c478bd9Sstevel@tonic-gate 	}
7197c478bd9Sstevel@tonic-gate     }
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate     if (!k4->realm[0])
7227c478bd9Sstevel@tonic-gate 	krb_get_lrealm(k4->realm, 1);
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate     if (k4->inst[0])
7257c478bd9Sstevel@tonic-gate 	sprintf(k4->name, "%s.%s@%s", k4->aname, k4->inst, k4->realm);
7267c478bd9Sstevel@tonic-gate     else
7277c478bd9Sstevel@tonic-gate 	sprintf(k4->name, "%s@%s", k4->aname, k4->realm);
7287c478bd9Sstevel@tonic-gate     opts->principal_name = k4->name;
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate  skip:
7317c478bd9Sstevel@tonic-gate     if (k4->aname[0] && !k_isname(k4->aname))
7327c478bd9Sstevel@tonic-gate     {
7337c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: bad Kerberos 4 name format\n", progname);
7347c478bd9Sstevel@tonic-gate 	return 0;
7357c478bd9Sstevel@tonic-gate     }
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate     if (k4->inst[0] && !k_isinst(k4->inst))
7387c478bd9Sstevel@tonic-gate     {
7397c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: bad Kerberos 4 instance format\n", progname);
7407c478bd9Sstevel@tonic-gate 	return 0;
7417c478bd9Sstevel@tonic-gate     }
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate     if (k4->realm[0] && !k_isrealm(k4->realm))
7447c478bd9Sstevel@tonic-gate     {
7457c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: bad Kerberos 4 realm format\n", progname);
7467c478bd9Sstevel@tonic-gate 	return 0;
7477c478bd9Sstevel@tonic-gate     }
7487c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
7497c478bd9Sstevel@tonic-gate     return 1;
7507c478bd9Sstevel@tonic-gate }
7517c478bd9Sstevel@tonic-gate 
752*56a424ccSmp153739 static void
7537c478bd9Sstevel@tonic-gate k4_end(k4)
7547c478bd9Sstevel@tonic-gate     struct k4_data* k4;
7557c478bd9Sstevel@tonic-gate {
7567c478bd9Sstevel@tonic-gate     memset(k4, 0, sizeof(*k4));
7577c478bd9Sstevel@tonic-gate }
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
7607c478bd9Sstevel@tonic-gate static char stash_password[1024];
7617c478bd9Sstevel@tonic-gate static int got_password = 0;
7627c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */
7637c478bd9Sstevel@tonic-gate 
764*56a424ccSmp153739 static krb5_error_code
7657c478bd9Sstevel@tonic-gate KRB5_CALLCONV
7667c478bd9Sstevel@tonic-gate kinit_prompter(
7677c478bd9Sstevel@tonic-gate     krb5_context ctx,
7687c478bd9Sstevel@tonic-gate     void *data,
7697c478bd9Sstevel@tonic-gate     const char *name,
7707c478bd9Sstevel@tonic-gate     const char *banner,
7717c478bd9Sstevel@tonic-gate     int num_prompts,
7727c478bd9Sstevel@tonic-gate     krb5_prompt prompts[]
7737c478bd9Sstevel@tonic-gate     )
7747c478bd9Sstevel@tonic-gate {
7757c478bd9Sstevel@tonic-gate     int i;
7767c478bd9Sstevel@tonic-gate     krb5_prompt_type *types;
7777c478bd9Sstevel@tonic-gate     krb5_error_code rc =
7787c478bd9Sstevel@tonic-gate 	krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts);
7797c478bd9Sstevel@tonic-gate     if (!rc && (types = krb5_get_prompt_types(ctx)))
7807c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_prompts; i++)
7817c478bd9Sstevel@tonic-gate 	    if ((types[i] == KRB5_PROMPT_TYPE_PASSWORD) ||
7827c478bd9Sstevel@tonic-gate 		(types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN))
7837c478bd9Sstevel@tonic-gate 	    {
7847c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
7857c478bd9Sstevel@tonic-gate 		strncpy(stash_password, prompts[i].reply->data,
7867c478bd9Sstevel@tonic-gate 			sizeof(stash_password));
7877c478bd9Sstevel@tonic-gate 		got_password = 1;
7887c478bd9Sstevel@tonic-gate #endif
7897c478bd9Sstevel@tonic-gate 	    }
7907c478bd9Sstevel@tonic-gate     return rc;
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate 
793*56a424ccSmp153739 static int
7947c478bd9Sstevel@tonic-gate k5_kinit(opts, k5)
7957c478bd9Sstevel@tonic-gate     struct k_opts* opts;
7967c478bd9Sstevel@tonic-gate     struct k5_data* k5;
7977c478bd9Sstevel@tonic-gate {
7987c478bd9Sstevel@tonic-gate     char* progname = progname_v5;
7997c478bd9Sstevel@tonic-gate     int notix = 1;
8007c478bd9Sstevel@tonic-gate     krb5_keytab keytab = 0;
8017c478bd9Sstevel@tonic-gate     krb5_creds my_creds;
8027c478bd9Sstevel@tonic-gate     krb5_error_code code = 0;
8037c478bd9Sstevel@tonic-gate     krb5_get_init_creds_opt options;
8047c478bd9Sstevel@tonic-gate     krb5_timestamp now;
8057c478bd9Sstevel@tonic-gate     krb5_deltat lifetime = 0, rlife = 0, krb5_max_duration;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate     if (!got_k5)
8087c478bd9Sstevel@tonic-gate 	return 0;
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate     krb5_get_init_creds_opt_init(&options);
8117c478bd9Sstevel@tonic-gate     memset(&my_creds, 0, sizeof(my_creds));
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate     /*
8147c478bd9Sstevel@tonic-gate      * Solaris Kerberos: added support for max_life and max_renewable_life
8157c478bd9Sstevel@tonic-gate      * which should be removed in the next minor release.  See PSARC 2003/545
8167c478bd9Sstevel@tonic-gate      * for more info.
8177c478bd9Sstevel@tonic-gate      *
8187c478bd9Sstevel@tonic-gate      * Also, check krb5.conf for proxiable/forwardable/renewable/no_address
8197c478bd9Sstevel@tonic-gate      * parameter values.
8207c478bd9Sstevel@tonic-gate      */
8217c478bd9Sstevel@tonic-gate     /* If either tkt life or renew life weren't set earlier take common steps to
8227c478bd9Sstevel@tonic-gate      * get the krb5.conf parameter values.
8237c478bd9Sstevel@tonic-gate      */
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate     if ((code = krb5_timeofday(k5->ctx, &now))) {
8267c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("while getting time of day"));
8277c478bd9Sstevel@tonic-gate 	    exit(1);
8287c478bd9Sstevel@tonic-gate     }
8297c478bd9Sstevel@tonic-gate     krb5_max_duration = KRB5_KDB_EXPIRATION - now - 60*60;
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate     if (opts->lifetime == 0 || opts->rlife == 0) {
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	krb_realm = krb5_princ_realm(k5->ctx, k5->me)->data;
8347c478bd9Sstevel@tonic-gate 	/* realm params take precedence */
8357c478bd9Sstevel@tonic-gate 	profile_get_options_string(k5->ctx->profile, realmdef, config_times);
8367c478bd9Sstevel@tonic-gate 	profile_get_options_string(k5->ctx->profile, appdef, config_times);
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	/* if the input opts doesn't have lifetime set and the krb5.conf
8397c478bd9Sstevel@tonic-gate 	 * parameter has been set, use that.
8407c478bd9Sstevel@tonic-gate 	 */
8417c478bd9Sstevel@tonic-gate 	if (opts->lifetime == 0 && life_timeval != NULL) {
8427c478bd9Sstevel@tonic-gate 	    code = krb5_string_to_deltat(life_timeval, &lifetime);
8437c478bd9Sstevel@tonic-gate 	    if (code != 0 || lifetime == 0 || lifetime > krb5_max_duration) {
8447c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Bad max_life "
8457c478bd9Sstevel@tonic-gate 			    "value in Kerberos config file %s\n"),
8467c478bd9Sstevel@tonic-gate 			life_timeval);
8477c478bd9Sstevel@tonic-gate 		exit(1);
8487c478bd9Sstevel@tonic-gate 	    }
8497c478bd9Sstevel@tonic-gate 	    opts->lifetime = lifetime;
8507c478bd9Sstevel@tonic-gate 	}
8517c478bd9Sstevel@tonic-gate 	if (opts->rlife == 0 && renew_timeval != NULL) {
8527c478bd9Sstevel@tonic-gate 	    code = krb5_string_to_deltat(renew_timeval, &rlife);
8537c478bd9Sstevel@tonic-gate 	    if (code != 0 || rlife == 0 || rlife > krb5_max_duration) {
8547c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Bad max_renewable_life "
8557c478bd9Sstevel@tonic-gate 			    "value in Kerberos config file %s\n"),
8567c478bd9Sstevel@tonic-gate 			renew_timeval);
8577c478bd9Sstevel@tonic-gate 		exit(1);
8587c478bd9Sstevel@tonic-gate 	    }
8597c478bd9Sstevel@tonic-gate 	    opts->rlife = rlife;
8607c478bd9Sstevel@tonic-gate 	}
8617c478bd9Sstevel@tonic-gate     }
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate     /*
8647c478bd9Sstevel@tonic-gate      * If lifetime is not set on the cmdline or in the krb5.conf
8657c478bd9Sstevel@tonic-gate      * file, default to max.
8667c478bd9Sstevel@tonic-gate      */
8677c478bd9Sstevel@tonic-gate     if (opts->lifetime == 0)
8687c478bd9Sstevel@tonic-gate 	    opts->lifetime = krb5_max_duration;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate     profile_get_options_boolean(k5->ctx->profile,
8727c478bd9Sstevel@tonic-gate 				realmdef, config_option);
8737c478bd9Sstevel@tonic-gate     profile_get_options_boolean(k5->ctx->profile,
8747c478bd9Sstevel@tonic-gate 				appdef, config_option);
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate     /* cmdline opts take precedence over krb5.conf file values */
8787c478bd9Sstevel@tonic-gate     if (!opts->not_proxiable && proxiable_flag) {
8797c478bd9Sstevel@tonic-gate 	    krb5_get_init_creds_opt_set_proxiable(&options, 1);
8807c478bd9Sstevel@tonic-gate     }
8817c478bd9Sstevel@tonic-gate     if (!opts->not_forwardable && forwardable_flag) {
8827c478bd9Sstevel@tonic-gate 	    krb5_get_init_creds_opt_set_forwardable(&options, 1);
8837c478bd9Sstevel@tonic-gate     }
8847c478bd9Sstevel@tonic-gate     if (renewable_flag) {
8857c478bd9Sstevel@tonic-gate 	    /*
8867c478bd9Sstevel@tonic-gate 	     * If this flag is set in krb5.conf, but rlife is 0, then
8877c478bd9Sstevel@tonic-gate 	     * set it to the max (and let the KDC sort it out).
8887c478bd9Sstevel@tonic-gate 	     */
8897c478bd9Sstevel@tonic-gate 	    opts->rlife = opts->rlife ? opts->rlife : krb5_max_duration;
8907c478bd9Sstevel@tonic-gate     }
8917c478bd9Sstevel@tonic-gate     if (no_address_flag) {
8927c478bd9Sstevel@tonic-gate 	    /* cmdline opts will overwrite this below if needbe */
8937c478bd9Sstevel@tonic-gate 	    krb5_get_init_creds_opt_set_address_list(&options, NULL);
8947c478bd9Sstevel@tonic-gate     }
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate     /*
8987c478bd9Sstevel@tonic-gate       From this point on, we can goto cleanup because my_creds is
8997c478bd9Sstevel@tonic-gate       initialized.
9007c478bd9Sstevel@tonic-gate     */
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate     if (opts->lifetime)
9037c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
9047c478bd9Sstevel@tonic-gate     if (opts->rlife)
9057c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife);
9067c478bd9Sstevel@tonic-gate     if (opts->forwardable)
9077c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_forwardable(&options, 1);
9087c478bd9Sstevel@tonic-gate     if (opts->not_forwardable)
9097c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_forwardable(&options, 0);
9107c478bd9Sstevel@tonic-gate     if (opts->proxiable)
9117c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_proxiable(&options, 1);
9127c478bd9Sstevel@tonic-gate     if (opts->not_proxiable)
9137c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_proxiable(&options, 0);
9147c478bd9Sstevel@tonic-gate     if (opts->addresses)
9157c478bd9Sstevel@tonic-gate     {
9167c478bd9Sstevel@tonic-gate 	krb5_address **addresses = NULL;
9177c478bd9Sstevel@tonic-gate 	code = krb5_os_localaddr(k5->ctx, &addresses);
9187c478bd9Sstevel@tonic-gate 	if (code != 0) {
9197c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("getting local addresses"));
9207c478bd9Sstevel@tonic-gate 	    goto cleanup;
9217c478bd9Sstevel@tonic-gate 	}
9227c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_address_list(&options, addresses);
9237c478bd9Sstevel@tonic-gate     }
9247c478bd9Sstevel@tonic-gate     if (opts->no_addresses)
9257c478bd9Sstevel@tonic-gate 	krb5_get_init_creds_opt_set_address_list(&options, NULL);
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate     if ((opts->action == INIT_KT) && opts->keytab_name)
9287c478bd9Sstevel@tonic-gate     {
9297c478bd9Sstevel@tonic-gate 	code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
9307c478bd9Sstevel@tonic-gate 	if (code != 0) {
9317c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("resolving keytab %s"),
9327c478bd9Sstevel@tonic-gate 		    opts->keytab_name);
9337c478bd9Sstevel@tonic-gate 	    goto cleanup;
9347c478bd9Sstevel@tonic-gate 	}
9357c478bd9Sstevel@tonic-gate     }
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate     switch (opts->action) {
9387c478bd9Sstevel@tonic-gate     case INIT_PW:
9397c478bd9Sstevel@tonic-gate 	code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
9407c478bd9Sstevel@tonic-gate 					    0, kinit_prompter, 0,
9417c478bd9Sstevel@tonic-gate 					    opts->starttime,
9427c478bd9Sstevel@tonic-gate 					    opts->service_name,
9437c478bd9Sstevel@tonic-gate 					    &options);
9447c478bd9Sstevel@tonic-gate 	break;
9457c478bd9Sstevel@tonic-gate     case INIT_KT:
9467c478bd9Sstevel@tonic-gate 	code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
9477c478bd9Sstevel@tonic-gate 					  keytab,
9487c478bd9Sstevel@tonic-gate 					  opts->starttime,
9497c478bd9Sstevel@tonic-gate 					  opts->service_name,
9507c478bd9Sstevel@tonic-gate 					  &options);
9517c478bd9Sstevel@tonic-gate 	break;
9527c478bd9Sstevel@tonic-gate     case VALIDATE:
9537c478bd9Sstevel@tonic-gate 	code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc,
9547c478bd9Sstevel@tonic-gate 					opts->service_name);
9557c478bd9Sstevel@tonic-gate 	break;
9567c478bd9Sstevel@tonic-gate     case RENEW:
9577c478bd9Sstevel@tonic-gate 	code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc,
9587c478bd9Sstevel@tonic-gate 				      opts->service_name);
9597c478bd9Sstevel@tonic-gate 	break;
9607c478bd9Sstevel@tonic-gate     }
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate     if (code) {
9637c478bd9Sstevel@tonic-gate 	char *doing = 0;
9647c478bd9Sstevel@tonic-gate 	switch (opts->action) {
9657c478bd9Sstevel@tonic-gate 	case INIT_PW:
9667c478bd9Sstevel@tonic-gate 	case INIT_KT:
9677c478bd9Sstevel@tonic-gate 	    doing = gettext("getting initial credentials");
9687c478bd9Sstevel@tonic-gate 	    break;
9697c478bd9Sstevel@tonic-gate 	case VALIDATE:
9707c478bd9Sstevel@tonic-gate 	    doing = gettext("validating credentials");
9717c478bd9Sstevel@tonic-gate 	    break;
9727c478bd9Sstevel@tonic-gate 	case RENEW:
9737c478bd9Sstevel@tonic-gate 	    doing = gettext("renewing credentials");
9747c478bd9Sstevel@tonic-gate 	    break;
9757c478bd9Sstevel@tonic-gate 	}
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	/* If got code == KRB5_AP_ERR_V4_REPLY && got_k4, we should
9787c478bd9Sstevel@tonic-gate 	   let the user know that maybe he/she wants -4. */
9797c478bd9Sstevel@tonic-gate 	if (code == KRB5KRB_AP_ERR_V4_REPLY && got_k4)
9807c478bd9Sstevel@tonic-gate 	    com_err(progname, code, "while %s\n"
9817c478bd9Sstevel@tonic-gate 		    "The KDC doesn't support v5.  "
9827c478bd9Sstevel@tonic-gate 		    "You may want the -4 option in the future",
9837c478bd9Sstevel@tonic-gate 		    doing);
9847c478bd9Sstevel@tonic-gate 	else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
9857c478bd9Sstevel@tonic-gate 	    fprintf(stderr, gettext("%s: Password incorrect while %s\n"), progname,
9867c478bd9Sstevel@tonic-gate 		    doing);
9877c478bd9Sstevel@tonic-gate 	else
9887c478bd9Sstevel@tonic-gate 	    com_err(progname, code, gettext("while %s"), doing);
9897c478bd9Sstevel@tonic-gate 	goto cleanup;
9907c478bd9Sstevel@tonic-gate     }
9917c478bd9Sstevel@tonic-gate 
9927c478bd9Sstevel@tonic-gate     if (!opts->lifetime) {
9937c478bd9Sstevel@tonic-gate 	/* We need to figure out what lifetime to use for Kerberos 4. */
9947c478bd9Sstevel@tonic-gate 	opts->lifetime = my_creds.times.endtime - my_creds.times.authtime;
9957c478bd9Sstevel@tonic-gate     }
9967c478bd9Sstevel@tonic-gate 
997*56a424ccSmp153739     code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me);
998*56a424ccSmp153739     if (code) {
9997c478bd9Sstevel@tonic-gate 	com_err(progname, code, gettext("when initializing cache %s"),
10007c478bd9Sstevel@tonic-gate 		opts->k5_cache_name?opts->k5_cache_name:"");
10017c478bd9Sstevel@tonic-gate 	goto cleanup;
10027c478bd9Sstevel@tonic-gate     }
10037c478bd9Sstevel@tonic-gate 
1004*56a424ccSmp153739     code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);
1005*56a424ccSmp153739     if (code) {
10067c478bd9Sstevel@tonic-gate 	com_err(progname, code, gettext("while storing credentials"));
10077c478bd9Sstevel@tonic-gate 	goto cleanup;
10087c478bd9Sstevel@tonic-gate     }
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate     if (opts->action == RENEW) {
10117c478bd9Sstevel@tonic-gate         _kwarnd_del_warning(opts->principal_name);
10127c478bd9Sstevel@tonic-gate         _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime);
10137c478bd9Sstevel@tonic-gate     } else if ((opts->action == INIT_KT) || (opts->action == INIT_PW)) {
10147c478bd9Sstevel@tonic-gate         _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime);
10157c478bd9Sstevel@tonic-gate     }
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate     notix = 0;
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate  cleanup:
10207c478bd9Sstevel@tonic-gate     if (my_creds.client == k5->me) {
10217c478bd9Sstevel@tonic-gate 	my_creds.client = 0;
10227c478bd9Sstevel@tonic-gate     }
10237c478bd9Sstevel@tonic-gate     krb5_free_cred_contents(k5->ctx, &my_creds);
10247c478bd9Sstevel@tonic-gate     if (keytab)
10257c478bd9Sstevel@tonic-gate 	krb5_kt_close(k5->ctx, keytab);
10267c478bd9Sstevel@tonic-gate     return notix?0:1;
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate 
1029*56a424ccSmp153739 static int
10307c478bd9Sstevel@tonic-gate k4_kinit(opts, k4, ctx)
10317c478bd9Sstevel@tonic-gate     struct k_opts* opts;
10327c478bd9Sstevel@tonic-gate     struct k4_data* k4;
10337c478bd9Sstevel@tonic-gate     krb5_context ctx;
10347c478bd9Sstevel@tonic-gate {
10357c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
10367c478bd9Sstevel@tonic-gate     char* progname = progname_v4;
10377c478bd9Sstevel@tonic-gate     int k_errno = 0;
10387c478bd9Sstevel@tonic-gate #endif
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate     if (!got_k4)
10417c478bd9Sstevel@tonic-gate 	return 0;
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate     if (opts->starttime)
10447c478bd9Sstevel@tonic-gate 	return 0;
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
10477c478bd9Sstevel@tonic-gate     if (!k4->lifetime)
10487c478bd9Sstevel@tonic-gate 	k4->lifetime = opts->lifetime;
10497c478bd9Sstevel@tonic-gate     if (!k4->lifetime)
10507c478bd9Sstevel@tonic-gate 	k4->lifetime = KRB4_BACKUP_DEFAULT_LIFE_SECS;
10517c478bd9Sstevel@tonic-gate 
1052*56a424ccSmp153739     k4->lifetime = krb_time_to_life(0, k4->lifetime);
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate     switch (opts->action)
10557c478bd9Sstevel@tonic-gate     {
10567c478bd9Sstevel@tonic-gate     case INIT_PW:
10577c478bd9Sstevel@tonic-gate 	if (!got_password) {
1058*56a424ccSmp153739 	    unsigned int pwsize = sizeof(stash_password);
10597c478bd9Sstevel@tonic-gate 	    krb5_error_code code;
10607c478bd9Sstevel@tonic-gate 	    char prompt[1024];
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 	    sprintf(prompt, gettext("Password for %s: "), opts->principal_name);
10637c478bd9Sstevel@tonic-gate 	    stash_password[0] = 0;
10647c478bd9Sstevel@tonic-gate 	    /*
10657c478bd9Sstevel@tonic-gate 	      Note: krb5_read_password does not actually look at the
10667c478bd9Sstevel@tonic-gate 	      context, so we're ok even if we don't have a context.  If
10677c478bd9Sstevel@tonic-gate 	      we cannot dynamically load krb5, we can substitute any
10687c478bd9Sstevel@tonic-gate 	      decent read password function instead of the krb5 one.
10697c478bd9Sstevel@tonic-gate 	    */
10707c478bd9Sstevel@tonic-gate 	    code = krb5_read_password(ctx, prompt, 0, stash_password, &pwsize);
10717c478bd9Sstevel@tonic-gate 	    if (code || pwsize == 0)
10727c478bd9Sstevel@tonic-gate 	    {
10737c478bd9Sstevel@tonic-gate 		fprintf(stderr, gettext("Error while reading password for '%s'\n"),
10747c478bd9Sstevel@tonic-gate 			opts->principal_name);
10757c478bd9Sstevel@tonic-gate 		memset(stash_password, 0, sizeof(stash_password));
10767c478bd9Sstevel@tonic-gate 		return 0;
10777c478bd9Sstevel@tonic-gate 	    }
10787c478bd9Sstevel@tonic-gate 	    got_password = 1;
10797c478bd9Sstevel@tonic-gate 	}
10807c478bd9Sstevel@tonic-gate 	k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt",
10817c478bd9Sstevel@tonic-gate 				    k4->realm, k4->lifetime, stash_password);
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	if (k_errno) {
10847c478bd9Sstevel@tonic-gate 	    fprintf(stderr, "%s: %s\n", progname,
10857c478bd9Sstevel@tonic-gate 		    krb_get_err_text(k_errno));
10867c478bd9Sstevel@tonic-gate 	    if (authed_k5)
10877c478bd9Sstevel@tonic-gate 	        fprintf(stderr, gettext("Maybe your KDC does not support v4.  "
10887c478bd9Sstevel@tonic-gate 			"Try the -5 option next time.\n"));
10897c478bd9Sstevel@tonic-gate 	    return 0;
10907c478bd9Sstevel@tonic-gate 	}
10917c478bd9Sstevel@tonic-gate 	return 1;
10927c478bd9Sstevel@tonic-gate #ifndef HAVE_KRB524
10937c478bd9Sstevel@tonic-gate     case INIT_KT:
10947c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: srvtabs are not supported\n"), progname);
10957c478bd9Sstevel@tonic-gate 	return 0;
10967c478bd9Sstevel@tonic-gate     case RENEW:
10977c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("%s: renewal of krb4 tickets is not supported\n"),
10987c478bd9Sstevel@tonic-gate 		progname);
10997c478bd9Sstevel@tonic-gate 	return 0;
1100*56a424ccSmp153739 #else
1101*56a424ccSmp153739     /* These cases are handled by the 524 code - this prevents the compiler
1102*56a424ccSmp153739        warnings of not using all the enumerated types.
1103*56a424ccSmp153739     */
1104*56a424ccSmp153739     case INIT_KT:
1105*56a424ccSmp153739     case RENEW:
1106*56a424ccSmp153739     case VALIDATE:
1107*56a424ccSmp153739         return 0;
11087c478bd9Sstevel@tonic-gate #endif
11097c478bd9Sstevel@tonic-gate     }
11107c478bd9Sstevel@tonic-gate #endif
11117c478bd9Sstevel@tonic-gate     return 0;
11127c478bd9Sstevel@tonic-gate }
11137c478bd9Sstevel@tonic-gate 
1114*56a424ccSmp153739 static char*
1115*56a424ccSmp153739 getvprogname(v, progname)
1116*56a424ccSmp153739     char *v, *progname;
11177c478bd9Sstevel@tonic-gate {
1118*56a424ccSmp153739     unsigned int len = strlen(progname) + 2 + strlen(v) + 2;
11197c478bd9Sstevel@tonic-gate     char *ret = malloc(len);
11207c478bd9Sstevel@tonic-gate     if (ret)
11217c478bd9Sstevel@tonic-gate 	sprintf(ret, "%s(v%s)", progname, v);
11227c478bd9Sstevel@tonic-gate     else
11237c478bd9Sstevel@tonic-gate 	ret = progname;
11247c478bd9Sstevel@tonic-gate     return ret;
11257c478bd9Sstevel@tonic-gate }
11267c478bd9Sstevel@tonic-gate 
11277c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
11287c478bd9Sstevel@tonic-gate /* Convert krb5 tickets to krb4. */
1129*56a424ccSmp153739 static int try_convert524(k5)
11307c478bd9Sstevel@tonic-gate     struct k5_data* k5;
11317c478bd9Sstevel@tonic-gate {
11327c478bd9Sstevel@tonic-gate     char * progname = progname_v524;
11337c478bd9Sstevel@tonic-gate     krb5_error_code code = 0;
11347c478bd9Sstevel@tonic-gate     int icode = 0;
11357c478bd9Sstevel@tonic-gate     krb5_principal kpcserver = 0;
11367c478bd9Sstevel@tonic-gate     krb5_creds *v5creds = 0;
11377c478bd9Sstevel@tonic-gate     krb5_creds increds;
11387c478bd9Sstevel@tonic-gate     CREDENTIALS v4creds;
11397c478bd9Sstevel@tonic-gate 
11407c478bd9Sstevel@tonic-gate     if (!got_k4 || !got_k5)
11417c478bd9Sstevel@tonic-gate 	return 0;
11427c478bd9Sstevel@tonic-gate 
11437c478bd9Sstevel@tonic-gate     memset((char *) &increds, 0, sizeof(increds));
11447c478bd9Sstevel@tonic-gate     /*
11457c478bd9Sstevel@tonic-gate       From this point on, we can goto cleanup because increds is
11467c478bd9Sstevel@tonic-gate       initialized.
11477c478bd9Sstevel@tonic-gate     */
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate     if ((code = krb5_build_principal(k5->ctx,
11507c478bd9Sstevel@tonic-gate 				     &kpcserver,
11517c478bd9Sstevel@tonic-gate 				     krb5_princ_realm(k5->ctx, k5->me)->length,
11527c478bd9Sstevel@tonic-gate 				     krb5_princ_realm(k5->ctx, k5->me)->data,
11537c478bd9Sstevel@tonic-gate 				     "krbtgt",
11547c478bd9Sstevel@tonic-gate 				     krb5_princ_realm(k5->ctx, k5->me)->data,
11557c478bd9Sstevel@tonic-gate 				     NULL))) {
11567c478bd9Sstevel@tonic-gate 	com_err(progname, code, gettext(
11577c478bd9Sstevel@tonic-gate 		"while creating service principal name"));
11587c478bd9Sstevel@tonic-gate 	goto cleanup;
11597c478bd9Sstevel@tonic-gate     }
11607c478bd9Sstevel@tonic-gate 
11617c478bd9Sstevel@tonic-gate     increds.client = k5->me;
11627c478bd9Sstevel@tonic-gate     increds.server = kpcserver;
11637c478bd9Sstevel@tonic-gate     /* Prevent duplicate free calls.  */
11647c478bd9Sstevel@tonic-gate     kpcserver = 0;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate     increds.times.endtime = 0;
11677c478bd9Sstevel@tonic-gate     increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
11687c478bd9Sstevel@tonic-gate     if ((code = krb5_get_credentials(k5->ctx, 0,
11697c478bd9Sstevel@tonic-gate 				     k5->cc,
11707c478bd9Sstevel@tonic-gate 				     &increds,
11717c478bd9Sstevel@tonic-gate 				     &v5creds))) {
11727c478bd9Sstevel@tonic-gate 	com_err(progname, code,
11737c478bd9Sstevel@tonic-gate 		gettext("getting V5 credentials"));
11747c478bd9Sstevel@tonic-gate 	goto cleanup;
11757c478bd9Sstevel@tonic-gate     }
11767c478bd9Sstevel@tonic-gate     if ((icode = krb524_convert_creds_kdc(k5->ctx,
11777c478bd9Sstevel@tonic-gate 					  v5creds,
11787c478bd9Sstevel@tonic-gate 					  &v4creds))) {
11797c478bd9Sstevel@tonic-gate 	com_err(progname, icode,
11807c478bd9Sstevel@tonic-gate 		gettext("converting to V4 credentials"));
11817c478bd9Sstevel@tonic-gate 	goto cleanup;
11827c478bd9Sstevel@tonic-gate     }
11837c478bd9Sstevel@tonic-gate     /* this is stolen from the v4 kinit */
11847c478bd9Sstevel@tonic-gate     /* initialize ticket cache */
11857c478bd9Sstevel@tonic-gate     if ((icode = in_tkt(v4creds.pname, v4creds.pinst)
11867c478bd9Sstevel@tonic-gate 	 != KSUCCESS)) {
11877c478bd9Sstevel@tonic-gate 	com_err(progname, icode, gettext(
11887c478bd9Sstevel@tonic-gate 		"trying to create the V4 ticket file"));
11897c478bd9Sstevel@tonic-gate 	goto cleanup;
11907c478bd9Sstevel@tonic-gate     }
11917c478bd9Sstevel@tonic-gate     /* stash ticket, session key, etc. for future use */
11927c478bd9Sstevel@tonic-gate     if ((icode = krb_save_credentials(v4creds.service,
11937c478bd9Sstevel@tonic-gate 				      v4creds.instance,
11947c478bd9Sstevel@tonic-gate 				      v4creds.realm,
11957c478bd9Sstevel@tonic-gate 				      v4creds.session,
11967c478bd9Sstevel@tonic-gate 				      v4creds.lifetime,
11977c478bd9Sstevel@tonic-gate 				      v4creds.kvno,
11987c478bd9Sstevel@tonic-gate 				      &(v4creds.ticket_st),
11997c478bd9Sstevel@tonic-gate 				      v4creds.issue_date))) {
12007c478bd9Sstevel@tonic-gate 	com_err(progname, icode, gettext(
12017c478bd9Sstevel@tonic-gate 		"trying to save the V4 ticket"));
12027c478bd9Sstevel@tonic-gate 	goto cleanup;
12037c478bd9Sstevel@tonic-gate     }
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate  cleanup:
12067c478bd9Sstevel@tonic-gate     memset(&v4creds, 0, sizeof(v4creds));
12077c478bd9Sstevel@tonic-gate     if (v5creds)
12087c478bd9Sstevel@tonic-gate 	krb5_free_creds(k5->ctx, v5creds);
12097c478bd9Sstevel@tonic-gate     increds.client = 0;
12107c478bd9Sstevel@tonic-gate     krb5_free_cred_contents(k5->ctx, &increds);
12117c478bd9Sstevel@tonic-gate     if (kpcserver)
12127c478bd9Sstevel@tonic-gate 	krb5_free_principal(k5->ctx, kpcserver);
12137c478bd9Sstevel@tonic-gate     return !(code || icode);
12147c478bd9Sstevel@tonic-gate }
12157c478bd9Sstevel@tonic-gate #endif /* HAVE_KRB524 */
12167c478bd9Sstevel@tonic-gate 
12177c478bd9Sstevel@tonic-gate int
12187c478bd9Sstevel@tonic-gate main(argc, argv)
12197c478bd9Sstevel@tonic-gate     int argc;
12207c478bd9Sstevel@tonic-gate     char **argv;
12217c478bd9Sstevel@tonic-gate {
12227c478bd9Sstevel@tonic-gate     struct k_opts opts;
12237c478bd9Sstevel@tonic-gate     struct k5_data k5;
12247c478bd9Sstevel@tonic-gate     struct k4_data k4;
12257c478bd9Sstevel@tonic-gate 
12267c478bd9Sstevel@tonic-gate     (void) setlocale(LC_ALL, "");
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
12297c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"
12307c478bd9Sstevel@tonic-gate #endif
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
12337c478bd9Sstevel@tonic-gate 
12347c478bd9Sstevel@tonic-gate     progname = GET_PROGNAME(argv[0]);
1235*56a424ccSmp153739     progname_v5 = getvprogname("5", progname);
12367c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
1237*56a424ccSmp153739     progname_v4 = getvprogname("4", progname);
1238*56a424ccSmp153739     progname_v524 = getvprogname("524", progname);
12397c478bd9Sstevel@tonic-gate #endif
12407c478bd9Sstevel@tonic-gate 
12417c478bd9Sstevel@tonic-gate     /* Ensure we can be driven from a pipe */
12427c478bd9Sstevel@tonic-gate     if(!isatty(fileno(stdin)))
12437c478bd9Sstevel@tonic-gate 	setvbuf(stdin, 0, _IONBF, 0);
12447c478bd9Sstevel@tonic-gate     if(!isatty(fileno(stdout)))
12457c478bd9Sstevel@tonic-gate 	setvbuf(stdout, 0, _IONBF, 0);
12467c478bd9Sstevel@tonic-gate     if(!isatty(fileno(stderr)))
12477c478bd9Sstevel@tonic-gate 	setvbuf(stderr, 0, _IONBF, 0);
12487c478bd9Sstevel@tonic-gate 
12497c478bd9Sstevel@tonic-gate     /*
12507c478bd9Sstevel@tonic-gate       This is where we would put in code to dynamically load Kerberos
12517c478bd9Sstevel@tonic-gate       libraries.  Currenlty, we just get them implicitly.
12527c478bd9Sstevel@tonic-gate     */
12537c478bd9Sstevel@tonic-gate     got_k5 = 1;
12547c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
12557c478bd9Sstevel@tonic-gate     got_k4 = 1;
12567c478bd9Sstevel@tonic-gate #endif
12577c478bd9Sstevel@tonic-gate 
12587c478bd9Sstevel@tonic-gate     memset(&opts, 0, sizeof(opts));
12597c478bd9Sstevel@tonic-gate     opts.action = INIT_PW;
12607c478bd9Sstevel@tonic-gate 
12617c478bd9Sstevel@tonic-gate     memset(&k5, 0, sizeof(k5));
12627c478bd9Sstevel@tonic-gate     memset(&k4, 0, sizeof(k4));
12637c478bd9Sstevel@tonic-gate 
1264*56a424ccSmp153739     parse_options(argc, argv, &opts, progname);
12657c478bd9Sstevel@tonic-gate 
12667c478bd9Sstevel@tonic-gate     got_k5 = k5_begin(&opts, &k5, &k4);
12677c478bd9Sstevel@tonic-gate     got_k4 = k4_begin(&opts, &k4);
12687c478bd9Sstevel@tonic-gate 
12697c478bd9Sstevel@tonic-gate     authed_k5 = k5_kinit(&opts, &k5);
12707c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524
12717c478bd9Sstevel@tonic-gate     if (authed_k5)
12727c478bd9Sstevel@tonic-gate 	authed_k4 = try_convert524(&k5);
12737c478bd9Sstevel@tonic-gate #endif
12747c478bd9Sstevel@tonic-gate     if (!authed_k4)
12757c478bd9Sstevel@tonic-gate 	authed_k4 = k4_kinit(&opts, &k4, k5.ctx);
12767c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT
12777c478bd9Sstevel@tonic-gate     memset(stash_password, 0, sizeof(stash_password));
12787c478bd9Sstevel@tonic-gate #endif
12797c478bd9Sstevel@tonic-gate 
12807c478bd9Sstevel@tonic-gate     if (authed_k5 && opts.verbose)
12817c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Authenticated to Kerberos v5\n"));
12827c478bd9Sstevel@tonic-gate     if (authed_k4 && opts.verbose)
12837c478bd9Sstevel@tonic-gate 	fprintf(stderr, gettext("Authenticated to Kerberos v4\n"));
12847c478bd9Sstevel@tonic-gate 
12857c478bd9Sstevel@tonic-gate     k5_end(&k5);
12867c478bd9Sstevel@tonic-gate     k4_end(&k4);
12877c478bd9Sstevel@tonic-gate 
1288*56a424ccSmp153739     if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4) ||
1289*56a424ccSmp153739 	(!got_k5 && !got_k4))
12907c478bd9Sstevel@tonic-gate 	exit(1);
12917c478bd9Sstevel@tonic-gate     return 0;
12927c478bd9Sstevel@tonic-gate }
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate static void
12957c478bd9Sstevel@tonic-gate _kwarnd_add_warning(char *me, time_t endtime)
12967c478bd9Sstevel@tonic-gate {
12977c478bd9Sstevel@tonic-gate     if (kwarn_add_warning(me, endtime) != 0)
12987c478bd9Sstevel@tonic-gate         fprintf(stderr, gettext(
12997c478bd9Sstevel@tonic-gate             "%s:  no ktkt_warnd warning possible\n"), progname);
13007c478bd9Sstevel@tonic-gate     return;
13017c478bd9Sstevel@tonic-gate }
13027c478bd9Sstevel@tonic-gate 
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate static void
13057c478bd9Sstevel@tonic-gate _kwarnd_del_warning(char *me)
13067c478bd9Sstevel@tonic-gate {
13077c478bd9Sstevel@tonic-gate     if (kwarn_del_warning(me) != 0)
13087c478bd9Sstevel@tonic-gate         fprintf(stderr, gettext(
13097c478bd9Sstevel@tonic-gate             "%s:  unable to delete ktkt_warnd message for %s\n"),
13107c478bd9Sstevel@tonic-gate             progname, me);
13117c478bd9Sstevel@tonic-gate     return;
13127c478bd9Sstevel@tonic-gate }
1313