From 89a074b784295204aa8d7dd585bf3533ac7971a7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Jun 2009 12:11:14 +1000 Subject: [PATCH] s4:heimdal Allow KRB5_NT_ENTERPRISE names in all DB lookups The previous code only allowed an KRB5_NT_ENTERPRISE name (an e-mail list user principal name) in an AS-REQ. Evidence from the wild (Win2k8 reportadely) indicates that this is instead valid for all types of requests. While this is now handled in heimdal/kdc/misc.c, a flag is now defined in Heimdal's hdb so that we can take over this handling in future (once we start using a system Heimdal, and if we find out there is more to be done here). Andrew Bartlett --- source4/heimdal/kdc/kerberos5.c | 28 ++++++---------------------- source4/heimdal/kdc/misc.c | 22 ++++++++++++++++++++++ source4/heimdal/lib/hdb/hdb.h | 6 ++++-- source4/kdc/hdb-samba4.c | 1 + testprogs/blackbox/test_kinit.sh | 2 ++ 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index ac495b1..e364dcc 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -925,28 +925,12 @@ _kdc_as_rep(krb5_context context, ret = KRB5KRB_ERR_GENERIC; e_text = "No client in request"; } else { - - if (b->cname->name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { - if (b->cname->name_string.len != 1) { - kdc_log(context, config, 0, - "AS-REQ malformed canon request from %s, " - "enterprise name with %d name components", - from, b->cname->name_string.len); - ret = KRB5_PARSE_MALFORMED; - goto out; - } - ret = krb5_parse_name(context, b->cname->name_string.val[0], - &client_princ); - if (ret) - goto out; - } else { - ret = _krb5_principalname2krb5_principal (context, - &client_princ, - *(b->cname), - b->realm); - if (ret) - goto out; - } + ret = _krb5_principalname2krb5_principal (context, + &client_princ, + *(b->cname), + b->realm); + if (ret) + goto out; ret = krb5_unparse_name(context, client_princ, &client_name); } diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index 8a53fc8..247cb57 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -56,17 +56,39 @@ _kdc_db_fetch(krb5_context context, } for(i = 0; i < config->num_db; i++) { + krb5_principal enterprise_principal = NULL; + if (!(config->db[i]->hdb_capability_flags & HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL) + && principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { + if (principal->name.name_string.len != 1) { + ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "malformed request: " + "enterprise name with %d name components", + principal->name.name_string.len); + return ret; + } + ret = krb5_parse_name(context, principal->name.name_string.val[0], + &enterprise_principal); + if (ret) + return ret; + + principal = enterprise_principal; + } + ret = config->db[i]->hdb_open(context, config->db[i], O_RDONLY, 0); if (ret) { kdc_log(context, config, 0, "Failed to open database: %s", krb5_get_err_text(context, ret)); continue; } + ret = config->db[i]->hdb_fetch(context, config->db[i], principal, flags | HDB_F_DECRYPT, ent); + krb5_free_principal(context, enterprise_principal); + config->db[i]->hdb_close(context, config->db[i]); if(ret == 0) { if (db) diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index ce21915..a5e6514 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -54,6 +54,8 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ #define HDB_F_CANON 32 /* want canonicalition */ +#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 + /* key usage for master key */ #define HDB_KU_MKEY 0x484442 @@ -80,7 +82,7 @@ typedef struct HDB{ int hdb_master_key_set; hdb_master_key hdb_master_key; int hdb_openp; - + int hdb_capability_flags; /** * Open (or create) the a Kerberos database. * @@ -184,7 +186,7 @@ typedef struct HDB{ krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*); }HDB; -#define HDB_INTERFACE_VERSION 4 +#define HDB_INTERFACE_VERSION 5 struct hdb_so_method { int version; diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c index 367eee5..7d731ab 100644 --- a/source4/kdc/hdb-samba4.c +++ b/source4/kdc/hdb-samba4.c @@ -1425,6 +1425,7 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx, (*db)->hdb_master_key_set = 0; (*db)->hdb_db = NULL; + (*db)->hdb_capability_flags = 0; nt_status = auth_system_session_info(*db, lp_ctx, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/testprogs/blackbox/test_kinit.sh b/testprogs/blackbox/test_kinit.sh index 840002f..2349afa 100755 --- a/testprogs/blackbox/test_kinit.sh +++ b/testprogs/blackbox/test_kinit.sh @@ -51,6 +51,8 @@ export KRB5CCNAME echo $PASSWORD > ./tmppassfile #testit "kinit with keytab" $samba4kinit --keytab=$PREFIX/dc/private/secrets.keytab $SERVER\$@$REALM || failed=`expr $failed + 1` testit "kinit with password" $samba4kinit --password-file=./tmppassfile --request-pac $USERNAME@$REALM || failed=`expr $failed + 1` +testit "kinit with password (enterprise style)" $samba4kinit --enterprise --password-file=./tmppassfile --request-pac $USERNAME@$REALM || failed=`expr $failed + 1` +testit "kinit with password (windows style)" $samba4kinit --windows --password-file=./tmppassfile --request-pac $USERNAME@$REALM || failed=`expr $failed + 1` testit "kinit with pkinit" $samba4kinit --request-pac --renewable --pk-user=FILE:$PREFIX/dc/private/tls/admincert.pem,$PREFIX/dc/private/tls/adminkey.pem $USERNAME@$REALM || failed=`expr $failed + 1` testit "kinit renew ticket" $samba4kinit --request-pac -R -- 1.6.0.6