s4:heimdal Allow KRB5_NT_ENTERPRISE names in all DB lookups
authorAndrew Bartlett <abartlet@samba.org>
Tue, 30 Jun 2009 02:11:14 +0000 (12:11 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 30 Jun 2009 02:11:14 +0000 (12:11 +1000)
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
source4/heimdal/kdc/misc.c
source4/heimdal/lib/hdb/hdb.h
source4/kdc/hdb-samba4.c
testprogs/blackbox/test_kinit.sh

index ac495b1ac7b318708ccc4c81b87f7732ddff655e..e364dcc1d1f5dba8dc6c1a67d00aefdb38e873e3 100644 (file)
@@ -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);
     }
index 8a53fc88278979279b3c7ec0b49792fcf9d0a525..247cb575de0eed7acfa16aa1e25d7ba7abadbcd3 100644 (file)
@@ -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)
index ce219153b34436015ab1fcf0dc068bd592e4c458..a5e6514e6c836bdd375052cb1b09e0ec70341c90 100644 (file)
@@ -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;
index 367eee5f14be0fed79c173c1d733da3abca16afe..7d731ab13d993e4b15fb8a3d8669309229250f6d 100644 (file)
@@ -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)) {
index 840002f51eaa37e6928635d8d493a3dc7191c063..2349afae7e0550a97fe4c962c6dc931a6bfffa1d 100755 (executable)
@@ -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