svn commit: lorikeet r270 - in trunk/heimdal: . lib/hdb

abartlet at samba.org abartlet at samba.org
Tue May 10 14:20:08 GMT 2005


Author: abartlet
Date: 2005-05-10 14:20:07 +0000 (Tue, 10 May 2005)
New Revision: 270

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

Log:
Implement the algorithm described by Luke Howard of PADL last
November, for the correct salting of prinipals in a AD-like realm.

Update my config.abartlet script to disabled shared libs, as these
break when placed alongside MIT.

Andrew Bartlett

Modified:
   trunk/heimdal/config.abartlet
   trunk/heimdal/lib/hdb/hdb-ldb.c


Changeset:
Modified: trunk/heimdal/config.abartlet
===================================================================
--- trunk/heimdal/config.abartlet	2005-05-10 09:14:44 UTC (rev 269)
+++ trunk/heimdal/config.abartlet	2005-05-10 14:20:07 UTC (rev 270)
@@ -1 +1 @@
-CFLAGS="-g -O -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Wdeclaration-after-statement" CC="ccache gcc" ./configure  --with-ldb=/usr/local --enable-shared --without-openssl
+CFLAGS="-g -O -Wall -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -Wdeclaration-after-statement" CC="ccache gcc" ./configure  --with-ldb=/usr/local --disable-shared --without-openssl

Modified: trunk/heimdal/lib/hdb/hdb-ldb.c
===================================================================
--- trunk/heimdal/lib/hdb/hdb-ldb.c	2005-05-10 09:14:44 UTC (rev 269)
+++ trunk/heimdal/lib/hdb/hdb-ldb.c	2005-05-10 14:20:07 UTC (rev 270)
@@ -44,9 +44,14 @@
 #include <ldb.h>
 #include <talloc.h>
 
+#include <ctype.h>
+
 #include "hdb-ldb.h"
 
