From: Danilo Almeida Date: Wed, 16 Feb 2000 21:11:07 +0000 (+0000) Subject: * kinit.c: Nicer usage message. Better checking for illegal X-Git-Tag: krb5-1.2-beta1~74 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=5d85bab0c29696c0fbfe6a5f85a61eb58c6bd329;p=krb5.git * kinit.c: Nicer usage message. Better checking for illegal options. Do not output error when doing Kerberos 4 if we will be trying 524 afterwards. Add hooks for future support for specifying the Kerberos 4 cache name. Fix GET_PROGNAME macro to properly return program name under Win32. Re-indent, turning spaces that should be tabs into tabs. * kinit.M: Document new Kerberos 4 kinit behavior. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12049 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/clients/kinit/ChangeLog b/src/clients/kinit/ChangeLog index 9f984af84..736f43a16 100644 --- a/src/clients/kinit/ChangeLog +++ b/src/clients/kinit/ChangeLog @@ -1,3 +1,14 @@ +2000-02-16 Danilo Almeida + + * kinit.c: Nicer usage message. Better checking for illegal + options. Do not output error when doing Kerberos 4 if we will be + trying 524 afterwards. Add hooks for future support for + specifying the Kerberos 4 cache name. Fix GET_PROGNAME macro to + properly return program name under Win32. Re-indent, turning + spaces that should be tabs into tabs. + + * kinit.M: Document new Kerberos 4 kinit behavior. + 2000-02-07 Ken Raeburn * kinit.c (try_convert524): Avoid duplicate free calls. diff --git a/src/clients/kinit/kinit.M b/src/clients/kinit/kinit.M index e87536c91..356155224 100644 --- a/src/clients/kinit/kinit.M +++ b/src/clients/kinit/kinit.M @@ -28,18 +28,39 @@ kinit \- obtain and cache Kerberos ticket-granting ticket .TP .B kinit .ad l -[\fB\-l\fP \fIlifetime\fP] [\fB\-s\fP \fIstart_time\fP] [\fB\-v\fP] -[\fB\-p\fP] [\fB\-f\fP] [\fB\-k\fP [\fB\-t\fP \fIkeytab_file\fP]] -[\fB\-r\fP \fIrenewable_life\fP] [\fB\-R\fP] [\fB\-c\fP -\fIcache_name\fP] [\fB\-S\fP \fIservice_name\fP] [\fIprincipal\fP] +[\fB\-5\fP] +[\fB\-4\fP] +[\fB\-V\fP] +[\fB\-l\fP \fIlifetime\fP] [\fB\-s\fP \fIstart_time\fP] +[\fB\-r\fP \fIrenewable_life\fP] +[\fB\-p\fP | \fB\-P\fP] +[\fB\-f\fP | \fB\-F\fP] +[\fB\-A\fP] +[\fB\-v\fP] [\fB\-R\fP] +[\fB\-k\fP [\fB\-t\fP \fIkeytab_file\fP]] [\fB\-c\fP \fIcache_name\fP] +[\fB\-S\fP \fIservice_name\fP] [\fIprincipal\fP] .ad b .br .SH DESCRIPTION .I kinit obtains and caches an initial ticket-granting ticket for -.IR principal . +.IR principal . If kinit was build with Kerberos 4 support, +the default behavior is to acquired both Kerberos 5 and Kerberos 4 tickets. +Otherwise, the default behavior is to acquire only Kerberos 5 tickets. +Any documentation particular to Kerberos 4 does not apply if Kerberos 4 +support was not built into kinit. .SH OPTIONS .TP +.B \-5 +get Kerberos 5 tickets only. +.TP +.B \-4 +get Kerberos 4 tickets only. This option is only avialbale if kinit was built +with Kerberos 4 compatibility. +.TP +.B \-V +display verbose output. +.TP \fB\-l\fP \fIlifetime\fP requests a ticket with the lifetime .IR lifetime . @@ -73,30 +94,40 @@ Postdated tickets are issued with the .I invalid flag set, and need to be fed back to the kdc before use. .TP -.B \-v -requests that the ticket granting ticket in the cache (with the -.I invalid -flag set) be passed to the kdc for validation. If the ticket is within -its requested time range, the cache is replaced with the validated -ticket. -.TP -.B \-p -request proxiable tickets. -.TP -.B \-f -request forwardable tickets. -.TP \fB\-r\fP \fIrenewable_life\fP requests renewable tickets, with a total lifetime of .IR renewable_life . The duration is in the same format as the .B \-l -option, with the same delimiters. +option, with the same delimiters. (Not applicaple to Kerberos 4.) +.TP +.B \-f +request forwardable tickets. (Not applicaple to Kerberos 4.) +.TP +.B \-F +do not request forwardable tickets. (Not applicaple to Kerberos 4.) +.TP +.B \-p +request proxiable tickets. (Not applicaple to Kerberos 4.) +.TP +.B \-P +do not request proxiable tickets. (Not applicaple to Kerberos 4.) +.TP +.B \-A +request address-less tickets. (Not applicaple to Kerberos 4.) +.TP +.B \-v +requests that the ticket granting ticket in the cache (with the +.I invalid +flag set) be passed to the kdc for validation. If the ticket is within +its requested time range, the cache is replaced with the validated +ticket. (Not applicaple to Kerberos 4.) .TP .B \-R requests renewal of the ticket-granting ticket. Note that an expired ticket cannot be renewed, even if the ticket is still within its -renewable life. +renewable life. When using this option with Kerberos 4, the kdc must +support Kerberos 5 to Kerberos 4 ticket conversion. .TP \fB\-k\fP [\fB\-t\fP \fIkeytab_file\fP] requests a host ticket, obtained from a key in the local host's @@ -105,33 +136,46 @@ file. The name and location of the keytab file may be specified with the .B \-t .I keytab_file -option; otherwise the default name and location will be used. +option; otherwise the default name and location will be used. When using +this option with Kerberos 4, the kdc must support Kerberos 5 to Kerberos 4 +ticket conversion. .TP \fB\-c\fP \fIcache_name\fP use .I cache_name -as the credentials (ticket) cache name and location; if this option is -not used, the default cache name and location are used. +as the Kerberos 5 credentials (ticket) cache name and location; if this +option is not used, the default cache name and location are used. .sp The default credentials cache may vary between systems. If the .B KRB5CCNAME environment variable is set, its value is used to name the default ticket cache. Any existing contents of the cache are destroyed by .IR kinit . +(Note: The default name for Kerberos 4 comes from the +.B KRBTKFILE +environment variable. This option does not apply to Kerberos 4.) .TP \fB\-S\fP \fIservice_name\fP specify an alternate service name to use when -getting initial tickets. +getting initial tickets. (Applicable to Kerberos 5 or if using both +Kerberos 5 and Kerberos 4 with a kdc that supports Kerberos 5 to Kerberos 4 +ticket conversion.) .SH ENVIRONMENT .B Kinit uses the following environment variable: .TP "\w'.SM KRB5CCNAME\ \ 'u" .SM KRB5CCNAME -Location of the credentials (ticket) cache. +Location of the Kerberos 5 credentials (ticket) cache. +.TP "\w'.SM KRBTKFILE\ \ 'u" +.SM KRBTKFILE +Filename of the Kerberos 4 credentials (ticket) cache. .SH FILES .TP "\w'/tmp/krb5cc_[uid]\ \ 'u" /tmp/krb5cc_[uid] -default credentials cache ([uid] is the decimal UID of the user). +default Kerberos 5 credentials cache ([uid] is the decimal UID of the user). +.TP "\w'/tmp/tkt[uid]\ \ 'u" +/tmp/tkt[uid] +default Kerberos 4 credentials cache ([uid] is the decimal UID of the user). .TP /etc/krb5.keytab default location for the local host's diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c index 6eb39515a..5f281e3a2 100644 --- a/src/clients/kinit/kinit.c +++ b/src/clients/kinit/kinit.c @@ -58,7 +58,7 @@ extern int getopt(); #ifndef _WIN32 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x)) #else -#define GET_PROGNAME(x) (max(strrchr((x), '/'), strrchr((x), '\\')) + 1, (x)) +#define GET_PROGNAME(x) max(max(strrchr((x), '/'), strrchr((x), '\\')) + 1,(x)) #endif #ifdef HAVE_PWD_H @@ -127,7 +127,8 @@ struct k_opts char* principal_name; char* service_name; char* keytab_name; - char* cache_name; + char* k5_cache_name; + char* k4_cache_name; action_type action; }; @@ -168,114 +169,162 @@ struct option long_options[] = { }; #define GETOPT(argc, argv, str) getopt_long(argc, argv, str, long_options, 0) -#define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable" -#define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable" -#define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses" #else #define GETOPT(argc, argv, str) getopt(argc, argv, str) -#define USAGE_LONG_FORWARDABLE "" -#define USAGE_LONG_PROXIABLE "" -#define USAGE_LONG_ADDRESSES "" #endif void -usage() +usage(have_k4, have_k5) + int have_k4; +int have_k5; { -#ifdef KRB5_KRB4_COMPAT -#define USAGE_K54_OPT "[-4] [-5] " -#define USAGE_K54_SRVTAB "/srvtab" + char* k4_default = 0; + char* k5_default = 0; + +#define USAGE_BREAK "\n\t" + +#ifdef GETOPT_LONG +#define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable" +#define USAGE_LONG_PROXIABLE " | --proxiable | --noproxiable" +#define USAGE_LONG_ADDRESSES " | --addresses | --noaddresses" +#define USAGE_BREAK_LONG USAGE_BREAK #else -#define USAGE_K54_OPT "" -#define USAGE_K54_SRVTAB "" +#define USAGE_LONG_FORWARDABLE "" +#define USAGE_LONG_PROXIABLE "" +#define USAGE_LONG_ADDRESSES "" +#define USAGE_BREAK_LONG "" #endif - fprintf(stderr, "Usage: %s [-V] " USAGE_K54_OPT - "[-l lifetime] [-r renewable_life] " + fprintf(stderr, "Usage: %s [-5] [-4] [-V] " + "[-l lifetime] [-s start_time] " + USAGE_BREAK + "[-r renewable_life] " "[-f | -F" USAGE_LONG_FORWARDABLE "] " + USAGE_BREAK_LONG "[-p | -P" USAGE_LONG_PROXIABLE "] " + USAGE_BREAK_LONG "[-A" USAGE_LONG_ADDRESSES "] " - "[-s start_time] [-S target_service] " - "[-k [-t keytab_file]] [-R] [-v] [-c cachename] [principal]\n", + USAGE_BREAK + "[-v] [-R] " + "[-k [-t keytab_file]] " + USAGE_BREAK + "[-c cachename] " + "[-S service_name] [principal]" + "\n\n", progname); - fprintf(stderr, -#ifdef KRB5_KRB4_COMPAT - "\t-4 Kerberos 4 only, -5 Kerberos 5 only, default is both\n" - "\toptions applicable to Kerberos 5 only:\n" + +#define DEFAULT_BOTH "(default is Kerberos 4 & 5)" +#define DEFAULT "(default)" +#define NOT_AVAILABLE "(not available)" + + if (have_k4 && have_k5) + { + k4_default = k5_default = DEFAULT_BOTH; + } + else if (have_k5) + { + k4_default = NOT_AVAILABLE; + k5_default = DEFAULT; + } + else if (have_k4) + { + k4_default = DEFAULT; + k5_default = NOT_AVAILABLE; + } + else + { + k4_default = k5_default = NOT_AVAILABLE; + } + +#define OPTTYPE_KRB5 "5" +#define OPTTYPE_KRB4 "4" +#define OPTTYPE_EITHER "Either 4 or 5" +#ifdef HAVE_KRB524 +#define OPTTYPE_BOTH "5, or both 5 and 4" +#else +#define OPTTYPE_BOTH "5" #endif - "\t\t-v validate\n" - "\t\t-c cache name\n" - "\t\t-f forwardable\n" - "\t\t-F not forwardable\n" - "\t\t-p proxiable\n" - "\t\t-P not proxiable\n" - "\t\t-A do not include addresses\n" - "\t\t-r renewable lifetime\n" - "\t\t-s start time\n" + #ifdef KRB5_KRB4_COMPAT - "\toptions potentially applicable to both:\n" +#define USAGE_OPT_FMT "%s%-50s%s\n" +#else +#define USAGE_OPT_FMT "%s%s\n" #endif - "\t\t-R renew\n" - "\t\t-l lifetime\n" - "\t\t-S service\n" - "\t\t-k use keytab" USAGE_K54_SRVTAB "\n" - "\t\t-t filename of keytab" USAGE_K54_SRVTAB " to use\n" - "\t\t-V verbose\n" - ); + +#define ULINE(indent, col1, col2) \ +fprintf(stderr, USAGE_OPT_FMT, indent, col1, col2) + + ULINE(" ", "options:", "valid with Kerberos:"); + fprintf(stderr, "\t-5 Kerberos 5 only %s\n", k5_default); + fprintf(stderr, "\t-4 Kerberos 4 only %s\n", k4_default); + ULINE("\t", "-V verbose", OPTTYPE_EITHER); + ULINE("\t", "-l lifetime", OPTTYPE_EITHER); + ULINE("\t", "-s start time", OPTTYPE_KRB5); + ULINE("\t", "-r renewable lifetime", OPTTYPE_KRB5); + ULINE("\t", "-f forwardable", OPTTYPE_KRB5); + ULINE("\t", "-F not forwardable", OPTTYPE_KRB5); + ULINE("\t", "-p proxiable", OPTTYPE_KRB5); + ULINE("\t", "-P not proxiable", OPTTYPE_KRB5); + ULINE("\t", "-A do not include addresses", OPTTYPE_KRB5); + ULINE("\t", "-v validate", OPTTYPE_KRB5); + ULINE("\t", "-R renew", OPTTYPE_BOTH); + ULINE("\t", "-k use keytab", OPTTYPE_BOTH); + ULINE("\t", "-t filename of keytab to use", OPTTYPE_BOTH); + ULINE("\t", "-c Kerberos 5 cache name", OPTTYPE_KRB5); + /* This options is not yet available: */ + /* ULINE("\t", "-C Kerberos 4 cache name", OPTTYPE_KRB4); */ + ULINE("\t", "-S service", OPTTYPE_BOTH); exit(2); } char * parse_options(argc, argv, opts) int argc; - char **argv; - struct k_opts* opts; +char **argv; +struct k_opts* opts; { krb5_error_code code; int errflg = 0; int use_k4_only = 0; int use_k5_only = 0; + int old_got_k4 = got_k4; + int old_got_k5 = got_k5; int i; -#ifdef KRB5_KRB4_COMPAT -#define GETOPT_K54 "45" -#else -#define GETOPT_K54 "" -#endif - - while ((i = GETOPT(argc, argv, "r:fpFP" GETOPT_K54 "AVl:s:c:kt:RS:v")) + while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RS:v")) != -1) { switch (i) { - case 'V': - opts->verbose = 1; - break; - case 'l': - /* Lifetime */ - code = krb5_string_to_deltat(optarg, &opts->lifetime); - if (code != 0 || opts->lifetime == 0) { - fprintf(stderr, "Bad lifetime value %s\n", optarg); - errflg++; - } - break; + case 'V': + opts->verbose = 1; + break; + case 'l': + /* Lifetime */ + code = krb5_string_to_deltat(optarg, &opts->lifetime); + if (code != 0 || opts->lifetime == 0) { + fprintf(stderr, "Bad lifetime value %s\n", optarg); + errflg++; + } + break; case 'r': - /* Renewable Time */ - code = krb5_string_to_deltat(optarg, &opts->rlife); - if (code != 0 || opts->rlife == 0) { - fprintf(stderr, "Bad lifetime value %s\n", optarg); - errflg++; - } - break; + /* Renewable Time */ + code = krb5_string_to_deltat(optarg, &opts->rlife); + if (code != 0 || opts->rlife == 0) { + fprintf(stderr, "Bad lifetime value %s\n", optarg); + errflg++; + } + break; case 'f': - opts->forwardable = 1; - break; - case 'F': - opts->not_forwardable = 1; - break; + opts->forwardable = 1; + break; + case 'F': + opts->not_forwardable = 1; + break; case 'p': - opts->proxiable = 1; - break; + opts->proxiable = 1; + break; case 'P': - opts->not_proxiable = 1; - break; + opts->not_proxiable = 1; + break; case 'a': /* Note: This is supported only with GETOPT_LONG */ opts->addresses = 1; @@ -297,21 +346,21 @@ parse_options(argc, argv, opts) } } break; - case 'S': - opts->service_name = optarg; + case 'S': + opts->service_name = optarg; break; - case 'k': - opts->action = INIT_KT; + case 'k': + opts->action = INIT_KT; + break; + case 't': + if (opts->keytab_name) + { + fprintf(stderr, "Only one -t option allowed.\n"); + errflg++; + } else { + opts->keytab_name = optarg; + } break; - case 't': - if (opts->keytab_name) - { - fprintf(stderr, "Only one -t option allowed.\n"); - errflg++; - } else { - opts->keytab_name = optarg; - } - break; case 'R': opts->action = RENEW; break; @@ -319,32 +368,49 @@ parse_options(argc, argv, opts) opts->action = VALIDATE; break; case 'c': - if (opts->cache_name) - { - fprintf(stderr, "Only one -c option allowed\n"); - errflg++; - } else { - opts->cache_name = optarg; - } + if (opts->k5_cache_name) + { + fprintf(stderr, "Only one -c option allowed\n"); + errflg++; + } else { + opts->k5_cache_name = optarg; + } + break; +#if 0 + /* + A little more work is needed before we can enable this + option. + */ + case 'C': + if (opts->k4_cache_name) + { + fprintf(stderr, "Only one -C option allowed\n"); + errflg++; + } else { + opts->k4_cache_name = optarg; + } break; +#endif + case '4': + if (!got_k4) + { #ifdef KRB5_KRB4_COMPAT - case '4': - if (!got_k4) - { - fprintf(stderr, "Kerberos 4 support could not be loaded\n"); - exit(3); - } - use_k4_only = 1; - break; - case '5': - if (!got_k5) - { - fprintf(stderr, "Kerberos 5 support could not be loaded\n"); - exit(3); - } - use_k5_only = 1; - break; + fprintf(stderr, "Kerberos 4 support could not be loaded\n"); +#else + fprintf(stderr, "This kinit was not built with Kerberos 4 support\n"); #endif + exit(3); + } + use_k4_only = 1; + break; + case '5': + if (!got_k5) + { + fprintf(stderr, "Kerberos 5 support could not be loaded\n"); + exit(3); + } + use_k5_only = 1; + break; default: errflg++; break; @@ -353,23 +419,23 @@ parse_options(argc, argv, opts) if (use_k5_only && use_k4_only) { - fprintf(stderr, "Only one of -4 and -5 allowed\n"); - errflg++; + fprintf(stderr, "Only one of -4 and -5 allowed\n"); + errflg++; } if (opts->forwardable && opts->not_forwardable) { - fprintf(stderr, "Only one of -f and -F allowed\n"); - errflg++; + fprintf(stderr, "Only one of -f and -F allowed\n"); + errflg++; } if (opts->proxiable && opts->not_proxiable) { - fprintf(stderr, "Only one of -p and -P allowed\n"); - errflg++; + fprintf(stderr, "Only one of -p and -P allowed\n"); + errflg++; } if (opts->addresses && opts->no_addresses) { - fprintf(stderr, "Only one of -a and -A allowed\n"); - errflg++; + fprintf(stderr, "Only one of -a and -A allowed\n"); + errflg++; } if (argc - optind > 1) { @@ -378,15 +444,46 @@ parse_options(argc, argv, opts) errflg++; } - if (errflg) { - usage(); - } - - /* At this point, we know we only have one option selection */ + /* At this point, if errorless, we know we only have one option + selection */ if (use_k4_only) - got_k5 = 0; + got_k5 = 0; if (use_k5_only) - got_k4 = 0; + got_k4 = 0; + + /* Now, we encode the OPTTYPE stuff here... */ + if (!got_k5 && + (opts->starttime || opts->rlife || opts->forwardable || + opts->proxiable || opts->addresses || opts->not_forwardable || + opts->not_proxiable || opts->no_addresses || + (opts->action == VALIDATE) || opts->k5_cache_name)) + { + fprintf(stderr, "Specified option that requires Kerberos 5\n"); + errflg++; + } + if (!got_k4 && + opts->k4_cache_name) + { + fprintf(stderr, "Specified option that require Kerberos 4\n"); + errflg++; + } + if ( +#ifdef HAVE_KRB524 + !got_k5 +#else + got_k4 +#endif + && (opts->service_name || opts->keytab_name || + (opts->action == INIT_KT) || (opts->action == RENEW)) + ) + { + fprintf(stderr, "Specified option that requires Kerberos 5\n"); + errflg++; + } + + if (errflg) { + usage(old_got_k4, old_got_k5); + } opts->principal_name = (optind == argc-1) ? argv[optind] : 0; return opts->principal_name; @@ -395,82 +492,82 @@ parse_options(argc, argv, opts) int k5_begin(opts, k5, k4) struct k_opts* opts; - struct k5_data* k5; - struct k4_data* k4; +struct k5_data* k5; +struct k4_data* k4; { char* progname = progname_v5; krb5_error_code code = 0; if (!got_k5) - return 0; + return 0; if (code = krb5_init_context(&k5->ctx)) { - com_err(progname, code, "while initializing Kerberos 5 library"); - return 0; + com_err(progname, code, "while initializing Kerberos 5 library"); + return 0; } - if (opts->cache_name) + if (opts->k5_cache_name) { - code = krb5_cc_resolve(k5->ctx, opts->cache_name, &k5->cc); - if (code != 0) { - com_err(progname, code, "resolving ccache %s", - opts->cache_name); - return 0; - } + code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc); + if (code != 0) { + com_err(progname, code, "resolving ccache %s", + opts->k5_cache_name); + return 0; + } } else { - if ((code = krb5_cc_default(k5->ctx, &k5->cc))) { - com_err(progname, code, "while getting default ccache"); - return 0; - } + if ((code = krb5_cc_default(k5->ctx, &k5->cc))) { + com_err(progname, code, "while getting default ccache"); + return 0; + } } if (opts->principal_name) { - /* Use specified name */ - if ((code = krb5_parse_name(k5->ctx, opts->principal_name, - &k5->me))) { - com_err(progname, code, "when parsing name %s", - opts->principal_name); - return 0; - } + /* Use specified name */ + if ((code = krb5_parse_name(k5->ctx, opts->principal_name, + &k5->me))) { + com_err(progname, code, "when parsing name %s", + opts->principal_name); + return 0; + } } else { - /* No principal name specified */ - if (opts->action == INIT_KT) { - /* Use the default host/service name */ - if (code = krb5_sname_to_principal(k5->ctx, NULL, NULL, + /* No principal name specified */ + if (opts->action == INIT_KT) { + /* Use the default host/service name */ + if (code = krb5_sname_to_principal(k5->ctx, NULL, NULL, KRB5_NT_SRV_HST, &k5->me)) { - com_err(progname, code, + com_err(progname, code, "when creating default server principal name"); - return 0; - } - } else { - /* Get default principal from cache if one exists */ - if (code = krb5_cc_get_principal(k5->ctx, k5->cc, - &k5->me)) - { - char *name = get_name_from_os(); - if (!name) - { - fprintf(stderr, "Unable to identify user\n"); - return 0; - } - if ((code = krb5_parse_name(k5->ctx, name, - &k5->me))) - { - com_err(progname, code, "when parsing name %s", + return 0; + } + } else { + /* Get default principal from cache if one exists */ + if (code = krb5_cc_get_principal(k5->ctx, k5->cc, + &k5->me)) + { + char *name = get_name_from_os(); + if (!name) + { + fprintf(stderr, "Unable to identify user\n"); + return 0; + } + if ((code = krb5_parse_name(k5->ctx, name, + &k5->me))) + { + com_err(progname, code, "when parsing name %s", name); - return 0; - } - } - } + return 0; + } + } + } } if (code = krb5_unparse_name(k5->ctx, k5->me, &k5->name)) { - com_err(progname, code, "when unparsing name"); - return 0; + com_err(progname, code, "when unparsing name"); + return 0; } opts->principal_name = k5->name; @@ -495,97 +592,97 @@ k5_end(k5) struct k5_data* k5; { if (k5->name) - krb5_free_unparsed_name(k5->ctx, k5->name); + krb5_free_unparsed_name(k5->ctx, k5->name); if (k5->me) - krb5_free_principal(k5->ctx, k5->me); + krb5_free_principal(k5->ctx, k5->me); if (k5->cc) - krb5_cc_close(k5->ctx, k5->cc); + krb5_cc_close(k5->ctx, k5->cc); if (k5->ctx) - krb5_free_context(k5->ctx); + krb5_free_context(k5->ctx); memset(k5, 0, sizeof(*k5)); } int k4_begin(opts, k4) struct k_opts* opts; - struct k4_data* k4; +struct k4_data* k4; { char* progname = progname_v4; int k_errno = 0; if (!got_k4) - return 0; + return 0; #ifdef KRB5_KRB4_COMPAT if (k4->aname[0]) - goto skip; + goto skip; if (opts->principal_name) { - /* Use specified name */ - if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, - opts->principal_name)) - { - fprintf(stderr, "%s: %s\n", progname, - krb_get_err_text(k_errno)); - return 0; - } + /* Use specified name */ + if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, + opts->principal_name)) + { + fprintf(stderr, "%s: %s\n", progname, + krb_get_err_text(k_errno)); + return 0; + } } else { - /* No principal name specified */ - if (opts->action == INIT_KT) { - /* Use the default host/service name */ - /* XXX - need to add this functionality */ - fprintf(stderr, "%s: Kerberos 4 srvtab support is not " - "implemented\n", progname); - return 0; - } else { - /* Get default principal from cache if one exists */ - if (k_errno = krb_get_tf_fullname(tkt_string(), k4->aname, - k4->inst, k4->realm)) - { - char *name = get_name_from_os(); - if (!name) - { - fprintf(stderr, "Unable to identify user\n"); - return 0; - } - if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, - name)) - { - fprintf(stderr, "%s: %s\n", progname, - krb_get_err_text(k_errno)); - return 0; - } - } - } + /* No principal name specified */ + if (opts->action == INIT_KT) { + /* Use the default host/service name */ + /* XXX - need to add this functionality */ + fprintf(stderr, "%s: Kerberos 4 srvtab support is not " + "implemented\n", progname); + return 0; + } else { + /* Get default principal from cache if one exists */ + if (k_errno = krb_get_tf_fullname(tkt_string(), k4->aname, + k4->inst, k4->realm)) + { + char *name = get_name_from_os(); + if (!name) + { + fprintf(stderr, "Unable to identify user\n"); + return 0; + } + if (k_errno = kname_parse(k4->aname, k4->inst, k4->realm, + name)) + { + fprintf(stderr, "%s: %s\n", progname, + krb_get_err_text(k_errno)); + return 0; + } + } + } } if (!k4->realm[0]) - krb_get_lrealm(k4->realm, 1); + krb_get_lrealm(k4->realm, 1); if (k4->inst[0]) - sprintf(k4->name, "%s.%s@%s", k4->aname, k4->inst, k4->realm); + sprintf(k4->name, "%s.%s@%s", k4->aname, k4->inst, k4->realm); else - sprintf(k4->name, "%s@%s", k4->aname, k4->realm); + sprintf(k4->name, "%s@%s", k4->aname, k4->realm); opts->principal_name = k4->name; skip: if (k4->aname[0] && !k_isname(k4->aname)) { fprintf(stderr, "%s: bad Kerberos 4 name format\n", progname); - return 0; + return 0; } if (k4->inst[0] && !k_isinst(k4->inst)) { - fprintf(stderr, "%s: bad Kerberos 4 instance format\n", progname); - return 0; + fprintf(stderr, "%s: bad Kerberos 4 instance format\n", progname); + return 0; } if (k4->realm[0] && !k_isrealm(k4->realm)) { - fprintf(stderr, "%s: bad Kerberos 4 realm format\n", progname); - return 0; + fprintf(stderr, "%s: bad Kerberos 4 realm format\n", progname); + return 0; } #endif /* KRB5_KRB4_COMPAT */ return 1; @@ -601,8 +698,8 @@ k4_end(k4) int k5_kinit(opts, k5, password) struct k_opts* opts; - struct k5_data* k5; - char* password; +struct k5_data* k5; +char* password; { char* progname = progname_v5; int notix = 1; @@ -612,7 +709,7 @@ k5_kinit(opts, k5, password) krb5_get_init_creds_opt options; if (!got_k5) - return 0; + return 0; krb5_get_init_creds_opt_init(&options); memset(&my_creds, 0, sizeof(my_creds)); @@ -639,8 +736,8 @@ k5_kinit(opts, k5, password) krb5_address **addresses = NULL; code = krb5_os_localaddr(k5->ctx, &addresses); if (code != 0) { - com_err(progname, code, "getting local addresses"); - goto cleanup; + com_err(progname, code, "getting local addresses"); + goto cleanup; } krb5_get_init_creds_opt_set_address_list(&options, addresses); krb5_free_addresses(k5->ctx, addresses); @@ -650,12 +747,12 @@ k5_kinit(opts, k5, password) if ((opts->action == INIT_KT) && opts->keytab_name) { - code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); - if (code != 0) { - com_err(progname, code, "resolving keytab %s", - opts->keytab_name); - goto cleanup; - } + code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab); + if (code != 0) { + com_err(progname, code, "resolving keytab %s", + opts->keytab_name); + goto cleanup; + } } switch (opts->action) { @@ -684,56 +781,56 @@ k5_kinit(opts, k5, password) } if (code) { - char *doing = 0; - switch (opts->action) { - case INIT_PW: - case INIT_KT: - doing = "getting initial credentials"; - break; - case VALIDATE: - doing = "validating credentials"; - break; - case RENEW: - doing = "renewing credentials"; - break; - } + char *doing = 0; + switch (opts->action) { + case INIT_PW: + case INIT_KT: + doing = "getting initial credentials"; + break; + case VALIDATE: + doing = "validating credentials"; + break; + case RENEW: + doing = "renewing credentials"; + break; + } /* If got code == KRB5_AP_ERR_V4_REPLY && got_k4, we should let the user know that maybe he/she wants -4. */ - if (code == KRB5KRB_AP_ERR_V4_REPLY && got_k4) - com_err(progname, code, "while %s\n" - "The KDC doesn't support v5. " - "You may want the -4 option in the future", - doing); - else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) - fprintf(stderr, "%s: Password incorrect while %s\n", progname, - doing); + if (code == KRB5KRB_AP_ERR_V4_REPLY && got_k4) + com_err(progname, code, "while %s\n" + "The KDC doesn't support v5. " + "You may want the -4 option in the future", + doing); + else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) + fprintf(stderr, "%s: Password incorrect while %s\n", progname, + doing); else - com_err(progname, code, "while %s", doing); - goto cleanup; + com_err(progname, code, "while %s", doing); + goto cleanup; } if (!opts->lifetime) { /* We need to figure out what lifetime to use for Kerberos 4. */ - opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; + opts->lifetime = my_creds.times.endtime - my_creds.times.authtime; } if (code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me)) { - com_err(progname, code, "when initializing cache %s", - opts->cache_name?opts->cache_name:""); - goto cleanup; + com_err(progname, code, "when initializing cache %s", + opts->k5_cache_name?opts->k5_cache_name:""); + goto cleanup; } if (code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds)) { - com_err(progname, code, "while storing credentials"); - goto cleanup; + com_err(progname, code, "while storing credentials"); + goto cleanup; } notix = 0; cleanup: if (my_creds.client == k5->me) { - my_creds.client = 0; + my_creds.client = 0; } krb5_free_cred_contents(k5->ctx, &my_creds); if (keytab) @@ -744,17 +841,17 @@ k5_kinit(opts, k5, password) int k4_kinit(opts, k4, password) struct k_opts* opts; - struct k4_data* k4; - char* password; +struct k4_data* k4; +char* password; { char* progname = progname_v4; int k_errno = 0; if (!got_k4) - return 0; + return 0; if (opts->starttime) - return 0; + return 0; #ifdef KRB5_KRB4_COMPAT if (!k4->lifetime) @@ -764,33 +861,35 @@ k4_kinit(opts, k4, password) k4->lifetime /= (5 * 60); if (k4->lifetime < 1) - k4->lifetime = 1; + k4->lifetime = 1; if (k4->lifetime > 255) - k4->lifetime = 255; + k4->lifetime = 255; switch (opts->action) { case INIT_PW: - k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt", - k4->realm, k4->lifetime, password); - - if (k_errno) { - fprintf(stderr, "%s: %s\n", progname, - krb_get_err_text(k_errno)); - if (authed_k5) - fprintf(stderr, "Maybe your KDC does not support v4. " - "Try the -5 option next time.\n"); - return 0; - } - return 1; + k_errno = krb_get_pw_in_tkt(k4->aname, k4->inst, k4->realm, "krbtgt", + k4->realm, k4->lifetime, password); + + if (k_errno) { +#ifndef HAVE_KRB524 + fprintf(stderr, "%s: %s\n", progname, + krb_get_err_text(k_errno)); + if (authed_k5) + fprintf(stderr, "Maybe your KDC does not support v4. " + "Try the -5 option next time.\n"); +#endif + return 0; + } + return 1; #ifndef HAVE_KRB524 case INIT_KT: - fprintf(stderr, "%s: srvtabs are not supported\n", progname); - return 0; + fprintf(stderr, "%s: srvtabs are not supported\n", progname); + return 0; case RENEW: - fprintf(stderr, "%s: renewal of krb4 tickets is not supported\n", - progname); - return 0; + fprintf(stderr, "%s: renewal of krb4 tickets is not supported\n", + progname); + return 0; #endif } #endif @@ -804,9 +903,9 @@ getvprogname(v) int len = strlen(progname) + 2 + strlen(v) + 2; char *ret = malloc(len); if (ret) - sprintf(ret, "%s(v%s)", progname, v); + sprintf(ret, "%s(v%s)", progname, v); else - ret = progname; + ret = progname; return ret; } @@ -879,13 +978,13 @@ int try_convert524(k5) } /* stash ticket, session key, etc. for future use */ if ((icode = krb_save_credentials(v4creds.service, - v4creds.instance, - v4creds.realm, - v4creds.session, - v4creds.lifetime, - v4creds.kvno, - &(v4creds.ticket_st), - v4creds.issue_date))) { + v4creds.instance, + v4creds.realm, + v4creds.session, + v4creds.lifetime, + v4creds.kvno, + &(v4creds.ticket_st), + v4creds.issue_date))) { com_err(progname, icode, "trying to save the V4 ticket"); goto cleanup; @@ -894,11 +993,11 @@ int try_convert524(k5) cleanup: memset(&v4creds, 0, sizeof(v4creds)); if (v5creds) - krb5_free_creds(k5->ctx, v5creds); + krb5_free_creds(k5->ctx, v5creds); increds.client = 0; krb5_free_cred_contents(k5->ctx, &increds); if (kpcserver) - krb5_free_principal(k5->ctx, kpcserver); + krb5_free_principal(k5->ctx, kpcserver); return !(code || icode); } #endif /* HAVE_KRB524 */ @@ -906,7 +1005,7 @@ int try_convert524(k5) int main(argc, argv) int argc; - char **argv; +char **argv; { struct k_opts opts; struct k5_data k5; @@ -920,12 +1019,16 @@ main(argc, argv) /* Ensure we can be driven from a pipe */ if(!isatty(fileno(stdin))) - setvbuf(stdin, 0, _IONBF, 0); + setvbuf(stdin, 0, _IONBF, 0); if(!isatty(fileno(stdout))) - setvbuf(stdout, 0, _IONBF, 0); + setvbuf(stdout, 0, _IONBF, 0); if(!isatty(fileno(stderr))) - setvbuf(stderr, 0, _IONBF, 0); + setvbuf(stderr, 0, _IONBF, 0); + /* + This is where we would put in code to dynamically load Kerberos + libraries. Currenlty, we just get them implicitly. + */ got_k5 = 1; #ifdef KRB5_KRB4_COMPAT got_k4 = 1; @@ -944,26 +1047,26 @@ main(argc, argv) if (opts.action == INIT_PW) { - char prompt[255]; - int pwsize = sizeof(password); - krb5_error_code code; - - sprintf(prompt, "Password for %s: ", opts.principal_name); - password[0] = 0; - /* - Note: krb5_read_password does not actually look at the - context, so we're ok even if we don't have a context. If - we cannot dynamically load krb5, we can substitute any - decent read password function instead of the krb5 one. - */ - code = krb5_read_password(k5.ctx, prompt, 0, password, &pwsize); - if (code || pwsize == 0) - { - fprintf(stderr, "Error while reading password for '%s'\n", - opts.principal_name); - memset(password, 0, sizeof(password)); - exit(1); - } + char prompt[255]; + int pwsize = sizeof(password); + krb5_error_code code; + + sprintf(prompt, "Password for %s: ", opts.principal_name); + password[0] = 0; + /* + Note: krb5_read_password does not actually look at the + context, so we're ok even if we don't have a context. If + we cannot dynamically load krb5, we can substitute any + decent read password function instead of the krb5 one. + */ + code = krb5_read_password(k5.ctx, prompt, 0, password, &pwsize); + if (code || pwsize == 0) + { + fprintf(stderr, "Error while reading password for '%s'\n", + opts.principal_name); + memset(password, 0, sizeof(password)); + exit(1); + } } authed_k5 = k5_kinit(&opts, &k5, password); @@ -976,14 +1079,14 @@ main(argc, argv) #endif if (authed_k5 && opts.verbose) - fprintf(stderr, "Authenticated to Kerberos v5\n"); + fprintf(stderr, "Authenticated to Kerberos v5\n"); if (authed_k4 && opts.verbose) - fprintf(stderr, "Authenticated to Kerberos v4\n"); + fprintf(stderr, "Authenticated to Kerberos v4\n"); k5_end(&k5); k4_end(&k4); if ((got_k5 && !authed_k5) || (got_k4 && !authed_k4)) - exit(1); + exit(1); return 0; }