summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/kuser/kinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/kuser/kinit.c')
-rw-r--r--crypto/heimdal/kuser/kinit.c265
1 files changed, 226 insertions, 39 deletions
diff --git a/crypto/heimdal/kuser/kinit.c b/crypto/heimdal/kuser/kinit.c
index 35b493a..be2857c 100644
--- a/crypto/heimdal/kuser/kinit.c
+++ b/crypto/heimdal/kuser/kinit.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -32,16 +32,142 @@
*/
#include "kuser_locl.h"
-RCSID("$Id: kinit.c,v 1.60 2000/02/01 14:06:33 joda Exp $");
+RCSID("$Id: kinit.c,v 1.69 2001/01/05 16:32:55 joda Exp $");
-int forwardable = 0;
-int proxiable = 0;
-int renewable = 0;
+#ifdef KRB4
+/* for when the KDC tells us it's a v4 one, we try to talk that */
+
+static int
+key_to_key(const char *user,
+ char *instance,
+ const char *realm,
+ const void *arg,
+ des_cblock *key)
+{
+ memcpy(key, arg, sizeof(des_cblock));
+ return 0;
+}
+
+static int
+do_v4_fallback (krb5_context context,
+ const krb5_principal principal,
+ int lifetime,
+ int use_srvtab, const char *srvtab_str,
+ char *passwd, size_t passwd_size)
+{
+ int ret;
+ krb_principal princ;
+ des_cblock key;
+ krb5_error_code kret;
+
+ if (lifetime == 0)
+ lifetime = DEFAULT_TKT_LIFE;
+ else
+ lifetime = krb_time_to_life (0, lifetime);
+
+ kret = krb5_524_conv_principal (context, principal,
+ princ.name,
+ princ.instance,
+ princ.realm);
+ if (kret) {
+ krb5_warn (context, kret, "krb5_524_conv_principal");
+ return 1;
+ }
+
+ if (use_srvtab || srvtab_str) {
+ if (srvtab_str == NULL)
+ srvtab_str = KEYFILE;
+
+ ret = read_service_key (princ.name, princ.instance, princ.realm,
+ 0, srvtab_str, (char *)&key);
+ if (ret) {
+ warnx ("read_service_key %s: %s", srvtab_str,
+ krb_get_err_text (ret));
+ return 1;
+ }
+ ret = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET, princ.realm,
+ lifetime, key_to_key, NULL, key);
+ } else {
+ ret = krb_get_pw_in_tkt2(princ.name, princ.instance, princ.realm,
+ KRB_TICKET_GRANTING_TICKET, princ.realm,
+ lifetime, passwd, &key);
+ }
+ memset (passwd, 0, passwd_size);
+ memset (key, 0, sizeof(key));
+ if (ret) {
+ warnx ("%s", krb_get_err_text(ret));
+ return 1;
+ }
+ if (k_hasafs()) {
+ if ((ret = krb_afslog(NULL, NULL)) != 0 && ret != KDC_PR_UNKNOWN) {
+ if(ret > 0)
+ warnx ("%s", krb_get_err_text(ret));
+ else
+ warnx ("failed to store AFS token");
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * the special version of get_default_principal that takes v4 into account
+ */
+
+static krb5_error_code
+kinit_get_default_principal (krb5_context context,
+ krb5_principal *princ)
+{
+ krb5_error_code ret;
+ krb5_ccache id;
+ krb_principal v4_princ;
+ int kret;
+
+ ret = krb5_cc_default (context, &id);
+ if (ret == 0) {
+ ret = krb5_cc_get_principal (context, id, princ);
+ krb5_cc_close (context, id);
+ if (ret == 0)
+ return 0;
+ }
+
+ kret = krb_get_tf_fullname (tkt_string(),
+ v4_princ.name,
+ v4_princ.instance,
+ v4_princ.realm);
+ if (kret == KSUCCESS) {
+ ret = krb5_425_conv_principal (context,
+ v4_princ.name,
+ v4_princ.instance,
+ v4_princ.realm,
+ princ);
+ if (ret == 0)
+ return 0;
+ }
+ return krb5_get_default_principal (context, princ);
+}
+
+#else /* !KRB4 */
+
+static krb5_error_code
+kinit_get_default_principal (krb5_context context,
+ krb5_principal *princ)
+{
+ return krb5_get_default_principal (context, princ);
+}
+
+#endif /* !KRB4 */
+
+int forwardable_flag = -1;
+int proxiable_flag = -1;
+int renewable_flag = -1;
int renew_flag = 0;
int validate_flag = 0;
int version_flag = 0;
int help_flag = 0;
int addrs_flag = 1;
+int anonymous_flag = 0;
char *lifetime = NULL;
char *renew_life = NULL;
char *server = NULL;
@@ -56,7 +182,7 @@ extern int get_v4_tgt;
#endif
int fcache_version;
-struct getargs args[] = {
+static struct getargs args[] = {
#ifdef KRB4
{ "524init", '4', arg_flag, &get_v4_tgt,
"obtain version 4 TGT" },
@@ -67,32 +193,32 @@ struct getargs args[] = {
{ "cache", 'c', arg_string, &cred_cache,
"credentials cache", "cachename" },
- { "forwardable", 'f', arg_flag, &forwardable,
+ { "forwardable", 'f', arg_flag, &forwardable_flag,
"get forwardable tickets"},
{ "keytab", 't', arg_string, &keytab_str,
"keytab to use", "keytabname" },
{ "lifetime", 'l', arg_string, &lifetime,
- "lifetime of tickets", "seconds"},
+ "lifetime of tickets", "time"},
- { "proxiable", 'p', arg_flag, &proxiable,
+ { "proxiable", 'p', arg_flag, &proxiable_flag,
"get proxiable tickets" },
{ "renew", 'R', arg_flag, &renew_flag,
"renew TGT" },
- { "renewable", 0, arg_flag, &renewable,
+ { "renewable", 0, arg_flag, &renewable_flag,
"get renewable tickets" },
{ "renewable-life", 'r', arg_string, &renew_life,
- "renewable lifetime of tickets", "seconds" },
+ "renewable lifetime of tickets", "time" },
{ "server", 'S', arg_string, &server,
"server to get ticket for", "principal" },
{ "start-time", 's', arg_string, &start_str,
- "when ticket gets valid", "seconds" },
+ "when ticket gets valid", "time" },
{ "use-keytab", 'k', arg_flag, &use_keytab,
"get key from keytab" },
@@ -101,7 +227,7 @@ struct getargs args[] = {
"validate TGT" },
{ "enctypes", 'e', arg_strings, &etype_str,
- "encryption type to use", "enctype" },
+ "encryption types to use", "enctypes" },
{ "fcache-version", 0, arg_integer, &fcache_version,
"file cache version to create" },
@@ -109,6 +235,9 @@ struct getargs args[] = {
{ "addresses", 0, arg_negative_flag, &addrs_flag,
"request a ticket with no addresses" },
+ { "anonymous", 0, arg_flag, &anonymous_flag,
+ "request an anonymous ticket" },
+
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@@ -159,10 +288,11 @@ renew_validate(krb5_context context,
}
}
flags.i = 0;
- flags.b.renewable = flags.b.renew = renew;
- flags.b.validate = validate;
- flags.b.forwardable = forwardable;
- flags.b.proxiable = proxiable;
+ flags.b.renewable = flags.b.renew = renew;
+ flags.b.validate = validate;
+ flags.b.forwardable = forwardable_flag;
+ flags.b.proxiable = proxiable_flag;
+ flags.b.request_anonymous = anonymous_flag;
if(life)
in.times.endtime = time(NULL) + life;
@@ -207,18 +337,22 @@ main (int argc, char **argv)
krb5_deltat start_time = 0;
krb5_deltat ticket_life = 0;
krb5_addresses no_addrs;
+ char passwd[256];
set_progname (argv[0]);
memset(&cred, 0, sizeof(cred));
ret = krb5_init_context (&context);
if (ret)
- errx(1, "krb5_init_context failed: %u", ret);
+ errx(1, "krb5_init_context failed: %d", ret);
- forwardable = krb5_config_get_bool (context, NULL,
- "libdefaults",
- "forwardable",
- NULL);
+ /* XXX no way to figure out if set without explict test */
+ if(krb5_config_get_string(context, NULL, "libdefaults",
+ "forwardable", NULL))
+ forwardable_flag = krb5_config_get_bool (context, NULL,
+ "libdefaults",
+ "forwardable",
+ NULL);
#ifdef KRB4
get_v4_tgt = krb5_config_get_bool_default (context, NULL,
@@ -239,6 +373,22 @@ main (int argc, char **argv)
exit(0);
}
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1)
+ usage (1);
+
+ if (argv[0]) {
+ ret = krb5_parse_name (context, argv[0], &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name");
+ } else {
+ ret = kinit_get_default_principal (context, &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_default_principal");
+ }
+
if(fcache_version)
krb5_set_fcache_version(context, fcache_version);
@@ -264,8 +414,15 @@ main (int argc, char **argv)
krb5_get_init_creds_opt_init (&opt);
- krb5_get_init_creds_opt_set_forwardable (&opt, forwardable);
- krb5_get_init_creds_opt_set_proxiable (&opt, proxiable);
+ krb5_get_init_creds_opt_set_default_flags(context, "kinit",
+ /* XXX */principal->realm, &opt);
+
+ if(forwardable_flag != -1)
+ krb5_get_init_creds_opt_set_forwardable (&opt, forwardable_flag);
+ if(proxiable_flag != -1)
+ krb5_get_init_creds_opt_set_proxiable (&opt, proxiable_flag);
+ if(anonymous_flag != -1)
+ krb5_get_init_creds_opt_set_anonymous (&opt, anonymous_flag);
if (!addrs_flag) {
no_addrs.len = 0;
@@ -280,7 +437,7 @@ main (int argc, char **argv)
errx (1, "unparsable time: %s", renew_life);
krb5_get_init_creds_opt_set_renew_life (&opt, tmp);
- } else if (renewable)
+ } else if (renewable_flag)
krb5_get_init_creds_opt_set_renew_life (&opt, 1 << 30);
if(ticket_life != 0)
@@ -311,18 +468,16 @@ main (int argc, char **argv)
etype_str.num_strings);
}
- argc -= optind;
- argv += optind;
-
- if (argc > 1)
- usage (1);
-
- if (argv[0]) {
- ret = krb5_parse_name (context, argv[0], &principal);
- if (ret)
- krb5_err (context, 1, ret, "krb5_parse_name");
- } else
- principal = NULL;
+#ifdef KRB4
+ get_v4_tgt = krb5_config_get_bool_default (context,
+ NULL,
+ get_v4_tgt,
+ "realms",
+ krb5_princ_realm(context,
+ principal),
+ "krb4_get_tickets",
+ NULL);
+#endif
if(use_keytab || keytab_str) {
krb5_keytab kt;
@@ -340,23 +495,55 @@ main (int argc, char **argv)
server,
&opt);
krb5_kt_close(context, kt);
- } else
+ } else {
+ char *p, *prompt;
+
+ krb5_unparse_name (context, principal, &p);
+ asprintf (&prompt, "%s's Password: ", p);
+ free (p);
+
+ if (des_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
+ memset(passwd, 0, sizeof(passwd));
+ exit(1);
+ }
+
+ free (prompt);
+
ret = krb5_get_init_creds_password (context,
&cred,
principal,
- NULL,
+ passwd,
krb5_prompter_posix,
NULL,
start_time,
server,
&opt);
+ }
+#ifdef KRB4
+ if (ret == KRB5KRB_AP_ERR_V4_REPLY || ret == KRB5_KDC_UNREACH) {
+ int exit_val;
+
+ exit_val = do_v4_fallback (context, principal, ticket_life,
+ use_keytab, keytab_str,
+ passwd, sizeof(passwd));
+ memset(passwd, 0, sizeof(passwd));
+ if (exit_val == 0 || ret == KRB5KRB_AP_ERR_V4_REPLY) {
+ krb5_free_context (context);
+ return exit_val;
+ }
+ }
+#endif
+ memset(passwd, 0, sizeof(passwd));
+
switch(ret){
case 0:
break;
case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
+ memset(passwd, 0, sizeof(passwd));
exit(1);
case KRB5KRB_AP_ERR_BAD_INTEGRITY:
case KRB5KRB_AP_ERR_MODIFIED:
+ memset(passwd, 0, sizeof(passwd));
krb5_errx(context, 1, "Password incorrect");
break;
default:
OpenPOWER on IntegriCloud