diff options
Diffstat (limited to 'source4/heimdal/kuser')
-rw-r--r-- | source4/heimdal/kuser/kinit.c | 221 | ||||
-rw-r--r-- | source4/heimdal/kuser/kuser_locl.h | 5 |
2 files changed, 70 insertions, 156 deletions
diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index 667e0963b0..29a9bdd5c7 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -32,11 +32,9 @@ */ #include "kuser_locl.h" -RCSID("$Id: kinit.c,v 1.141 2006/12/12 16:35:41 lha Exp $"); +RCSID("$Id: kinit.c 20517 2007-04-22 10:42:26Z lha $"); -#ifndef KRB4 #include "krb5-v4compat.h" -#endif struct krb5_pk_identity; struct krb5_pk_cert; @@ -46,6 +44,7 @@ struct krb5_dh_moduli; struct krb5_plugin; enum plugin_type; #include "krb5-private.h" +#include "heimntlm.h" int forwardable_flag = -1; int proxiable_flag = -1; @@ -74,6 +73,8 @@ char *password_file = NULL; char *pk_user_id = NULL; char *pk_x509_anchors = NULL; int pk_use_enckey = 0; +static int canonicalize_flag = 0; +static char *ntlm_domain; static char *krb4_cc_name; @@ -153,18 +154,21 @@ static struct getargs args[] = { { "password-file", 0, arg_string, &password_file, "read the password from a file" }, + { "canonicalize",0, arg_flag, &canonicalize_flag, + "canonicalize client principal" }, #ifdef PKINIT - { "pk-user", 'C', arg_string, &pk_user_id, - "principal's public/private/certificate identifier", - "id" }, - - { "x509-anchors", 'D', arg_string, &pk_x509_anchors, - "directory with CA certificates", "directory" }, + { "pk-user", 'C', arg_string, &pk_user_id, + "principal's public/private/certificate identifier", "id" }, - { "pk-use-enckey", 0, arg_flag, &pk_use_enckey, - "Use RSA encrypted reply (instead of DH)" }, + { "x509-anchors", 'D', arg_string, &pk_x509_anchors, + "directory with CA certificates", "directory" }, + { "pk-use-enckey", 0, arg_flag, &pk_use_enckey, + "Use RSA encrypted reply (instead of DH)" }, #endif + { "ntlm-domain", 0, arg_string, &ntlm_domain, + "NTLM domain", "domain" }, + { "version", 0, arg_flag, &version_flag }, { "help", 0, arg_flag, &help_flag } }; @@ -179,130 +183,6 @@ usage (int ret) exit (ret); } -#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, - const char *passwd) -{ - 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_tkt(princ.name, princ.instance, princ.realm, - KRB_TICKET_GRANTING_TICKET, princ.realm, - lifetime, passwd); - } - memset (key, 0, sizeof(key)); - if (ret) { - warnx ("%s", krb_get_err_text(ret)); - return 1; - } - if (do_afslog && 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 */ - static krb5_error_code get_server(krb5_context context, krb5_principal client, @@ -457,6 +337,39 @@ out: } static krb5_error_code +store_ntlmkey(krb5_context context, krb5_ccache id, + const char *domain, krb5_const_principal client, + struct ntlm_buf *buf) +{ + krb5_error_code ret; + krb5_creds cred; + + memset(&cred, 0, sizeof(cred)); + + ret = krb5_make_principal(context, &cred.server, + krb5_principal_get_realm(context, client), + "@ntlm-key", domain, NULL); + if (ret) + goto out; + ret = krb5_copy_principal(context, client, &cred.client); + if (ret) + goto out; + + cred.times.authtime = time(NULL); + cred.times.endtime = time(NULL) + 3600 * 24 * 30; /* XXX */ + cred.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5; + ret = krb5_data_copy(&cred.session.keyvalue, buf->data, buf->length); + if (ret) + goto out; + + ret = krb5_cc_store_cred(context, id, &cred); + +out: + krb5_free_cred_contents (context, &cred); + return 0; +} + +static krb5_error_code get_new_tickets(krb5_context context, krb5_principal principal, krb5_ccache ccache, @@ -471,7 +384,9 @@ get_new_tickets(krb5_context context, krb5_deltat renew = 0; char *renewstr = NULL; krb5_enctype *enctype = NULL; + struct ntlm_buf ntlmkey; + memset(&ntlmkey, 0, sizeof(ntlmkey)); passwd[0] = '\0'; if (password_file) { @@ -500,8 +415,8 @@ get_new_tickets(krb5_context context, if (ret) krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc"); - krb5_get_init_creds_opt_set_default_flags(context, "kinit", - /* XXX */principal->realm, opt); + krb5_get_init_creds_opt_set_default_flags(context, "kinit", + krb5_principal_get_realm(context, principal), opt); if(forwardable_flag != -1) krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag); @@ -512,6 +427,8 @@ get_new_tickets(krb5_context context, if (pac_flag != -1) krb5_get_init_creds_opt_set_pac_request(context, opt, pac_flag ? TRUE : FALSE); + if (canonicalize_flag) + krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE); if (pk_user_id) { ret = krb5_get_init_creds_opt_set_pkinit(context, opt, principal, @@ -629,19 +546,8 @@ get_new_tickets(krb5_context context, opt); } krb5_get_init_creds_opt_free(context, 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); - get_v4_tgt = 0; - do_afslog = 0; - memset(passwd, 0, sizeof(passwd)); - if (exit_val == 0 || ret == KRB5KRB_AP_ERR_V4_REPLY) - return exit_val; - } -#endif + if (ntlm_domain && passwd[0]) + heim_ntlm_nt_key(passwd, &ntlmkey); memset(passwd, 0, sizeof(passwd)); switch(ret){ @@ -651,8 +557,12 @@ get_new_tickets(krb5_context context, exit(1); case KRB5KRB_AP_ERR_BAD_INTEGRITY: case KRB5KRB_AP_ERR_MODIFIED: + case KRB5KDC_ERR_PREAUTH_FAILED: krb5_errx(context, 1, "Password incorrect"); break; + case KRB5KRB_AP_ERR_V4_REPLY: + krb5_errx(context, 1, "Looks like a Kerberos 4 reply"); + break; default: krb5_err(context, 1, ret, "krb5_get_init_creds"); } @@ -685,6 +595,9 @@ get_new_tickets(krb5_context context, krb5_free_cred_contents (context, &cred); + if (ntlm_domain && ntlmkey.data) + store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey); + if (enctype) free(enctype); @@ -774,6 +687,7 @@ main (int argc, char **argv) krb5_principal principal; int optidx = 0; krb5_deltat ticket_life = 0; + int parseflags = 0; setprogname (argv[0]); @@ -797,12 +711,15 @@ main (int argc, char **argv) argc -= optidx; argv += optidx; + if (canonicalize_flag) + parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE; + if (argv[0]) { - ret = krb5_parse_name (context, argv[0], &principal); + ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal); if (ret) krb5_err (context, 1, ret, "krb5_parse_name"); } else { - ret = kinit_get_default_principal (context, &principal); + ret = krb5_get_default_principal (context, &principal); if (ret) krb5_err (context, 1, ret, "krb5_get_default_principal"); } diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h index 06403cbe67..36ea01a9a5 100644 --- a/source4/heimdal/kuser/kuser_locl.h +++ b/source4/heimdal/kuser/kuser_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: kuser_locl.h,v 1.13 2003/01/21 14:13:51 nectar Exp $ */ +/* $Id: kuser_locl.h 20458 2007-04-19 20:41:27Z lha $ */ #ifndef __KUSER_LOCL_H__ #define __KUSER_LOCL_H__ @@ -75,9 +75,6 @@ #include <err.h> #include <krb5.h> -#ifdef KRB4 -#include <krb.h> -#endif #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include <sys/ioctl.h> #endif |