+
+
 static const char * const krb5_attrs[] = {
+	"objectClass",
 	"cn",
 	"name",
 	"sAMAccountName",
@@ -211,12 +216,12 @@
 /*
  * Construct an hdb_entry from a directory entry.
  */
-static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, krb5_principal principal,
+static krb5_error_code LDB_message2entry(krb5_context context, HDB *db, 
+					 TALLOC_CTX *mem_ctx, krb5_principal principal,
 					 enum hdb_ent_type ent_type, struct ldb_message *realm_msg,
 					 struct ldb_message *msg,
 					 hdb_entry *ent)
 {
-	const char *unparsed_name = NULL;
 	const char *unicodePwd;
 	int userAccountControl;
 	int i;
@@ -231,8 +236,14 @@
 	
 	ent->principal = malloc(sizeof(*(ent->principal)));
 	if (ent_type == HDB_ENT_TYPE_ENUM) {
-		unparsed_name = ldb_msg_find_string(msg, "samAccountName", NULL);
-		krb5_make_principal(context, &ent->principal, realm, unparsed_name, NULL);
+		const char *samAccountName = ldb_msg_find_string(msg, "samAccountName", NULL);
+		if (!samAccountName) {
+			krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
+			ret = ENOENT;
+			goto out;
+		}
+		samAccountName = ldb_msg_find_string(msg, "samAccountName", NULL);
+		krb5_make_principal(context, &ent->principal, realm, samAccountName, NULL);
 	} else {
 		copy_Principal(principal, ent->principal);
 	}
@@ -278,12 +289,74 @@
 	/* create the keys and enctypes */
 	unicodePwd = ldb_msg_find_string(msg, "unicodePwd", NULL);
 	if (unicodePwd) {
-		/*
-		 * create keys from unicodePwd
-		 */
-		ret = hdb_generate_key_set_password(context, ent->principal, 
+		/* Many, many thanks to lukeh at padl.com for this
+		 * algorithm, described in his Nov 10 2004 mail to
+		 * samba-technical at samba.org */
+
+		Principal *salt_principal;
+		const char *user_principal_name = ldb_msg_find_string(msg, "userPrincipalName", NULL);
+		struct ldb_message_element *objectclasses;
+		struct ldb_val computer_val;
+		computer_val.data = "computer";
+		computer_val.length = strlen(computer_val.data);
+		
+		objectclasses = ldb_msg_find_element(msg, "objectClass");
+
+		if (objectclasses && ldb_msg_find_val(objectclasses, &computer_val)) {
+			/* Determine a salting principal */
+			char *samAccountName = talloc_strdup(mem_ctx, ldb_msg_find_string(msg, "samAccountName", NULL));
+			char *realm_lower = talloc_strdup(mem_ctx, realm);
+			char *saltbody;
+			int i;
+			if (!samAccountName) {
+				krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
+				ret = ENOENT;
+				goto out;
+			}
+			if (!realm_lower) {
+				krb5_set_error_string(context, "malloc: out of memory");
+				ret = ENOMEM;
+				goto out;
+			}
+			
+			/* TODO: Use Samba charset functions */
+			for (i=0; i< strlen(realm_lower); i++) {
+				realm_lower[i] = tolower(realm_lower[i]);
+			}
+			
+			if (samAccountName[strlen(samAccountName)-1] == '$') {
+				samAccountName[strlen(samAccountName)-1] = '\0';
+			}
+			saltbody = talloc_asprintf(mem_ctx, "%s.%s", samAccountName, realm_lower);
+			
+			ret = krb5_make_principal(context, &salt_principal, realm, "host", saltbody, NULL);
+		} else if (user_principal_name) {
+			char *p;
+			user_principal_name = talloc_strdup(mem_ctx, user_principal_name);
+			if (!user_principal_name) {
+				ret = ENOMEM;
+				goto out;
+			} else {
+				p = strchr(user_principal_name, '@');
+				if (p) {
+					p[0] = '\0';
+				}
+				ret = krb5_make_principal(context, &salt_principal, realm, user_principal_name, NULL);
+			} 
+		} else {
+			const char *samAccountName = ldb_msg_find_string(msg, "samAccountName", NULL);
+			ret = krb5_make_principal(context, &salt_principal, realm, samAccountName, NULL);
+		}
+
+		if (ret == 0) {
+			/*
+			 * create keys from unicodePwd
+			 */
+			ret = hdb_generate_key_set_password(context, salt_principal, 
 						    unicodePwd, 
-						    &ent->keys.val, &ent->keys.len);
+							    &ent->keys.val, &ent->keys.len);
+			krb5_free_principal(context, salt_principal);
+		}
 
 		if (ret != 0) {
 			krb5_warnx(context, "could not generate keys from unicodePwd\n");
@@ -567,7 +640,9 @@
 	if (ret != 0) {
 		krb5_warnx(context, "LDB_fetch: no principal found\n");
 	} else {
-		ret = LDB_message2entry(context, db, principal, ent_type, realm_msg[0], msg[0], entry);
+		ret = LDB_message2entry(context, db, mem_ctx, 
+					principal, ent_type, 
+					realm_msg[0], msg[0], entry);
 		if (ret != 0) {
 			krb5_warnx(context, "LDB_fetch: message2entry failed\n");	
 #if 0 /* master key support removed */
@@ -617,7 +692,9 @@
 	}
 
 	if (priv->index < priv->count) {
-		ret = LDB_message2entry(context, db, NULL, HDB_ENT_TYPE_ENUM, priv->realm_msgs[0], priv->msgs[priv->index++], entry);
+		ret = LDB_message2entry(context, db, mem_ctx, 
+					NULL, HDB_ENT_TYPE_ENUM, 
+					priv->realm_msgs[0], priv->msgs[priv->index++], entry);
 	} else {
 		ret = HDB_ERR_NOENTRY;
 	}



More information about the samba-cvs mailing list