svn commit: samba r21363 - in branches/SAMBA_4_0/source/kdc: .

metze at samba.org metze at samba.org
Thu Feb 15 12:56:49 GMT 2007


Author: metze
Date: 2007-02-15 12:56:46 +0000 (Thu, 15 Feb 2007)
New Revision: 21363

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21363

Log:
fallback to fetch the KEYTYPE_ARCFOUR out of the "unicodePwd" attribute
when no krb5key attribute is present or it doesn't contain the KEYTYPE_ARCFOUR
key.

metze
Modified:
   branches/SAMBA_4_0/source/kdc/hdb-ldb.c


Changeset:
Modified: branches/SAMBA_4_0/source/kdc/hdb-ldb.c
===================================================================
--- branches/SAMBA_4_0/source/kdc/hdb-ldb.c	2007-02-15 12:54:58 UTC (rev 21362)
+++ branches/SAMBA_4_0/source/kdc/hdb-ldb.c	2007-02-15 12:56:46 UTC (rev 21363)
@@ -58,8 +58,6 @@
 	"userPrincipalName",
 	"servicePrincipalName",
 
-	"krb5Key",
-
 	"userAccountControl",
 
 	"pwdLastSet",
@@ -69,6 +67,10 @@
 	"whenChanged",
 
 	"msDS-KeyVersionNumber",
+	"krb5Key",
+
+	"unicodePwd",
+
 	NULL
 };
 
@@ -196,63 +198,109 @@
 	talloc_free(entry_ex->ctx);
 }
 
-static krb5_error_code LDB_message2entry_keys(TALLOC_CTX *mem_ctx,
+static krb5_error_code LDB_message2entry_keys(krb5_context context,
+					      TALLOC_CTX *mem_ctx,
 					      struct ldb_message *msg,
 					      unsigned int userAccountControl,
 					      hdb_entry_ex *entry_ex)
 {
 	krb5_error_code ret = 0;
-	struct ldb_message_element *ldb_keys;
+	struct ldb_message_element *krb5keys;
+	struct samr_Password *hash;
 	int i;
+	bool arcfour_needed = true;
+	uint32_t allocated_keys = 0;
 
+	entry_ex->entry.keys.val = NULL;
+	entry_ex->entry.keys.len = 0;
+
 	/* Get krb5Key from the db */
 
-	ldb_keys = ldb_msg_find_element(msg, "krb5Key");
+	krb5keys = ldb_msg_find_element(msg, "krb5Key");
+	hash = samdb_result_hash(mem_ctx, msg, "unicodePwd");
 
-	if (!ldb_keys) {
+	if (krb5keys) {
+		allocated_keys = krb5keys->num_values;
+	}
+
+	if (hash) {
+		allocated_keys++;
+	}
+
+	if (allocated_keys == 0) {
 		/* oh, no password.  Apparently (comment in
 		 * hdb-ldap.c) this violates the ASN.1, but this
 		 * allows an entry with no keys (yet). */
-		entry_ex->entry.keys.val = NULL;
-		entry_ex->entry.keys.len = 0;
-	} else {
-		/* allocate space to decode into */
-		entry_ex->entry.keys.val = calloc(ldb_keys->num_values, sizeof(Key));
-		if (entry_ex->entry.keys.val == NULL) {
-			ret = ENOMEM;
+		return 0;
+	}
+
+	/* allocate space to decode into */
+	entry_ex->entry.keys.len = 0;
+	entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key));
+	if (entry_ex->entry.keys.val == NULL) {
+		ret = ENOMEM;
+		goto out;
+	}
+
+	/* Decode Kerberos keys into the hdb structure */
+	for (i=0; (krb5keys && i < krb5keys->num_values); i++) {
+		size_t decode_len;
+		Key key;
+		ret = decode_Key(krb5keys->values[i].data, krb5keys->values[i].length, 
+				 &key, &decode_len);
+		if (ret) {
+			/* Could be bougus data in the entry, or out of memory */
 			goto out;
 		}
 
-		entry_ex->entry.keys.len = 0;
-
-		/* Decode Kerberos keys into the hdb structure */
-		for (i=0; i < ldb_keys->num_values; i++) {
-			size_t decode_len;
-			Key key;
-			ret = decode_Key(ldb_keys->values[i].data, ldb_keys->values[i].length, 
-					 &key, &decode_len);
-			if (ret) {
-				/* Could be bougus data in the entry, or out of memory */
-				goto out;
-			}
-
-			if (userAccountControl & UF_USE_DES_KEY_ONLY) {
-				switch (key.key.keytype) {
-				case KEYTYPE_DES:
-					entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
-					entry_ex->entry.keys.len++;
-				default:
-					/* We must use DES keys only */
-					break;
-				}
-			} else {
+		if (userAccountControl & UF_USE_DES_KEY_ONLY) {
+			switch (key.key.keytype) {
+			case KEYTYPE_DES:
+				arcfour_needed = false;
 				entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
 				entry_ex->entry.keys.len++;
+				break;
+			default:
+				/* We must use DES keys only */
+				break;
 			}
+		} else {
+			switch (key.key.keytype) {
+			case KEYTYPE_ARCFOUR:
+				arcfour_needed = false;
+				break;
+			default:
+				break;
+			}
+			entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+			entry_ex->entry.keys.len++;
 		}
-	} 
+	}
 
+	if (arcfour_needed && hash) {
+		Key key;
+
+		key.mkvno = 0;
+		key.salt = NULL; /* No salt for this enc type */
+
+		ret = krb5_keyblock_init(context,
+					 KEYTYPE_ARCFOUR,
+					 hash->hash, sizeof(hash->hash), 
+					 &key.key);
+		if (ret) {
+			goto out;
+		}
+
+		entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+		entry_ex->entry.keys.len++;
+	}
+
 out:
+	if (ret != 0 && entry_ex->entry.keys.val) {
+		free(entry_ex->entry.keys.val);
+		entry_ex->entry.keys.val = NULL;
+		entry_ex->entry.keys.len = 0;
+	}
 	return ret;
 }
 
@@ -425,7 +473,7 @@
 	entry_ex->entry.generation = NULL;
 
 	/* Get keys from the db */
-	ret = LDB_message2entry_keys(mem_ctx, msg, userAccountControl, entry_ex);
+	ret = LDB_message2entry_keys(context, private, msg, userAccountControl, entry_ex);
 	if (ret) {
 		/* Could be bougus data in the entry, or out of memory */
 		goto out;



More information about the samba-cvs mailing list