1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*7c478bd9Sstevel@tonic-gate 8*7c478bd9Sstevel@tonic-gate /* 9*7c478bd9Sstevel@tonic-gate * clients/kinit/kinit.c 10*7c478bd9Sstevel@tonic-gate * 11*7c478bd9Sstevel@tonic-gate * Copyright 1990 by the Massachusetts Institute of Technology. 12*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 15*7c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 16*7c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 17*7c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 18*7c478bd9Sstevel@tonic-gate * 19*7c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20*7c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 21*7c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 22*7c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 23*7c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 24*7c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 25*7c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 26*7c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 27*7c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 28*7c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 29*7c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 30*7c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 31*7c478bd9Sstevel@tonic-gate * or implied warranty. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate * 34*7c478bd9Sstevel@tonic-gate * Initialize a credentials cache. 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate #include <k5-int.h> 37*7c478bd9Sstevel@tonic-gate #include <profile/prof_int.h> 38*7c478bd9Sstevel@tonic-gate #include <com_err.h> 39*7c478bd9Sstevel@tonic-gate #include <libintl.h> 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #include <krb5.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 44*7c478bd9Sstevel@tonic-gate #include <kerberosIV/krb.h> 45*7c478bd9Sstevel@tonic-gate #define HAVE_KRB524 46*7c478bd9Sstevel@tonic-gate #else 47*7c478bd9Sstevel@tonic-gate #undef HAVE_KRB524 48*7c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */ 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #include <string.h> 51*7c478bd9Sstevel@tonic-gate #include <stdio.h> 52*7c478bd9Sstevel@tonic-gate #include <time.h> 53*7c478bd9Sstevel@tonic-gate #include <netdb.h> 54*7c478bd9Sstevel@tonic-gate #include <locale.h> 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG 57*7c478bd9Sstevel@tonic-gate #include <getopt.h> 58*7c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */ 59*7c478bd9Sstevel@tonic-gate #ifdef HAVE_UNISTD_H 60*7c478bd9Sstevel@tonic-gate #include <unistd.h> 61*7c478bd9Sstevel@tonic-gate #else /* HAVE_UNISTD_H */ 62*7c478bd9Sstevel@tonic-gate extern int optind; 63*7c478bd9Sstevel@tonic-gate extern char *optarg; 64*7c478bd9Sstevel@tonic-gate extern int getopt(); 65*7c478bd9Sstevel@tonic-gate #endif /* HAVE_UNISTD_H */ 66*7c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */ 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate #ifndef _WIN32 69*7c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x)) 70*7c478bd9Sstevel@tonic-gate #else /* _WIN32 */ 71*7c478bd9Sstevel@tonic-gate #define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) 72*7c478bd9Sstevel@tonic-gate #endif /* _WIN32 */ 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate #ifdef HAVE_PWD_H 75*7c478bd9Sstevel@tonic-gate #include <pwd.h> 76*7c478bd9Sstevel@tonic-gate char * get_name_from_os() 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate struct passwd *pw; 79*7c478bd9Sstevel@tonic-gate if (pw = getpwuid((int) getuid())) 80*7c478bd9Sstevel@tonic-gate return pw->pw_name; 81*7c478bd9Sstevel@tonic-gate return 0; 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate #else /* HAVE_PWD_H */ 84*7c478bd9Sstevel@tonic-gate #ifdef _WIN32 85*7c478bd9Sstevel@tonic-gate char * get_name_from_os() 86*7c478bd9Sstevel@tonic-gate { 87*7c478bd9Sstevel@tonic-gate static char name[1024]; 88*7c478bd9Sstevel@tonic-gate DWORD name_size = sizeof(name); 89*7c478bd9Sstevel@tonic-gate if (GetUserName(name, &name_size)) { 90*7c478bd9Sstevel@tonic-gate name[sizeof(name)-1] = 0; /* Just to be extra safe */ 91*7c478bd9Sstevel@tonic-gate return name; 92*7c478bd9Sstevel@tonic-gate } else { 93*7c478bd9Sstevel@tonic-gate return 0; 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate #else /* _WIN32 */ 97*7c478bd9Sstevel@tonic-gate char * get_name_from_os() 98*7c478bd9Sstevel@tonic-gate { 99*7c478bd9Sstevel@tonic-gate return 0; 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate #endif /* _WIN32 */ 102*7c478bd9Sstevel@tonic-gate #endif /* HAVE_PWD_H */ 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate static char *progname; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate static char* progname_v5 = 0; 107*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 108*7c478bd9Sstevel@tonic-gate static char* progname_v4 = 0; 109*7c478bd9Sstevel@tonic-gate static char* progname_v524 = 0; 110*7c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */ 111*7c478bd9Sstevel@tonic-gate #include <locale.h> 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate static int got_k5 = 0; 114*7c478bd9Sstevel@tonic-gate static int got_k4 = 0; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate static int default_k5 = 1; 117*7c478bd9Sstevel@tonic-gate #if defined(KRB5_KRB4_COMPAT) && defined(KINIT_DEFAULT_BOTH) 118*7c478bd9Sstevel@tonic-gate static int default_k4 = 1; 119*7c478bd9Sstevel@tonic-gate #else /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */ 120*7c478bd9Sstevel@tonic-gate static int default_k4 = 0; 121*7c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT && KINIT_DEFAULT_BOTH */ 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate static int authed_k5 = 0; 124*7c478bd9Sstevel@tonic-gate static int authed_k4 = 0; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate #define KRB4_BACKUP_DEFAULT_LIFE_SECS 10*60*60 /* 10 hours */ 127*7c478bd9Sstevel@tonic-gate #define ROOT_UNAME "root" 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate struct k_opts 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate /* in seconds */ 134*7c478bd9Sstevel@tonic-gate krb5_deltat starttime; 135*7c478bd9Sstevel@tonic-gate krb5_deltat lifetime; 136*7c478bd9Sstevel@tonic-gate krb5_deltat rlife; 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate int forwardable; 139*7c478bd9Sstevel@tonic-gate int proxiable; 140*7c478bd9Sstevel@tonic-gate int addresses; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate int not_forwardable; 143*7c478bd9Sstevel@tonic-gate int not_proxiable; 144*7c478bd9Sstevel@tonic-gate int no_addresses; 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate int verbose; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate char* principal_name; 149*7c478bd9Sstevel@tonic-gate char* service_name; 150*7c478bd9Sstevel@tonic-gate char* keytab_name; 151*7c478bd9Sstevel@tonic-gate char* k5_cache_name; 152*7c478bd9Sstevel@tonic-gate char* k4_cache_name; 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate action_type action; 155*7c478bd9Sstevel@tonic-gate }; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate int forwardable_flag = 0; 158*7c478bd9Sstevel@tonic-gate int renewable_flag = 0; 159*7c478bd9Sstevel@tonic-gate int proxiable_flag = 0; 160*7c478bd9Sstevel@tonic-gate int no_address_flag = 0; 161*7c478bd9Sstevel@tonic-gate profile_options_boolean config_option[] = { 162*7c478bd9Sstevel@tonic-gate { "forwardable", &forwardable_flag, 0 }, 163*7c478bd9Sstevel@tonic-gate { "renewable", &renewable_flag, 0 }, 164*7c478bd9Sstevel@tonic-gate { "proxiable", &proxiable_flag, 0 }, 165*7c478bd9Sstevel@tonic-gate { "no_addresses", &no_address_flag, 0 }, 166*7c478bd9Sstevel@tonic-gate { NULL, NULL, 0 } 167*7c478bd9Sstevel@tonic-gate }; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate char *renew_timeval=NULL; 170*7c478bd9Sstevel@tonic-gate char *life_timeval=NULL; 171*7c478bd9Sstevel@tonic-gate int lifetime_specified; 172*7c478bd9Sstevel@tonic-gate int renewtime_specified; 173*7c478bd9Sstevel@tonic-gate profile_option_strings config_times[] = { 174*7c478bd9Sstevel@tonic-gate { "max_life", &life_timeval, 0 }, 175*7c478bd9Sstevel@tonic-gate { "max_renewable_life", &renew_timeval, 0 }, 176*7c478bd9Sstevel@tonic-gate { NULL, NULL, 0 } 177*7c478bd9Sstevel@tonic-gate }; 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate struct k5_data 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate krb5_context ctx; 182*7c478bd9Sstevel@tonic-gate krb5_ccache cc; 183*7c478bd9Sstevel@tonic-gate krb5_principal me; 184*7c478bd9Sstevel@tonic-gate char* name; 185*7c478bd9Sstevel@tonic-gate }; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate struct k4_data 188*7c478bd9Sstevel@tonic-gate { 189*7c478bd9Sstevel@tonic-gate krb5_deltat lifetime; 190*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 191*7c478bd9Sstevel@tonic-gate char aname[ANAME_SZ + 1]; 192*7c478bd9Sstevel@tonic-gate char inst[INST_SZ + 1]; 193*7c478bd9Sstevel@tonic-gate char realm[REALM_SZ + 1]; 194*7c478bd9Sstevel@tonic-gate char name[ANAME_SZ + 1 + INST_SZ + 1 + REALM_SZ + 1]; 195*7c478bd9Sstevel@tonic-gate #endif /*KRB5_KRB4_COMPAT */ 196*7c478bd9Sstevel@tonic-gate }; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate char *realmdef[] = { "realms", NULL, "kinit", NULL }; 199*7c478bd9Sstevel@tonic-gate char *appdef[] = { "appdefaults", "kinit", NULL }; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate #define krb_realm (*(realmdef + 1)) 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate #define lifetime_specified config_times[0].found 204*7c478bd9Sstevel@tonic-gate #define renewtime_specified config_times[1].found 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * Try no preauthentication first; then try the encrypted timestamp 208*7c478bd9Sstevel@tonic-gate */ 209*7c478bd9Sstevel@tonic-gate krb5_preauthtype * preauth = NULL; 210*7c478bd9Sstevel@tonic-gate krb5_preauthtype preauth_list[2] = { 0, -1 }; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate static void _kwarnd_add_warning(char *, time_t); 213*7c478bd9Sstevel@tonic-gate static void _kwarnd_del_warning(char *); 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG 216*7c478bd9Sstevel@tonic-gate /* if struct[2] == NULL, then long_getopt acts as if the short flag 217*7c478bd9Sstevel@tonic-gate struct[3] was specified. If struct[2] != NULL, then struct[3] is 218*7c478bd9Sstevel@tonic-gate stored in *(struct[2]), the array index which was specified is 219*7c478bd9Sstevel@tonic-gate stored in *index, and long_getopt() returns 0. */ 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate struct option long_options[] = { 222*7c478bd9Sstevel@tonic-gate { "noforwardable", 0, NULL, 'F' }, 223*7c478bd9Sstevel@tonic-gate { "noproxiable", 0, NULL, 'P' }, 224*7c478bd9Sstevel@tonic-gate { "addresses", 0, NULL, 'a'}, 225*7c478bd9Sstevel@tonic-gate { "forwardable", 0, NULL, 'f' }, 226*7c478bd9Sstevel@tonic-gate { "proxiable", 0, NULL, 'p' }, 227*7c478bd9Sstevel@tonic-gate { "noaddresses", 0, NULL, 'A' }, 228*7c478bd9Sstevel@tonic-gate { NULL, 0, NULL, 0 } 229*7c478bd9Sstevel@tonic-gate }; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt_long(argc, argv, str, long_options, 0) 232*7c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */ 233*7c478bd9Sstevel@tonic-gate #define GETOPT(argc, argv, str) getopt(argc, argv, str) 234*7c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */ 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /* Save the program name for the error messages */ 237*7c478bd9Sstevel@tonic-gate static char *progname; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate void 240*7c478bd9Sstevel@tonic-gate usage(void) 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate #define USAGE_BREAK "\n\t" 243*7c478bd9Sstevel@tonic-gate #ifdef GETOPT_LONG 244*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable" 245*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable" 246*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses" 247*7c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG USAGE_BREAK 248*7c478bd9Sstevel@tonic-gate #else /* GETOPT_LONG */ 249*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_FORWARDABLE "" 250*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_PROXIABLE "" 251*7c478bd9Sstevel@tonic-gate #define USAGE_LONG_ADDRESSES "" 252*7c478bd9Sstevel@tonic-gate #define USAGE_BREAK_LONG "" 253*7c478bd9Sstevel@tonic-gate #endif /* GETOPT_LONG */ 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s : %s [-V] " 256*7c478bd9Sstevel@tonic-gate "[-l lifetime] [-s start_time] " 257*7c478bd9Sstevel@tonic-gate USAGE_BREAK 258*7c478bd9Sstevel@tonic-gate "[-r renewable_life] " 259*7c478bd9Sstevel@tonic-gate "[-f | -F" USAGE_LONG_FORWARDABLE "] " 260*7c478bd9Sstevel@tonic-gate USAGE_BREAK_LONG 261*7c478bd9Sstevel@tonic-gate "[-p | -P" USAGE_LONG_PROXIABLE "] " 262*7c478bd9Sstevel@tonic-gate USAGE_BREAK_LONG 263*7c478bd9Sstevel@tonic-gate "[-A" USAGE_LONG_ADDRESSES "] " 264*7c478bd9Sstevel@tonic-gate USAGE_BREAK 265*7c478bd9Sstevel@tonic-gate "[-v] [-R] " 266*7c478bd9Sstevel@tonic-gate "[-k [-t keytab_file]] " 267*7c478bd9Sstevel@tonic-gate USAGE_BREAK 268*7c478bd9Sstevel@tonic-gate "[-c cachename] " 269*7c478bd9Sstevel@tonic-gate "[-S service_name] [principal]" 270*7c478bd9Sstevel@tonic-gate "\n\n", 271*7c478bd9Sstevel@tonic-gate gettext("Usage"), progname); 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate #define KRB_AVAIL_STRING(x) ((x)?gettext("available"):gettext("not available")) 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB5 "5" 276*7c478bd9Sstevel@tonic-gate #define OPTTYPE_KRB4 "4" 277*7c478bd9Sstevel@tonic-gate #define OPTTYPE_EITHER "Either 4 or 5" 278*7c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524 279*7c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5, or both 5 and 4" 280*7c478bd9Sstevel@tonic-gate #else 281*7c478bd9Sstevel@tonic-gate #define OPTTYPE_BOTH "5" 282*7c478bd9Sstevel@tonic-gate #endif 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 285*7c478bd9Sstevel@tonic-gate #define USAGE_OPT_FMT "%s%-50s%s\n" 286*7c478bd9Sstevel@tonic-gate #else 287*7c478bd9Sstevel@tonic-gate #define USAGE_OPT_FMT "%s%s\n" 288*7c478bd9Sstevel@tonic-gate #endif 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate #define ULINE(indent, col1, col2) \ 291*7c478bd9Sstevel@tonic-gate fprintf(stderr, USAGE_OPT_FMT, indent, col1, col2) 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate ULINE(" ", "options:", "valid with Kerberos:"); 294*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-5 Kerberos 5 (%s)\n", KRB_AVAIL_STRING(got_k5)); 295*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t-4 Kerberos 4 (%s)\n", KRB_AVAIL_STRING(got_k4)); 296*7c478bd9Sstevel@tonic-gate fprintf(stderr, "\t (Default behavior is to try %s%s%s%s)\n", 297*7c478bd9Sstevel@tonic-gate default_k5?"Kerberos 5":"", 298*7c478bd9Sstevel@tonic-gate (default_k5 && default_k4)?gettext(" and "):"", 299*7c478bd9Sstevel@tonic-gate default_k4?"Kerberos 4":"", 300*7c478bd9Sstevel@tonic-gate (!default_k5 && !default_k4)?gettext("neither"):""); 301*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-V verbose"), OPTTYPE_EITHER); 302*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-l lifetime"), OPTTYPE_EITHER); 303*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-s start time"), OPTTYPE_KRB5); 304*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-r renewable lifetime"), OPTTYPE_KRB5); 305*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-f forwardable"), OPTTYPE_KRB5); 306*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-F not forwardable"), OPTTYPE_KRB5); 307*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-p proxiable"), OPTTYPE_KRB5); 308*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-P not proxiable"), OPTTYPE_KRB5); 309*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-A do not include addresses"), OPTTYPE_KRB5); 310*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-v validate"), OPTTYPE_KRB5); 311*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-R renew"), OPTTYPE_BOTH); 312*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-k use keytab"), OPTTYPE_BOTH); 313*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-t filename of keytab to use"), OPTTYPE_BOTH); 314*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-c Kerberos 5 cache name"), OPTTYPE_KRB5); 315*7c478bd9Sstevel@tonic-gate /* This options is not yet available: */ 316*7c478bd9Sstevel@tonic-gate /* ULINE("\t", "-C Kerberos 4 cache name", OPTTYPE_KRB4); */ 317*7c478bd9Sstevel@tonic-gate ULINE("\t", gettext("-S service"), OPTTYPE_BOTH); 318*7c478bd9Sstevel@tonic-gate exit(2); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate char * 322*7c478bd9Sstevel@tonic-gate parse_options(argc, argv, opts) 323*7c478bd9Sstevel@tonic-gate int argc; 324*7c478bd9Sstevel@tonic-gate char **argv; 325*7c478bd9Sstevel@tonic-gate struct k_opts* opts; 326*7c478bd9Sstevel@tonic-gate { 327*7c478bd9Sstevel@tonic-gate krb5_error_code code; 328*7c478bd9Sstevel@tonic-gate int errflg = 0; 329*7c478bd9Sstevel@tonic-gate int use_k4 = 0; 330*7c478bd9Sstevel@tonic-gate int use_k5 = 0; 331*7c478bd9Sstevel@tonic-gate int i; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RS:v")) 334*7c478bd9Sstevel@tonic-gate != -1) { 335*7c478bd9Sstevel@tonic-gate switch (i) { 336*7c478bd9Sstevel@tonic-gate case 'V': 337*7c478bd9Sstevel@tonic-gate opts->verbose = 1; 338*7c478bd9Sstevel@tonic-gate break; 339*7c478bd9Sstevel@tonic-gate case 'l': 340*7c478bd9Sstevel@tonic-gate /* Lifetime */ 341*7c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->lifetime); 342*7c478bd9Sstevel@tonic-gate if (code != 0 || opts->lifetime == 0) { 343*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg); 344*7c478bd9Sstevel@tonic-gate errflg++; 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate break; 347*7c478bd9Sstevel@tonic-gate case 'r': 348*7c478bd9Sstevel@tonic-gate /* Renewable Time */ 349*7c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->rlife); 350*7c478bd9Sstevel@tonic-gate if (code != 0 || opts->rlife == 0) { 351*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad lifetime value %s\n"), optarg); 352*7c478bd9Sstevel@tonic-gate errflg++; 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate break; 355*7c478bd9Sstevel@tonic-gate case 'f': 356*7c478bd9Sstevel@tonic-gate opts->forwardable = 1; 357*7c478bd9Sstevel@tonic-gate break; 358*7c478bd9Sstevel@tonic-gate case 'F': 359*7c478bd9Sstevel@tonic-gate opts->not_forwardable = 1; 360*7c478bd9Sstevel@tonic-gate break; 361*7c478bd9Sstevel@tonic-gate case 'p': 362*7c478bd9Sstevel@tonic-gate opts->proxiable = 1; 363*7c478bd9Sstevel@tonic-gate break; 364*7c478bd9Sstevel@tonic-gate case 'P': 365*7c478bd9Sstevel@tonic-gate opts->not_proxiable = 1; 366*7c478bd9Sstevel@tonic-gate break; 367*7c478bd9Sstevel@tonic-gate case 'a': 368*7c478bd9Sstevel@tonic-gate /* Note: This is supported only with GETOPT_LONG */ 369*7c478bd9Sstevel@tonic-gate opts->addresses = 1; 370*7c478bd9Sstevel@tonic-gate break; 371*7c478bd9Sstevel@tonic-gate case 'A': 372*7c478bd9Sstevel@tonic-gate opts->no_addresses = 1; 373*7c478bd9Sstevel@tonic-gate break; 374*7c478bd9Sstevel@tonic-gate case 's': 375*7c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(optarg, &opts->starttime); 376*7c478bd9Sstevel@tonic-gate if (code != 0 || opts->starttime == 0) { 377*7c478bd9Sstevel@tonic-gate krb5_timestamp abs_starttime; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate code = krb5_string_to_timestamp(optarg, &abs_starttime); 380*7c478bd9Sstevel@tonic-gate if (code != 0 || abs_starttime == 0) { 381*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad start time value %s\n"), optarg); 382*7c478bd9Sstevel@tonic-gate errflg++; 383*7c478bd9Sstevel@tonic-gate } else { 384*7c478bd9Sstevel@tonic-gate opts->starttime = abs_starttime - time(0); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate break; 388*7c478bd9Sstevel@tonic-gate case 'S': 389*7c478bd9Sstevel@tonic-gate opts->service_name = optarg; 390*7c478bd9Sstevel@tonic-gate break; 391*7c478bd9Sstevel@tonic-gate case 'k': 392*7c478bd9Sstevel@tonic-gate opts->action = INIT_KT; 393*7c478bd9Sstevel@tonic-gate break; 394*7c478bd9Sstevel@tonic-gate case 't': 395*7c478bd9Sstevel@tonic-gate if (opts->keytab_name) 396*7c478bd9Sstevel@tonic-gate { 397*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one -t option allowed.\n")); 398*7c478bd9Sstevel@tonic-gate errflg++; 399*7c478bd9Sstevel@tonic-gate } else { 400*7c478bd9Sstevel@tonic-gate opts->keytab_name = optarg; 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate break; 403*7c478bd9Sstevel@tonic-gate case 'R': 404*7c478bd9Sstevel@tonic-gate opts->action = RENEW; 405*7c478bd9Sstevel@tonic-gate break; 406*7c478bd9Sstevel@tonic-gate case 'v': 407*7c478bd9Sstevel@tonic-gate opts->action = VALIDATE; 408*7c478bd9Sstevel@tonic-gate break; 409*7c478bd9Sstevel@tonic-gate case 'c': 410*7c478bd9Sstevel@tonic-gate if (opts->k5_cache_name) 411*7c478bd9Sstevel@tonic-gate { 412*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one -c option allowed\n")); 413*7c478bd9Sstevel@tonic-gate errflg++; 414*7c478bd9Sstevel@tonic-gate } else { 415*7c478bd9Sstevel@tonic-gate opts->k5_cache_name = optarg; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate break; 418*7c478bd9Sstevel@tonic-gate #if 0 419*7c478bd9Sstevel@tonic-gate /* 420*7c478bd9Sstevel@tonic-gate A little more work is needed before we can enable this 421*7c478bd9Sstevel@tonic-gate option. 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate case 'C': 424*7c478bd9Sstevel@tonic-gate if (opts->k4_cache_name) 425*7c478bd9Sstevel@tonic-gate { 426*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Only one -C option allowed\n"); 427*7c478bd9Sstevel@tonic-gate errflg++; 428*7c478bd9Sstevel@tonic-gate } else { 429*7c478bd9Sstevel@tonic-gate opts->k4_cache_name = optarg; 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate break; 432*7c478bd9Sstevel@tonic-gate #endif 433*7c478bd9Sstevel@tonic-gate case '4': 434*7c478bd9Sstevel@tonic-gate if (!got_k4) 435*7c478bd9Sstevel@tonic-gate { 436*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 437*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Kerberos 4 support could not be loaded\n"); 438*7c478bd9Sstevel@tonic-gate #else 439*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("This was not built with Kerberos 4 support\n")); 440*7c478bd9Sstevel@tonic-gate #endif 441*7c478bd9Sstevel@tonic-gate exit(3); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate use_k4 = 1; 444*7c478bd9Sstevel@tonic-gate break; 445*7c478bd9Sstevel@tonic-gate case '5': 446*7c478bd9Sstevel@tonic-gate if (!got_k5) 447*7c478bd9Sstevel@tonic-gate { 448*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Kerberos 5 support could not be loaded\n")); 449*7c478bd9Sstevel@tonic-gate exit(3); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate use_k5 = 1; 452*7c478bd9Sstevel@tonic-gate break; 453*7c478bd9Sstevel@tonic-gate default: 454*7c478bd9Sstevel@tonic-gate errflg++; 455*7c478bd9Sstevel@tonic-gate break; 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate if (opts->forwardable && opts->not_forwardable) 460*7c478bd9Sstevel@tonic-gate { 461*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -f and -F allowed\n")); 462*7c478bd9Sstevel@tonic-gate errflg++; 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate if (opts->proxiable && opts->not_proxiable) 465*7c478bd9Sstevel@tonic-gate { 466*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -p and -P allowed\n")); 467*7c478bd9Sstevel@tonic-gate errflg++; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate if (opts->addresses && opts->no_addresses) 470*7c478bd9Sstevel@tonic-gate { 471*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Only one of -a and -A allowed\n")); 472*7c478bd9Sstevel@tonic-gate errflg++; 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate if (argc - optind > 1) { 476*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Extra arguments (starting with \"%s\").\n"), 477*7c478bd9Sstevel@tonic-gate argv[optind+1]); 478*7c478bd9Sstevel@tonic-gate errflg++; 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate /* At this point, if errorless, we know we only have one option 482*7c478bd9Sstevel@tonic-gate selection */ 483*7c478bd9Sstevel@tonic-gate if (!use_k5 && !use_k4) { 484*7c478bd9Sstevel@tonic-gate use_k5 = default_k5; 485*7c478bd9Sstevel@tonic-gate use_k4 = default_k4; 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate /* Now, we encode the OPTTYPE stuff here... */ 489*7c478bd9Sstevel@tonic-gate if (!use_k5 && 490*7c478bd9Sstevel@tonic-gate (opts->starttime || opts->rlife || opts->forwardable || 491*7c478bd9Sstevel@tonic-gate opts->proxiable || opts->addresses || opts->not_forwardable || 492*7c478bd9Sstevel@tonic-gate opts->not_proxiable || opts->no_addresses || 493*7c478bd9Sstevel@tonic-gate (opts->action == VALIDATE) || opts->k5_cache_name)) 494*7c478bd9Sstevel@tonic-gate { 495*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that requires Kerberos 5\n")); 496*7c478bd9Sstevel@tonic-gate errflg++; 497*7c478bd9Sstevel@tonic-gate } 498*7c478bd9Sstevel@tonic-gate if (!use_k4 && 499*7c478bd9Sstevel@tonic-gate opts->k4_cache_name) 500*7c478bd9Sstevel@tonic-gate { 501*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that require Kerberos 4\n")); 502*7c478bd9Sstevel@tonic-gate errflg++; 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate if ( 505*7c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524 506*7c478bd9Sstevel@tonic-gate !use_k5 507*7c478bd9Sstevel@tonic-gate #else 508*7c478bd9Sstevel@tonic-gate use_k4 509*7c478bd9Sstevel@tonic-gate #endif 510*7c478bd9Sstevel@tonic-gate && (opts->service_name || opts->keytab_name || 511*7c478bd9Sstevel@tonic-gate (opts->action == INIT_KT) || (opts->action == RENEW)) 512*7c478bd9Sstevel@tonic-gate ) 513*7c478bd9Sstevel@tonic-gate { 514*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Specified option that requires Kerberos 5\n")); 515*7c478bd9Sstevel@tonic-gate errflg++; 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate if (errflg) { 519*7c478bd9Sstevel@tonic-gate usage(); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate got_k5 = got_k5 && use_k5; 523*7c478bd9Sstevel@tonic-gate got_k4 = got_k4 && use_k4; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate opts->principal_name = (optind == argc-1) ? argv[optind] : 0; 526*7c478bd9Sstevel@tonic-gate return opts->principal_name; 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate int 530*7c478bd9Sstevel@tonic-gate k5_begin(opts, k5, k4) 531*7c478bd9Sstevel@tonic-gate struct k_opts* opts; 532*7c478bd9Sstevel@tonic-gate struct k5_data* k5; 533*7c478bd9Sstevel@tonic-gate struct k4_data* k4; 534*7c478bd9Sstevel@tonic-gate { 535*7c478bd9Sstevel@tonic-gate char* progname = progname_v5; 536*7c478bd9Sstevel@tonic-gate krb5_error_code code = 0; 537*7c478bd9Sstevel@tonic-gate char* cp; 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate if (!got_k5) 540*7c478bd9Sstevel@tonic-gate return 0; 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate if (code = krb5_init_context(&k5->ctx)) { 543*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while initializing Kerberos 5 library")); 544*7c478bd9Sstevel@tonic-gate return 0; 545*7c478bd9Sstevel@tonic-gate } 546*7c478bd9Sstevel@tonic-gate if (opts->k5_cache_name) 547*7c478bd9Sstevel@tonic-gate { 548*7c478bd9Sstevel@tonic-gate code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); 549*7c478bd9Sstevel@tonic-gate if (code != 0) { 550*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("resolving ccache %s"), 551*7c478bd9Sstevel@tonic-gate opts->k5_cache_name); 552*7c478bd9Sstevel@tonic-gate return 0; 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate } 555*7c478bd9Sstevel@tonic-gate else 556*7c478bd9Sstevel@tonic-gate { 557*7c478bd9Sstevel@tonic-gate if ((code = krb5_cc_default(k5->ctx, &k5->cc))) { 558*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while getting default ccache")); 559*7c478bd9Sstevel@tonic-gate return 0; 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate if (opts->principal_name) 564*7c478bd9Sstevel@tonic-gate { 565*7c478bd9Sstevel@tonic-gate /* Use specified name */ 566*7c478bd9Sstevel@tonic-gate if ((code = krb5_parse_name(k5->ctx, opts->principal_name, 567*7c478bd9Sstevel@tonic-gate &k5->me))) { 568*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when parsing name %s"), 569*7c478bd9Sstevel@tonic-gate opts->principal_name); 570*7c478bd9Sstevel@tonic-gate return 0; 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate } 573*7c478bd9Sstevel@tonic-gate else 574*7c478bd9Sstevel@tonic-gate { 575*7c478bd9Sstevel@tonic-gate /* No principal name specified */ 576*7c478bd9Sstevel@tonic-gate if (opts->action == INIT_KT) { 577*7c478bd9Sstevel@tonic-gate /* Use the default host/service name */ 578*7c478bd9Sstevel@tonic-gate if (code = krb5_sname_to_principal(k5->ctx, NULL, NULL, 579*7c478bd9Sstevel@tonic-gate KRB5_NT_SRV_HST, &k5->me)) { 580*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext( 581*7c478bd9Sstevel@tonic-gate "when creating default server principal name")); 582*7c478bd9Sstevel@tonic-gate return 0; 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate } else { 585*7c478bd9Sstevel@tonic-gate /* Get default principal from cache if one exists */ 586*7c478bd9Sstevel@tonic-gate if (code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me)) { 587*7c478bd9Sstevel@tonic-gate char *name = get_name_from_os(); 588*7c478bd9Sstevel@tonic-gate if (!name) 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Unable to identify user\n")); 591*7c478bd9Sstevel@tonic-gate return 0; 592*7c478bd9Sstevel@tonic-gate } 593*7c478bd9Sstevel@tonic-gate /* use strcmp to ensure only "root" is matched */ 594*7c478bd9Sstevel@tonic-gate if (strcmp(name, ROOT_UNAME) == 0) 595*7c478bd9Sstevel@tonic-gate { 596*7c478bd9Sstevel@tonic-gate if (code = krb5_sname_to_principal(k5->ctx, NULL, ROOT_UNAME, 597*7c478bd9Sstevel@tonic-gate KRB5_NT_SRV_HST, &k5->me)) { 598*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext( 599*7c478bd9Sstevel@tonic-gate "when creating default server principal name")); 600*7c478bd9Sstevel@tonic-gate return 0; 601*7c478bd9Sstevel@tonic-gate } 602*7c478bd9Sstevel@tonic-gate } else if (code = krb5_parse_name(k5->ctx, name, &k5->me)) { 603*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when parsing name %s"), 604*7c478bd9Sstevel@tonic-gate name); 605*7c478bd9Sstevel@tonic-gate return 0; 606*7c478bd9Sstevel@tonic-gate } 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate if (code = krb5_unparse_name(k5->ctx, k5->me, &k5->name)) { 611*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when unparsing name")); 612*7c478bd9Sstevel@tonic-gate return 0; 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate opts->principal_name = k5->name; 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 618*7c478bd9Sstevel@tonic-gate if (got_k4) 619*7c478bd9Sstevel@tonic-gate { 620*7c478bd9Sstevel@tonic-gate /* Translate to a Kerberos 4 principal */ 621*7c478bd9Sstevel@tonic-gate code = krb5_524_conv_principal(k5->ctx, k5->me, 622*7c478bd9Sstevel@tonic-gate k4->aname, k4->inst, k4->realm); 623*7c478bd9Sstevel@tonic-gate if (code) { 624*7c478bd9Sstevel@tonic-gate k4->aname[0] = 0; 625*7c478bd9Sstevel@tonic-gate k4->inst[0] = 0; 626*7c478bd9Sstevel@tonic-gate k4->realm[0] = 0; 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate #endif 630*7c478bd9Sstevel@tonic-gate return 1; 631*7c478bd9Sstevel@tonic-gate } 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate void 634*7c478bd9Sstevel@tonic-gate k5_end(k5) 635*7c478bd9Sstevel@tonic-gate struct k5_data* k5; 636*7c478bd9Sstevel@tonic-gate { 637*7c478bd9Sstevel@tonic-gate if (k5->name) 638*7c478bd9Sstevel@tonic-gate krb5_free_unparsed_name(k5->ctx, k5->name); 639*7c478bd9Sstevel@tonic-gate if (k5->me) 640*7c478bd9Sstevel@tonic-gate krb5_free_principal(k5->ctx, k5->me); 641*7c478bd9Sstevel@tonic-gate if (k5->cc) 642*7c478bd9Sstevel@tonic-gate krb5_cc_close(k5->ctx, k5->cc); 643*7c478bd9Sstevel@tonic-gate if (k5->ctx) 644*7c478bd9Sstevel@tonic-gate krb5_free_context(k5->ctx); 645*7c478bd9Sstevel@tonic-gate memset(k5, 0, sizeof(*k5)); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate int 649*7c478bd9Sstevel@tonic-gate k4_begin(opts, k4) 650*7c478bd9Sstevel@tonic-gate struct k_opts* opts; 651*7c478bd9Sstevel@tonic-gate struct k4_data* k4; 652*7c478bd9Sstevel@tonic-gate { 653*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 654*7c478bd9Sstevel@tonic-gate char* progname = progname_v4; 655*7c478bd9Sstevel@tonic-gate int k_errno = 0; 656*7c478bd9Sstevel@tonic-gate #endif 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate if (!got_k4) 659*7c478bd9Sstevel@tonic-gate return 0; 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 662*7c478bd9Sstevel@tonic-gate if (k4->aname[0]) 663*7c478bd9Sstevel@tonic-gate goto skip; 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate if (opts->principal_name) 666*7c478bd9Sstevel@tonic-gate { 667*7c478bd9Sstevel@tonic-gate /* Use specified name */ 668*7c478bd9Sstevel@tonic-gate if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, 669*7c478bd9Sstevel@tonic-gate opts->principal_name)) 670*7c478bd9Sstevel@tonic-gate { 671*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname, 672*7c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno)); 673*7c478bd9Sstevel@tonic-gate return 0; 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate } else { 676*7c478bd9Sstevel@tonic-gate /* No principal name specified */ 677*7c478bd9Sstevel@tonic-gate if (opts->action == INIT_KT) { 678*7c478bd9Sstevel@tonic-gate /* Use the default host/service name */ 679*7c478bd9Sstevel@tonic-gate /* XXX - need to add this functionality */ 680*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: Kerberos 4 srvtab support is not " 681*7c478bd9Sstevel@tonic-gate "implemented\n", progname); 682*7c478bd9Sstevel@tonic-gate return 0; 683*7c478bd9Sstevel@tonic-gate } else { 684*7c478bd9Sstevel@tonic-gate /* Get default principal from cache if one exists */ 685*7c478bd9Sstevel@tonic-gate if (k_errno = krb_get_tf_fullname(tkt_string(), k4->aname, 686*7c478bd9Sstevel@tonic-gate k4->inst, k4->realm)) 687*7c478bd9Sstevel@tonic-gate { 688*7c478bd9Sstevel@tonic-gate char *name = get_name_from_os(); 689*7c478bd9Sstevel@tonic-gate if (!name) 690*7c478bd9Sstevel@tonic-gate { 691*7c478bd9Sstevel@tonic-gate fprintf(stderr, "Unable to identify user\n"); 692*7c478bd9Sstevel@tonic-gate return 0; 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, 695*7c478bd9Sstevel@tonic-gate name)) 696*7c478bd9Sstevel@tonic-gate { 697*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname, 698*7c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno)); 699*7c478bd9Sstevel@tonic-gate return 0; 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate if (!k4->realm[0]) 706*7c478bd9Sstevel@tonic-gate krb_get_lrealm(k4->realm, 1); 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate if (k4->inst[0]) 709*7c478bd9Sstevel@tonic-gate sprintf(k4->name, "%s.%s@%s", k4->aname, k4->inst, k4->realm); 710*7c478bd9Sstevel@tonic-gate else 711*7c478bd9Sstevel@tonic-gate sprintf(k4->name, "%s@%s", k4->aname, k4->realm); 712*7c478bd9Sstevel@tonic-gate opts->principal_name = k4->name; 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate skip: 715*7c478bd9Sstevel@tonic-gate if (k4->aname[0] && !k_isname(k4->aname)) 716*7c478bd9Sstevel@tonic-gate { 717*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 name format\n", progname); 718*7c478bd9Sstevel@tonic-gate return 0; 719*7c478bd9Sstevel@tonic-gate } 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate if (k4->inst[0] && !k_isinst(k4->inst)) 722*7c478bd9Sstevel@tonic-gate { 723*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 instance format\n", progname); 724*7c478bd9Sstevel@tonic-gate return 0; 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate if (k4->realm[0] && !k_isrealm(k4->realm)) 728*7c478bd9Sstevel@tonic-gate { 729*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: bad Kerberos 4 realm format\n", progname); 730*7c478bd9Sstevel@tonic-gate return 0; 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */ 733*7c478bd9Sstevel@tonic-gate return 1; 734*7c478bd9Sstevel@tonic-gate } 735*7c478bd9Sstevel@tonic-gate 736*7c478bd9Sstevel@tonic-gate void 737*7c478bd9Sstevel@tonic-gate k4_end(k4) 738*7c478bd9Sstevel@tonic-gate struct k4_data* k4; 739*7c478bd9Sstevel@tonic-gate { 740*7c478bd9Sstevel@tonic-gate memset(k4, 0, sizeof(*k4)); 741*7c478bd9Sstevel@tonic-gate } 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 744*7c478bd9Sstevel@tonic-gate static char stash_password[1024]; 745*7c478bd9Sstevel@tonic-gate static int got_password = 0; 746*7c478bd9Sstevel@tonic-gate #endif /* KRB5_KRB4_COMPAT */ 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate krb5_error_code 749*7c478bd9Sstevel@tonic-gate KRB5_CALLCONV 750*7c478bd9Sstevel@tonic-gate kinit_prompter( 751*7c478bd9Sstevel@tonic-gate krb5_context ctx, 752*7c478bd9Sstevel@tonic-gate void *data, 753*7c478bd9Sstevel@tonic-gate const char *name, 754*7c478bd9Sstevel@tonic-gate const char *banner, 755*7c478bd9Sstevel@tonic-gate int num_prompts, 756*7c478bd9Sstevel@tonic-gate krb5_prompt prompts[] 757*7c478bd9Sstevel@tonic-gate ) 758*7c478bd9Sstevel@tonic-gate { 759*7c478bd9Sstevel@tonic-gate int i; 760*7c478bd9Sstevel@tonic-gate krb5_prompt_type *types; 761*7c478bd9Sstevel@tonic-gate krb5_error_code rc = 762*7c478bd9Sstevel@tonic-gate krb5_prompter_posix(ctx, data, name, banner, num_prompts, prompts); 763*7c478bd9Sstevel@tonic-gate if (!rc && (types = krb5_get_prompt_types(ctx))) 764*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_prompts; i++) 765*7c478bd9Sstevel@tonic-gate if ((types[i] == KRB5_PROMPT_TYPE_PASSWORD) || 766*7c478bd9Sstevel@tonic-gate (types[i] == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN)) 767*7c478bd9Sstevel@tonic-gate { 768*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 769*7c478bd9Sstevel@tonic-gate strncpy(stash_password, prompts[i].reply->data, 770*7c478bd9Sstevel@tonic-gate sizeof(stash_password)); 771*7c478bd9Sstevel@tonic-gate got_password = 1; 772*7c478bd9Sstevel@tonic-gate #endif 773*7c478bd9Sstevel@tonic-gate } 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate return rc; 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate int 779*7c478bd9Sstevel@tonic-gate k5_kinit(opts, k5) 780*7c478bd9Sstevel@tonic-gate struct k_opts* opts; 781*7c478bd9Sstevel@tonic-gate struct k5_data* k5; 782*7c478bd9Sstevel@tonic-gate { 783*7c478bd9Sstevel@tonic-gate char* progname = progname_v5; 784*7c478bd9Sstevel@tonic-gate int notix = 1; 785*7c478bd9Sstevel@tonic-gate krb5_keytab keytab = 0; 786*7c478bd9Sstevel@tonic-gate krb5_creds my_creds; 787*7c478bd9Sstevel@tonic-gate krb5_error_code code = 0; 788*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt options; 789*7c478bd9Sstevel@tonic-gate krb5_timestamp now; 790*7c478bd9Sstevel@tonic-gate krb5_deltat lifetime = 0, rlife = 0, krb5_max_duration; 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate if (!got_k5) 793*7c478bd9Sstevel@tonic-gate return 0; 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_init(&options); 796*7c478bd9Sstevel@tonic-gate memset(&my_creds, 0, sizeof(my_creds)); 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate /* 799*7c478bd9Sstevel@tonic-gate * Solaris Kerberos: added support for max_life and max_renewable_life 800*7c478bd9Sstevel@tonic-gate * which should be removed in the next minor release. See PSARC 2003/545 801*7c478bd9Sstevel@tonic-gate * for more info. 802*7c478bd9Sstevel@tonic-gate * 803*7c478bd9Sstevel@tonic-gate * Also, check krb5.conf for proxiable/forwardable/renewable/no_address 804*7c478bd9Sstevel@tonic-gate * parameter values. 805*7c478bd9Sstevel@tonic-gate */ 806*7c478bd9Sstevel@tonic-gate /* If either tkt life or renew life weren't set earlier take common steps to 807*7c478bd9Sstevel@tonic-gate * get the krb5.conf parameter values. 808*7c478bd9Sstevel@tonic-gate */ 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate if ((code = krb5_timeofday(k5->ctx, &now))) { 811*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while getting time of day")); 812*7c478bd9Sstevel@tonic-gate exit(1); 813*7c478bd9Sstevel@tonic-gate } 814*7c478bd9Sstevel@tonic-gate krb5_max_duration = KRB5_KDB_EXPIRATION - now - 60*60; 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate if (opts->lifetime == 0 || opts->rlife == 0) { 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate krb_realm = krb5_princ_realm(k5->ctx, k5->me)->data; 819*7c478bd9Sstevel@tonic-gate /* realm params take precedence */ 820*7c478bd9Sstevel@tonic-gate profile_get_options_string(k5->ctx->profile, realmdef, config_times); 821*7c478bd9Sstevel@tonic-gate profile_get_options_string(k5->ctx->profile, appdef, config_times); 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate /* if the input opts doesn't have lifetime set and the krb5.conf 824*7c478bd9Sstevel@tonic-gate * parameter has been set, use that. 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate if (opts->lifetime == 0 && life_timeval != NULL) { 827*7c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(life_timeval, &lifetime); 828*7c478bd9Sstevel@tonic-gate if (code != 0 || lifetime == 0 || lifetime > krb5_max_duration) { 829*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad max_life " 830*7c478bd9Sstevel@tonic-gate "value in Kerberos config file %s\n"), 831*7c478bd9Sstevel@tonic-gate life_timeval); 832*7c478bd9Sstevel@tonic-gate exit(1); 833*7c478bd9Sstevel@tonic-gate } 834*7c478bd9Sstevel@tonic-gate opts->lifetime = lifetime; 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate if (opts->rlife == 0 && renew_timeval != NULL) { 837*7c478bd9Sstevel@tonic-gate code = krb5_string_to_deltat(renew_timeval, &rlife); 838*7c478bd9Sstevel@tonic-gate if (code != 0 || rlife == 0 || rlife > krb5_max_duration) { 839*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad max_renewable_life " 840*7c478bd9Sstevel@tonic-gate "value in Kerberos config file %s\n"), 841*7c478bd9Sstevel@tonic-gate renew_timeval); 842*7c478bd9Sstevel@tonic-gate exit(1); 843*7c478bd9Sstevel@tonic-gate } 844*7c478bd9Sstevel@tonic-gate opts->rlife = rlife; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate } 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate /* 849*7c478bd9Sstevel@tonic-gate * If lifetime is not set on the cmdline or in the krb5.conf 850*7c478bd9Sstevel@tonic-gate * file, default to max. 851*7c478bd9Sstevel@tonic-gate */ 852*7c478bd9Sstevel@tonic-gate if (opts->lifetime == 0) 853*7c478bd9Sstevel@tonic-gate opts->lifetime = krb5_max_duration; 854*7c478bd9Sstevel@tonic-gate 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate profile_get_options_boolean(k5->ctx->profile, 857*7c478bd9Sstevel@tonic-gate realmdef, config_option); 858*7c478bd9Sstevel@tonic-gate profile_get_options_boolean(k5->ctx->profile, 859*7c478bd9Sstevel@tonic-gate appdef, config_option); 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate /* cmdline opts take precedence over krb5.conf file values */ 863*7c478bd9Sstevel@tonic-gate if (!opts->not_proxiable && proxiable_flag) { 864*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_proxiable(&options, 1); 865*7c478bd9Sstevel@tonic-gate } 866*7c478bd9Sstevel@tonic-gate if (!opts->not_forwardable && forwardable_flag) { 867*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_forwardable(&options, 1); 868*7c478bd9Sstevel@tonic-gate } 869*7c478bd9Sstevel@tonic-gate if (renewable_flag) { 870*7c478bd9Sstevel@tonic-gate /* 871*7c478bd9Sstevel@tonic-gate * If this flag is set in krb5.conf, but rlife is 0, then 872*7c478bd9Sstevel@tonic-gate * set it to the max (and let the KDC sort it out). 873*7c478bd9Sstevel@tonic-gate */ 874*7c478bd9Sstevel@tonic-gate opts->rlife = opts->rlife ? opts->rlife : krb5_max_duration; 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate if (no_address_flag) { 877*7c478bd9Sstevel@tonic-gate /* cmdline opts will overwrite this below if needbe */ 878*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_address_list(&options, NULL); 879*7c478bd9Sstevel@tonic-gate } 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate /* 883*7c478bd9Sstevel@tonic-gate From this point on, we can goto cleanup because my_creds is 884*7c478bd9Sstevel@tonic-gate initialized. 885*7c478bd9Sstevel@tonic-gate */ 886*7c478bd9Sstevel@tonic-gate 887*7c478bd9Sstevel@tonic-gate if (opts->lifetime) 888*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime); 889*7c478bd9Sstevel@tonic-gate if (opts->rlife) 890*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife); 891*7c478bd9Sstevel@tonic-gate if (opts->forwardable) 892*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_forwardable(&options, 1); 893*7c478bd9Sstevel@tonic-gate if (opts->not_forwardable) 894*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_forwardable(&options, 0); 895*7c478bd9Sstevel@tonic-gate if (opts->proxiable) 896*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_proxiable(&options, 1); 897*7c478bd9Sstevel@tonic-gate if (opts->not_proxiable) 898*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_proxiable(&options, 0); 899*7c478bd9Sstevel@tonic-gate if (opts->addresses) 900*7c478bd9Sstevel@tonic-gate { 901*7c478bd9Sstevel@tonic-gate krb5_address **addresses = NULL; 902*7c478bd9Sstevel@tonic-gate code = krb5_os_localaddr(k5->ctx, &addresses); 903*7c478bd9Sstevel@tonic-gate if (code != 0) { 904*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("getting local addresses")); 905*7c478bd9Sstevel@tonic-gate goto cleanup; 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_address_list(&options, addresses); 908*7c478bd9Sstevel@tonic-gate krb5_free_addresses(k5->ctx, addresses); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate if (opts->no_addresses) 911*7c478bd9Sstevel@tonic-gate krb5_get_init_creds_opt_set_address_list(&options, NULL); 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate if ((opts->action == INIT_KT) && opts->keytab_name) 914*7c478bd9Sstevel@tonic-gate { 915*7c478bd9Sstevel@tonic-gate code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); 916*7c478bd9Sstevel@tonic-gate if (code != 0) { 917*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("resolving keytab %s"), 918*7c478bd9Sstevel@tonic-gate opts->keytab_name); 919*7c478bd9Sstevel@tonic-gate goto cleanup; 920*7c478bd9Sstevel@tonic-gate } 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate switch (opts->action) { 926*7c478bd9Sstevel@tonic-gate case INIT_PW: 927*7c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me, 928*7c478bd9Sstevel@tonic-gate 0, kinit_prompter, 0, 929*7c478bd9Sstevel@tonic-gate opts->starttime, 930*7c478bd9Sstevel@tonic-gate opts->service_name, 931*7c478bd9Sstevel@tonic-gate &options); 932*7c478bd9Sstevel@tonic-gate break; 933*7c478bd9Sstevel@tonic-gate case INIT_KT: 934*7c478bd9Sstevel@tonic-gate code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me, 935*7c478bd9Sstevel@tonic-gate keytab, 936*7c478bd9Sstevel@tonic-gate opts->starttime, 937*7c478bd9Sstevel@tonic-gate opts->service_name, 938*7c478bd9Sstevel@tonic-gate &options); 939*7c478bd9Sstevel@tonic-gate break; 940*7c478bd9Sstevel@tonic-gate case VALIDATE: 941*7c478bd9Sstevel@tonic-gate code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me, k5->cc, 942*7c478bd9Sstevel@tonic-gate opts->service_name); 943*7c478bd9Sstevel@tonic-gate break; 944*7c478bd9Sstevel@tonic-gate case RENEW: 945*7c478bd9Sstevel@tonic-gate code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me, k5->cc, 946*7c478bd9Sstevel@tonic-gate opts->service_name); 947*7c478bd9Sstevel@tonic-gate break; 948*7c478bd9Sstevel@tonic-gate } 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate if (code) { 951*7c478bd9Sstevel@tonic-gate char *doing = 0; 952*7c478bd9Sstevel@tonic-gate switch (opts->action) { 953*7c478bd9Sstevel@tonic-gate case INIT_PW: 954*7c478bd9Sstevel@tonic-gate case INIT_KT: 955*7c478bd9Sstevel@tonic-gate doing = gettext("getting initial credentials"); 956*7c478bd9Sstevel@tonic-gate break; 957*7c478bd9Sstevel@tonic-gate case VALIDATE: 958*7c478bd9Sstevel@tonic-gate doing = gettext("validating credentials"); 959*7c478bd9Sstevel@tonic-gate break; 960*7c478bd9Sstevel@tonic-gate case RENEW: 961*7c478bd9Sstevel@tonic-gate doing = gettext("renewing credentials"); 962*7c478bd9Sstevel@tonic-gate break; 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate /* If got code == KRB5_AP_ERR_V4_REPLY && got_k4, we should 966*7c478bd9Sstevel@tonic-gate let the user know that maybe he/she wants -4. */ 967*7c478bd9Sstevel@tonic-gate if (code == KRB5KRB_AP_ERR_V4_REPLY && got_k4) 968*7c478bd9Sstevel@tonic-gate com_err(progname, code, "while %s\n" 969*7c478bd9Sstevel@tonic-gate "The KDC doesn't support v5. " 970*7c478bd9Sstevel@tonic-gate "You may want the -4 option in the future", 971*7c478bd9Sstevel@tonic-gate doing); 972*7c478bd9Sstevel@tonic-gate else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) 973*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: Password incorrect while %s\n"), progname, 974*7c478bd9Sstevel@tonic-gate doing); 975*7c478bd9Sstevel@tonic-gate else 976*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while %s"), doing); 977*7c478bd9Sstevel@tonic-gate goto cleanup; 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate if (!opts->lifetime) { 981*7c478bd9Sstevel@tonic-gate /* We need to figure out what lifetime to use for Kerberos 4. */ 982*7c478bd9Sstevel@tonic-gate opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; 983*7c478bd9Sstevel@tonic-gate } 984*7c478bd9Sstevel@tonic-gate 985*7c478bd9Sstevel@tonic-gate if (code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me)) { 986*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("when initializing cache %s"), 987*7c478bd9Sstevel@tonic-gate opts->k5_cache_name?opts->k5_cache_name:""); 988*7c478bd9Sstevel@tonic-gate goto cleanup; 989*7c478bd9Sstevel@tonic-gate } 990*7c478bd9Sstevel@tonic-gate 991*7c478bd9Sstevel@tonic-gate if (code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds)) { 992*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext("while storing credentials")); 993*7c478bd9Sstevel@tonic-gate goto cleanup; 994*7c478bd9Sstevel@tonic-gate } 995*7c478bd9Sstevel@tonic-gate 996*7c478bd9Sstevel@tonic-gate if (opts->action == RENEW) { 997*7c478bd9Sstevel@tonic-gate _kwarnd_del_warning(opts->principal_name); 998*7c478bd9Sstevel@tonic-gate _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime); 999*7c478bd9Sstevel@tonic-gate } else if ((opts->action == INIT_KT) || (opts->action == INIT_PW)) { 1000*7c478bd9Sstevel@tonic-gate _kwarnd_add_warning(opts->principal_name, my_creds.times.endtime); 1001*7c478bd9Sstevel@tonic-gate } 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate notix = 0; 1004*7c478bd9Sstevel@tonic-gate 1005*7c478bd9Sstevel@tonic-gate cleanup: 1006*7c478bd9Sstevel@tonic-gate if (my_creds.client == k5->me) { 1007*7c478bd9Sstevel@tonic-gate my_creds.client = 0; 1008*7c478bd9Sstevel@tonic-gate } 1009*7c478bd9Sstevel@tonic-gate krb5_free_cred_contents(k5->ctx, &my_creds); 1010*7c478bd9Sstevel@tonic-gate if (keytab) 1011*7c478bd9Sstevel@tonic-gate krb5_kt_close(k5->ctx, keytab); 1012*7c478bd9Sstevel@tonic-gate return notix?0:1; 1013*7c478bd9Sstevel@tonic-gate } 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate int 1016*7c478bd9Sstevel@tonic-gate k4_kinit(opts, k4, ctx) 1017*7c478bd9Sstevel@tonic-gate struct k_opts* opts; 1018*7c478bd9Sstevel@tonic-gate struct k4_data* k4; 1019*7c478bd9Sstevel@tonic-gate krb5_context ctx; 1020*7c478bd9Sstevel@tonic-gate { 1021*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1022*7c478bd9Sstevel@tonic-gate char* progname = progname_v4; 1023*7c478bd9Sstevel@tonic-gate int k_errno = 0; 1024*7c478bd9Sstevel@tonic-gate #endif 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate if (!got_k4) 1027*7c478bd9Sstevel@tonic-gate return 0; 1028*7c478bd9Sstevel@tonic-gate 1029*7c478bd9Sstevel@tonic-gate if (opts->starttime) 1030*7c478bd9Sstevel@tonic-gate return 0; 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1033*7c478bd9Sstevel@tonic-gate if (!k4->lifetime) 1034*7c478bd9Sstevel@tonic-gate k4->lifetime = opts->lifetime; 1035*7c478bd9Sstevel@tonic-gate if (!k4->lifetime) 1036*7c478bd9Sstevel@tonic-gate k4->lifetime = KRB4_BACKUP_DEFAULT_LIFE_SECS; 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate k4->lifetime /= (5 * 60); 1039*7c478bd9Sstevel@tonic-gate if (k4->lifetime < 1) 1040*7c478bd9Sstevel@tonic-gate k4->lifetime = 1; 1041*7c478bd9Sstevel@tonic-gate if (k4->lifetime > 255) 1042*7c478bd9Sstevel@tonic-gate k4->lifetime = 255; 1043*7c478bd9Sstevel@tonic-gate 1044*7c478bd9Sstevel@tonic-gate switch (opts->action) 1045*7c478bd9Sstevel@tonic-gate { 1046*7c478bd9Sstevel@tonic-gate case INIT_PW: 1047*7c478bd9Sstevel@tonic-gate if (!got_password) { 1048*7c478bd9Sstevel@tonic-gate int pwsize = sizeof(stash_password); 1049*7c478bd9Sstevel@tonic-gate krb5_error_code code; 1050*7c478bd9Sstevel@tonic-gate char prompt[1024]; 1051*7c478bd9Sstevel@tonic-gate 1052*7c478bd9Sstevel@tonic-gate sprintf(prompt, gettext("Password for %s: "), opts->principal_name); 1053*7c478bd9Sstevel@tonic-gate stash_password[0] = 0; 1054*7c478bd9Sstevel@tonic-gate /* 1055*7c478bd9Sstevel@tonic-gate Note: krb5_read_password does not actually look at the 1056*7c478bd9Sstevel@tonic-gate context, so we're ok even if we don't have a context. If 1057*7c478bd9Sstevel@tonic-gate we cannot dynamically load krb5, we can substitute any 1058*7c478bd9Sstevel@tonic-gate decent read password function instead of the krb5 one. 1059*7c478bd9Sstevel@tonic-gate */ 1060*7c478bd9Sstevel@tonic-gate code = krb5_read_password(ctx, prompt, 0, stash_password, &pwsize); 1061*7c478bd9Sstevel@tonic-gate if (code || pwsize == 0) 1062*7c478bd9Sstevel@tonic-gate { 1063*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Error while reading password for '%s'\n"), 1064*7c478bd9Sstevel@tonic-gate opts->principal_name); 1065*7c478bd9Sstevel@tonic-gate memset(stash_password, 0, sizeof(stash_password)); 1066*7c478bd9Sstevel@tonic-gate return 0; 1067*7c478bd9Sstevel@tonic-gate } 1068*7c478bd9Sstevel@tonic-gate got_password = 1; 1069*7c478bd9Sstevel@tonic-gate } 1070*7c478bd9Sstevel@tonic-gate k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt", 1071*7c478bd9Sstevel@tonic-gate k4->realm, k4->lifetime, stash_password); 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate if (k_errno) { 1074*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: %s\n", progname, 1075*7c478bd9Sstevel@tonic-gate krb_get_err_text(k_errno)); 1076*7c478bd9Sstevel@tonic-gate if (authed_k5) 1077*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Maybe your KDC does not support v4. " 1078*7c478bd9Sstevel@tonic-gate "Try the -5 option next time.\n")); 1079*7c478bd9Sstevel@tonic-gate return 0; 1080*7c478bd9Sstevel@tonic-gate } 1081*7c478bd9Sstevel@tonic-gate return 1; 1082*7c478bd9Sstevel@tonic-gate #ifndef HAVE_KRB524 1083*7c478bd9Sstevel@tonic-gate case INIT_KT: 1084*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: srvtabs are not supported\n"), progname); 1085*7c478bd9Sstevel@tonic-gate return 0; 1086*7c478bd9Sstevel@tonic-gate case RENEW: 1087*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: renewal of krb4 tickets is not supported\n"), 1088*7c478bd9Sstevel@tonic-gate progname); 1089*7c478bd9Sstevel@tonic-gate return 0; 1090*7c478bd9Sstevel@tonic-gate #endif 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate #endif 1093*7c478bd9Sstevel@tonic-gate return 0; 1094*7c478bd9Sstevel@tonic-gate } 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate char* 1097*7c478bd9Sstevel@tonic-gate getvprogname(v) 1098*7c478bd9Sstevel@tonic-gate char *v; 1099*7c478bd9Sstevel@tonic-gate { 1100*7c478bd9Sstevel@tonic-gate int len = strlen(progname) + 2 + strlen(v) + 2; 1101*7c478bd9Sstevel@tonic-gate char *ret = malloc(len); 1102*7c478bd9Sstevel@tonic-gate if (ret) 1103*7c478bd9Sstevel@tonic-gate sprintf(ret, "%s(v%s)", progname, v); 1104*7c478bd9Sstevel@tonic-gate else 1105*7c478bd9Sstevel@tonic-gate ret = progname; 1106*7c478bd9Sstevel@tonic-gate return ret; 1107*7c478bd9Sstevel@tonic-gate } 1108*7c478bd9Sstevel@tonic-gate 1109*7c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524 1110*7c478bd9Sstevel@tonic-gate /* Convert krb5 tickets to krb4. */ 1111*7c478bd9Sstevel@tonic-gate int try_convert524(k5) 1112*7c478bd9Sstevel@tonic-gate struct k5_data* k5; 1113*7c478bd9Sstevel@tonic-gate { 1114*7c478bd9Sstevel@tonic-gate char * progname = progname_v524; 1115*7c478bd9Sstevel@tonic-gate krb5_error_code code = 0; 1116*7c478bd9Sstevel@tonic-gate int icode = 0; 1117*7c478bd9Sstevel@tonic-gate krb5_principal kpcserver = 0; 1118*7c478bd9Sstevel@tonic-gate krb5_creds *v5creds = 0; 1119*7c478bd9Sstevel@tonic-gate krb5_creds increds; 1120*7c478bd9Sstevel@tonic-gate CREDENTIALS v4creds; 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate if (!got_k4 || !got_k5) 1123*7c478bd9Sstevel@tonic-gate return 0; 1124*7c478bd9Sstevel@tonic-gate 1125*7c478bd9Sstevel@tonic-gate memset((char *) &increds, 0, sizeof(increds)); 1126*7c478bd9Sstevel@tonic-gate /* 1127*7c478bd9Sstevel@tonic-gate From this point on, we can goto cleanup because increds is 1128*7c478bd9Sstevel@tonic-gate initialized. 1129*7c478bd9Sstevel@tonic-gate */ 1130*7c478bd9Sstevel@tonic-gate 1131*7c478bd9Sstevel@tonic-gate /* or do this directly with krb524_convert_creds_kdc */ 1132*7c478bd9Sstevel@tonic-gate krb524_init_ets(k5->ctx); 1133*7c478bd9Sstevel@tonic-gate 1134*7c478bd9Sstevel@tonic-gate if ((code = krb5_build_principal(k5->ctx, 1135*7c478bd9Sstevel@tonic-gate &kpcserver, 1136*7c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->length, 1137*7c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->data, 1138*7c478bd9Sstevel@tonic-gate "krbtgt", 1139*7c478bd9Sstevel@tonic-gate krb5_princ_realm(k5->ctx, k5->me)->data, 1140*7c478bd9Sstevel@tonic-gate NULL))) { 1141*7c478bd9Sstevel@tonic-gate com_err(progname, code, gettext( 1142*7c478bd9Sstevel@tonic-gate "while creating service principal name")); 1143*7c478bd9Sstevel@tonic-gate goto cleanup; 1144*7c478bd9Sstevel@tonic-gate } 1145*7c478bd9Sstevel@tonic-gate 1146*7c478bd9Sstevel@tonic-gate increds.client = k5->me; 1147*7c478bd9Sstevel@tonic-gate increds.server = kpcserver; 1148*7c478bd9Sstevel@tonic-gate /* Prevent duplicate free calls. */ 1149*7c478bd9Sstevel@tonic-gate kpcserver = 0; 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate increds.times.endtime = 0; 1152*7c478bd9Sstevel@tonic-gate increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; 1153*7c478bd9Sstevel@tonic-gate if ((code = krb5_get_credentials(k5->ctx, 0, 1154*7c478bd9Sstevel@tonic-gate k5->cc, 1155*7c478bd9Sstevel@tonic-gate &increds, 1156*7c478bd9Sstevel@tonic-gate &v5creds))) { 1157*7c478bd9Sstevel@tonic-gate com_err(progname, code, 1158*7c478bd9Sstevel@tonic-gate gettext("getting V5 credentials")); 1159*7c478bd9Sstevel@tonic-gate goto cleanup; 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate if ((icode = krb524_convert_creds_kdc(k5->ctx, 1162*7c478bd9Sstevel@tonic-gate v5creds, 1163*7c478bd9Sstevel@tonic-gate &v4creds))) { 1164*7c478bd9Sstevel@tonic-gate com_err(progname, icode, 1165*7c478bd9Sstevel@tonic-gate gettext("converting to V4 credentials")); 1166*7c478bd9Sstevel@tonic-gate goto cleanup; 1167*7c478bd9Sstevel@tonic-gate } 1168*7c478bd9Sstevel@tonic-gate /* this is stolen from the v4 kinit */ 1169*7c478bd9Sstevel@tonic-gate /* initialize ticket cache */ 1170*7c478bd9Sstevel@tonic-gate if ((icode = in_tkt(v4creds.pname, v4creds.pinst) 1171*7c478bd9Sstevel@tonic-gate != KSUCCESS)) { 1172*7c478bd9Sstevel@tonic-gate com_err(progname, icode, gettext( 1173*7c478bd9Sstevel@tonic-gate "trying to create the V4 ticket file")); 1174*7c478bd9Sstevel@tonic-gate goto cleanup; 1175*7c478bd9Sstevel@tonic-gate } 1176*7c478bd9Sstevel@tonic-gate /* stash ticket, session key, etc. for future use */ 1177*7c478bd9Sstevel@tonic-gate if ((icode = krb_save_credentials(v4creds.service, 1178*7c478bd9Sstevel@tonic-gate v4creds.instance, 1179*7c478bd9Sstevel@tonic-gate v4creds.realm, 1180*7c478bd9Sstevel@tonic-gate v4creds.session, 1181*7c478bd9Sstevel@tonic-gate v4creds.lifetime, 1182*7c478bd9Sstevel@tonic-gate v4creds.kvno, 1183*7c478bd9Sstevel@tonic-gate &(v4creds.ticket_st), 1184*7c478bd9Sstevel@tonic-gate v4creds.issue_date))) { 1185*7c478bd9Sstevel@tonic-gate com_err(progname, icode, gettext( 1186*7c478bd9Sstevel@tonic-gate "trying to save the V4 ticket")); 1187*7c478bd9Sstevel@tonic-gate goto cleanup; 1188*7c478bd9Sstevel@tonic-gate } 1189*7c478bd9Sstevel@tonic-gate 1190*7c478bd9Sstevel@tonic-gate cleanup: 1191*7c478bd9Sstevel@tonic-gate memset(&v4creds, 0, sizeof(v4creds)); 1192*7c478bd9Sstevel@tonic-gate if (v5creds) 1193*7c478bd9Sstevel@tonic-gate krb5_free_creds(k5->ctx, v5creds); 1194*7c478bd9Sstevel@tonic-gate increds.client = 0; 1195*7c478bd9Sstevel@tonic-gate krb5_free_cred_contents(k5->ctx, &increds); 1196*7c478bd9Sstevel@tonic-gate if (kpcserver) 1197*7c478bd9Sstevel@tonic-gate krb5_free_principal(k5->ctx, kpcserver); 1198*7c478bd9Sstevel@tonic-gate return !(code || icode); 1199*7c478bd9Sstevel@tonic-gate } 1200*7c478bd9Sstevel@tonic-gate #endif /* HAVE_KRB524 */ 1201*7c478bd9Sstevel@tonic-gate 1202*7c478bd9Sstevel@tonic-gate int 1203*7c478bd9Sstevel@tonic-gate main(argc, argv) 1204*7c478bd9Sstevel@tonic-gate int argc; 1205*7c478bd9Sstevel@tonic-gate char **argv; 1206*7c478bd9Sstevel@tonic-gate { 1207*7c478bd9Sstevel@tonic-gate struct k_opts opts; 1208*7c478bd9Sstevel@tonic-gate struct k5_data k5; 1209*7c478bd9Sstevel@tonic-gate struct k4_data k4; 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1212*7c478bd9Sstevel@tonic-gate 1213*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1214*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1215*7c478bd9Sstevel@tonic-gate #endif 1216*7c478bd9Sstevel@tonic-gate 1217*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1218*7c478bd9Sstevel@tonic-gate 1219*7c478bd9Sstevel@tonic-gate progname = GET_PROGNAME(argv[0]); 1220*7c478bd9Sstevel@tonic-gate progname_v5 = getvprogname("5"); 1221*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1222*7c478bd9Sstevel@tonic-gate progname_v4 = getvprogname("4"); 1223*7c478bd9Sstevel@tonic-gate progname_v524 = getvprogname("524"); 1224*7c478bd9Sstevel@tonic-gate #endif 1225*7c478bd9Sstevel@tonic-gate 1226*7c478bd9Sstevel@tonic-gate /* Ensure we can be driven from a pipe */ 1227*7c478bd9Sstevel@tonic-gate if(!isatty(fileno(stdin))) 1228*7c478bd9Sstevel@tonic-gate setvbuf(stdin, 0, _IONBF, 0); 1229*7c478bd9Sstevel@tonic-gate if(!isatty(fileno(stdout))) 1230*7c478bd9Sstevel@tonic-gate setvbuf(stdout, 0, _IONBF, 0); 1231*7c478bd9Sstevel@tonic-gate if(!isatty(fileno(stderr))) 1232*7c478bd9Sstevel@tonic-gate setvbuf(stderr, 0, _IONBF, 0); 1233*7c478bd9Sstevel@tonic-gate 1234*7c478bd9Sstevel@tonic-gate /* 1235*7c478bd9Sstevel@tonic-gate This is where we would put in code to dynamically load Kerberos 1236*7c478bd9Sstevel@tonic-gate libraries. Currenlty, we just get them implicitly. 1237*7c478bd9Sstevel@tonic-gate */ 1238*7c478bd9Sstevel@tonic-gate got_k5 = 1; 1239*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1240*7c478bd9Sstevel@tonic-gate got_k4 = 1; 1241*7c478bd9Sstevel@tonic-gate #endif 1242*7c478bd9Sstevel@tonic-gate 1243*7c478bd9Sstevel@tonic-gate memset(&opts, 0, sizeof(opts)); 1244*7c478bd9Sstevel@tonic-gate opts.action = INIT_PW; 1245*7c478bd9Sstevel@tonic-gate 1246*7c478bd9Sstevel@tonic-gate memset(&k5, 0, sizeof(k5)); 1247*7c478bd9Sstevel@tonic-gate memset(&k4, 0, sizeof(k4)); 1248*7c478bd9Sstevel@tonic-gate 1249*7c478bd9Sstevel@tonic-gate parse_options(argc, argv, &opts); 1250*7c478bd9Sstevel@tonic-gate 1251*7c478bd9Sstevel@tonic-gate got_k5 = k5_begin(&opts, &k5, &k4); 1252*7c478bd9Sstevel@tonic-gate got_k4 = k4_begin(&opts, &k4); 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate authed_k5 = k5_kinit(&opts, &k5); 1255*7c478bd9Sstevel@tonic-gate #ifdef HAVE_KRB524 1256*7c478bd9Sstevel@tonic-gate if (authed_k5) 1257*7c478bd9Sstevel@tonic-gate authed_k4 = try_convert524(&k5); 1258*7c478bd9Sstevel@tonic-gate #endif 1259*7c478bd9Sstevel@tonic-gate if (!authed_k4) 1260*7c478bd9Sstevel@tonic-gate authed_k4 = k4_kinit(&opts, &k4, k5.ctx); 1261*7c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 1262*7c478bd9Sstevel@tonic-gate memset(stash_password, 0, sizeof(stash_password)); 1263*7c478bd9Sstevel@tonic-gate #endif 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate if (authed_k5 && opts.verbose) 1266*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Authenticated to Kerberos v5\n")); 1267*7c478bd9Sstevel@tonic-gate if (authed_k4 && opts.verbose) 1268*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Authenticated to Kerberos v4\n")); 1269*7c478bd9Sstevel@tonic-gate 1270*7c478bd9Sstevel@tonic-gate k5_end(&k5); 1271*7c478bd9Sstevel@tonic-gate k4_end(&k4); 1272*7c478bd9Sstevel@tonic-gate 1273*7c478bd9Sstevel@tonic-gate if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4)) 1274*7c478bd9Sstevel@tonic-gate exit(1); 1275*7c478bd9Sstevel@tonic-gate return 0; 1276*7c478bd9Sstevel@tonic-gate } 1277*7c478bd9Sstevel@tonic-gate 1278*7c478bd9Sstevel@tonic-gate static void 1279*7c478bd9Sstevel@tonic-gate _kwarnd_add_warning(char *me, time_t endtime) 1280*7c478bd9Sstevel@tonic-gate { 1281*7c478bd9Sstevel@tonic-gate if (kwarn_add_warning(me, endtime) != 0) 1282*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext( 1283*7c478bd9Sstevel@tonic-gate "%s: no ktkt_warnd warning possible\n"), progname); 1284*7c478bd9Sstevel@tonic-gate return; 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate static void 1289*7c478bd9Sstevel@tonic-gate _kwarnd_del_warning(char *me) 1290*7c478bd9Sstevel@tonic-gate { 1291*7c478bd9Sstevel@tonic-gate if (kwarn_del_warning(me) != 0) 1292*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext( 1293*7c478bd9Sstevel@tonic-gate "%s: unable to delete ktkt_warnd message for %s\n"), 1294*7c478bd9Sstevel@tonic-gate progname, me); 1295*7c478bd9Sstevel@tonic-gate return; 1296*7c478bd9Sstevel@tonic-gate } 1297