[Date Prev][Date Next] [Chronological] [Thread] [Top]

openldap-nsmta-head.txt (fwd)



Netscape's Directory server, Post.Office, QLDAP, freeradius,
CommunigatePro, and  probably some others... support
passwords stored in the "ns-mta-md5" format.

I have seen several requests to migrate from one of these to OpenLDAP,
but with the caviate that the passwords were in ns-mta-md5 format.

I have included an example patch that I found with a Google search.

What I would like to ask is would this be a reasonable compile time
"option" to support for those moving to openldap from legacy servers?

If approved for inclusion, I can get you an updated "tested" patch
against a current release... if you would like.

Thank you,
Randall

Copyright 2001, John Morrissey (jwm at horde dot net), All rights reserved.
This is free software; you can redistribute and use it under the same terms
as OpenLDAP itself.

Index: libraries/liblutil/passwd.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/libraries/liblutil/passwd.c,v
retrieving revision 1.58
diff -u -u -r1.58 passwd.c
--- libraries/liblutil/passwd.c	2001/12/17 21:42:56	1.58
+++ libraries/liblutil/passwd.c	2001/12/20 20:46:01
@@ -97,6 +97,11 @@
 	const struct berval *passwd,
 	const struct berval *cred );
 
+static int chk_nsmta(
+	const struct pw_scheme *scheme,
+	const struct berval *passwd,
+	const struct berval *cred );
+
 #ifdef LUTIL_SHA1_BYTES
 static int chk_ssha1(
 	const struct pw_scheme *scheme,
@@ -184,8 +189,9 @@
 	{ {sizeof("{SHA}")-1, "{SHA}"},		chk_sha1, hash_sha1 },
 #endif
 
-	{ {sizeof("{SMD5}")-1, "{SMD5}"},	chk_smd5, hash_smd5 },
-	{ {sizeof("{MD5}")-1, "{MD5}"},		chk_md5, hash_md5 },
+	{ {sizeof("{SMD5}")-1, "{SMD5}"},		chk_smd5,  hash_smd5 },
+	{ {sizeof("{MD5}")-1, "{MD5}"},			chk_md5,   hash_md5 },
+	{ {sizeof("{NS-MTA-MD5}")-1, "{NS-MTA-MD5}"},	chk_nsmta, NULL },
 
 #ifdef SLAPD_LMHASH
 	{ {sizeof("{LANMAN}")-1, "{LANMAN}"},	chk_lanman, hash_lanman },
@@ -606,6 +612,58 @@
 	/* compare */
 	rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
 	ber_memfree(orig_pass);
+	return rc ? 1 : 0;
+}
+
+static void ns_mta_hexify(
+	char * buffer,
+	char * str,
+	int len)
+{
+	char *ns_mta_hextab = "0123456789abcdef";
+	int i;
+
+	for (i = 0; i < len; ++i) {
+		buffer[2*i]   = ns_mta_hextab[(str[i] >> 4) & 0xF];
+		buffer[2*i+1] = ns_mta_hextab[str[i] & 0xF];
+	}
+}
+
+static int chk_nsmta(
+	const struct pw_scheme *sc,
+	const struct berval * passwd,
+	const struct berval * cred )
+{
+	lutil_MD5_CTX MD5context;
+	unsigned char MD5digest[LUTIL_MD5_BYTES], c;
+	char buffer[2 * LUTIL_MD5_BYTES];
+	int rc;
+
+	/* hash credentials with salt */
+	lutil_MD5Init(&MD5context);
+	lutil_MD5Update(&MD5context,
+		(const unsigned char *) passwd->bv_val + 32,
+		32 );
+	c = 89;
+	lutil_MD5Update(&MD5context,
+		(const unsigned char *) &c,
+		1 );
+	lutil_MD5Update(&MD5context,
+		(const unsigned char *) cred->bv_val,
+		cred->bv_len );
+	c = 247;
+	lutil_MD5Update(&MD5context,
+		(const unsigned char *) &c,
+		1 );
+	lutil_MD5Update(&MD5context,
+		(const unsigned char *) passwd->bv_val + 32,
+		32 );
+	lutil_MD5Final(MD5digest, &MD5context);
+
+	ns_mta_hexify(buffer, MD5digest, LUTIL_MD5_BYTES);
+
+	/* compare */
+	rc = memcmp((char *)passwd->bv_val, (char *)buffer, sizeof(buffer));
 	return rc ? 1 : 0;
 }