[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
R: Patch for NT 4.0 SAM MD4 password support (ITS#2099)
This is a multi-part message in MIME format.
------=_NextPart_000_0000_01C26364.32FA7770
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Ok,
I rewrote the whole ntmd4.c file, which is, of course, included in the
attached diff file.
I also changed the license stuff to meet OpenLDAP requirements.
Is it enough or I have to repost it from scratch?
Regards,
----------------------------------
Giampaolo Tomassoni
Assistenza rete e sistemi
Arezzo Telecomunicazione Srl
Via del Saracino, 57
I-52100 Arezzo - Italy
e-mail: g.tomassoni@ar-tel.it
tel: +39-0575-301530
fax: +39-0575-301570
> -----Messaggio originale-----
> Da: Kurt Zeilenga [mailto:openldap-its@OpenLDAP.org]
> Inviato: domenica 22 settembre 2002 17.54
> A: g.tomassoni@ar-tel.it
> Oggetto: Re: Patch for NT 4.0 SAM MD4 password support (ITS#2099)
>
>
> Your patch does not meet our contributing guidelines and, hence,
> cannot be accepted. In particular, we require:
> Patches MUST be redistributable and usable under the terms
> of the OpenLDAP Public License.
> http://www.openldap.org/devel/contributing.html#copyright
>
> Your patch is only distributable under the terms of the GNU GPL.
>
> Kurt
>
------=_NextPart_000_0000_01C26364.32FA7770
Content-Type: application/octet-stream;
name="openldap-2.1.4+ntpasswd.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="openldap-2.1.4+ntpasswd.diff"
diff -urdN ../openldap-2.1.4/configure ./configure=0A=
--- ../openldap-2.1.4/configure Thu Aug 22 02:37:55 2002=0A=
+++ ./configure Sun Sep 22 12:14:36 2002=0A=
@@ -75,6 +75,8 @@=0A=
ac_help=3D"$ac_help=0A=
--enable-lmpasswd enable LAN Manager passwords [no]"=0A=
ac_help=3D"$ac_help=0A=
+ --enable-ntpasswd enable NT SAM password [no]"=0A=
+ac_help=3D"$ac_help=0A=
--enable-spasswd enable (Cyrus) SASL password verification [no]"=0A=
ac_help=3D"$ac_help=0A=
--enable-modules enable dynamic module support [no]"=0A=
@@ -1845,11 +1847,28 @@=0A=
ol_enable_lmpasswd=3D"no"=0A=
fi=0A=
# end --enable-lmpasswd=0A=
+# OpenLDAP --enable-ntpasswd=0A=
+ # Check whether --enable-ntpasswd or --disable-ntpasswd was given.=0A=
+if test "${enable_ntpasswd+set}" =3D set; then=0A=
+ enableval=3D"$enable_ntpasswd"=0A=
+ ol_arg=3Dinvalid=0A=
+ for ol_val in auto yes no ; do=0A=
+ if test "$enableval" =3D "$ol_val" ; then=0A=
+ ol_arg=3D"$ol_val"=0A=
+ fi=0A=
+ done=0A=
+ if test "$ol_arg" =3D "invalid" ; then=0A=
+ { echo "configure: error: bad value $enableval for --enable-ntpasswd" =
1>&2; exit 1; }=0A=
+ fi=0A=
+ ol_enable_ntpasswd=3D"$ol_arg"=0A=
+else=0A=
+ ol_enable_ntpasswd=3D"no"=0A=
+fi=0A=
+# end --enable-ntpasswd=0A=
# OpenLDAP --enable-spasswd=0A=
# Check whether --enable-spasswd or --disable-spasswd was given.=0A=
if test "${enable_spasswd+set}" =3D set; then=0A=
enableval=3D"$enable_spasswd"=0A=
- =0A=
ol_arg=3Dinvalid=0A=
for ol_val in auto yes no ; do=0A=
if test "$enableval" =3D "$ol_val" ; then=0A=
@@ -1860,7 +1879,6 @@=0A=
{ echo "configure: error: bad value $enableval for --enable-spasswd" =
1>&2; exit 1; }=0A=
fi=0A=
ol_enable_spasswd=3D"$ol_arg"=0A=
-=0A=
else=0A=
ol_enable_spasswd=3D"no"=0A=
fi=0A=
@@ -11153,6 +11171,13 @@=0A=
=0A=
cat >> confdefs.h <<\EOF=0A=
#define SLAPD_LMHASH 1=0A=
+EOF=0A=
+=0A=
+fi=0A=
+=0A=
+if test $ol_enable_ntpasswd !=3D no; then=0A=
+ cat >> confdefs.h <<\EOF=0A=
+#define SLAPD_NTMD4 1=0A=
EOF=0A=
=0A=
fi=0A=
diff -urdN ../openldap-2.1.4/configure.in ./configure.in=0A=
--- ../openldap-2.1.4/configure.in Thu Aug 22 02:38:21 2002=0A=
+++ ./configure.in Sun Sep 22 12:14:36 2002=0A=
@@ -1268,6 +1268,12 @@=0A=
fi=0A=
=0A=
dnl ----------------------------------------------------------------=0A=
+dnl NT SAM MD4 password checking=0A=
+if test $ol_enable_lmpasswd !=3D no; then=0A=
+ AC_DEFINE(SLAPD_NTMD4, 1, [define to support NT 4.0 SAM passwords])=0A=
+fi=0A=
+=0A=
+dnl ----------------------------------------------------------------=0A=
dnl Tests for reentrant functions necessary to build a=0A=
dnl thread_safe -lldap.=0A=
AC_CHECK_FUNCS( \=0A=
diff -urdN ../openldap-2.1.4/include/portable.h.in =
./include/portable.h.in=0A=
--- ../openldap-2.1.4/include/portable.h.in Thu Jun 20 22:12:27 2002=0A=
+++ ./include/portable.h.in Sun Sep 22 12:14:36 2002=0A=
@@ -686,6 +686,9 @@=0A=
/* define to support LAN Manager passwords */=0A=
#undef SLAPD_LMHASH=0A=
=0A=
+/* define to support NT SAM passwords */=0A=
+#undef SLAPD_NTMD4=0A=
+=0A=
/* set to the number of arguments ctime_r() expects */=0A=
#undef CTIME_R_NARGS=0A=
=0A=
diff -urdN ../openldap-2.1.4/libraries/liblutil/Makefile.in =
./libraries/liblutil/Makefile.in=0A=
--- ../openldap-2.1.4/libraries/liblutil/Makefile.in Sun Jul 28 21:18:14 =
2002=0A=
+++ ./libraries/liblutil/Makefile.in Sun Sep 22 12:14:36 2002=0A=
@@ -15,10 +15,12 @@=0A=
=0A=
SRCS =3D base64.c csn.c entropy.c sasl.c signal.c hash.c \=0A=
md5.c passwd.c sha1.c getpass.c lockf.c utils.c uuid.c sockpair.c \=0A=
+ ntmd4.c \=0A=
@LIBSRCS@ $(@PLAT@_SRCS)=0A=
=0A=
OBJS =3D base64.o csn.o entropy.o sasl.o signal.o hash.o \=0A=
md5.o passwd.o sha1.o getpass.o lockf.o utils.o uuid.o sockpair.o \=0A=
+ ntmd4.o \=0A=
@LIBOBJS@ $(@PLAT@_OBJS)=0A=
=0A=
LDAP_INCDIR=3D ../../include =0A=
@@ -33,4 +35,3 @@=0A=
=0A=
clean-local:=0A=
$(RM) *.res=0A=
-=0A=
diff -urdN ../openldap-2.1.4/libraries/liblutil/ntmd4.c =
./libraries/liblutil/ntmd4.c=0A=
--- ../openldap-2.1.4/libraries/liblutil/ntmd4.c Thu Jan 1 01:00:00 1970=0A=
+++ ./libraries/liblutil/ntmd4.c Mon Sep 23 22:30:13 2002=0A=
@@ -0,0 +1,345 @@=0A=
+/*=0A=
+ MD4 hashing for NT 4.0 passwords.=0A=
+=0A=
+ Copyright 2002 by Giampaolo Tomassoni, All rights reserved.=0A=
+ This software is not subject to any license.=0A=
+=0A=
+ Redistribution and use in source and binary forms are permitted=0A=
+ without restriction or fee of any kind as long as this notice=0A=
+ is preserved.=0A=
+*/=0A=
+=0A=
+/*=0A=
+ This file exports the function:=0A=
+=0A=
+ int ntmd4hash(uchar p16[16], const uchar* passwd)=0A=
+=0A=
+ The function gets a null-terminated password -which is assumed=0A=
+ to be a multibyte string according to the application's current=0A=
+ locale-, converts it to a UCS-2 string, pads it with nulls to fit=0A=
+ a 128 uint16 buffer, and finally computes its 16-bytes md4 hash.=0A=
+=0A=
+ The function yields FALSE (=3D0) if one or more characters in passwd=0A=
+ can't be converted to UCS-2 or if the conversion results in more=0A=
+ than 128 UCS-2 characters. Otherwise the function returns TRUE (=3D1)=0A=
+ and the p16[16] buffer contains the 16-bytes md4 hash.=0A=
+=0A=
+ At the time of this writing, ntmd4hash() is called by=0A=
+ passwd.c:hash_ntmd4().=0A=
+=0A=
+ A porting test may be accomplished making an executable of this=0A=
+ file specifing the option -DTEST at compile time.=0A=
+=0A=
+ Enjoy moving your NT 4.0 Domain to OpenLDAP!=0A=
+=0A=
+ 2002-09-23 Giampaolo Tomassoni <g.tomassoni@ar-tel.it>=0A=
+*/=0A=
+=0A=
+#include "portable.h"=0A=
+=0A=
+#include <stdio.h>=0A=
+#include <wchar.h>=0A=
+=0A=
+typedef unsigned long uint32;=0A=
+typedef unsigned short uint16;=0A=
+typedef unsigned char uchar;=0A=
+=0A=
+=0A=
+/* NOTE: This code makes no attempt to be fast! =0A=
+ It assumes that a int is at least 32 bits long=0A=
+*/=0A=
+=0A=
+static uint32 F(uint32 X, uint32 Y, uint32 Z)=0A=
+{ return((X&Y) | ((~X)&Z)); }=0A=
+=0A=
+static uint32 G(uint32 X, uint32 Y, uint32 Z)=0A=
+{ return((X&Y) | (X&Z) | (Y&Z)); }=0A=
+=0A=
+static uint32 H(uint32 X, uint32 Y, uint32 Z)=0A=
+{ return(X^Y^Z); }=0A=
+=0A=
+static uint32 lshift(uint32 x, int s)=0A=
+{ return(((x<<s)&0xFFFFFFFF) | ((x&0xFFFFFFFF)>>(32-s))); }=0A=
+=0A=
+/* this applies md4 to 64 byte chunks */=0A=
+static void mdfour64(uint32 V[4], const uint32 M[16])=0A=
+{=0A=
+ uint32 A =3D V[0],=0A=
+ B =3D V[1],=0A=
+ C =3D V[2],=0A=
+ D =3D V[3];=0A=
+=0A=
+#define ROUND1(a,b,c,d,k,s) a =3D lshift(a + F(b,c,d) + M[k], s)=0A=
+#define ROUND2(a,b,c,d,k,s) a =3D lshift(a + G(b,c,d) + M[k] + \=0A=
+ (uint32)0x5A827999, s)=0A=
+#define ROUND3(a,b,c,d,k,s) a =3D lshift(a + H(b,c,d) + M[k] + \=0A=
+ (uint32)0x6ED9EBA1, s)=0A=
+=0A=
+ ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);=0A=
+ ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);=0A=
+ ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);=0A=
+ ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);=0A=
+ ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);=0A=
+ ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);=0A=
+ ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);=0A=
+ ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); =0A=
+=0A=
+ ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);=0A=
+ ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);=0A=
+ ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);=0A=
+ ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);=0A=
+ ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);=0A=
+ ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);=0A=
+ ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);=0A=
+ ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);=0A=
+=0A=
+ ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);=0A=
+ ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);=0A=
+ ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);=0A=
+ ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);=0A=
+ ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);=0A=
+ ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);=0A=
+ ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);=0A=
+ ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);=0A=
+=0A=
+#undef ROUND3=0A=
+#undef ROUND2=0A=
+#undef ROUND1=0A=
+=0A=
+ V[0] =3D (V[0] + A) & 0xFFFFFFFF;=0A=
+ V[1] =3D (V[1] + B) & 0xFFFFFFFF;=0A=
+ V[2] =3D (V[2] + C) & 0xFFFFFFFF;=0A=
+ V[3] =3D (V[3] + D) & 0xFFFFFFFF;=0A=
+}=0A=
+=0A=
+static void copy64(uint32* M, const uchar* in)=0A=
+{=0A=
+ int i;=0A=
+ for(i =3D 0; i < 16; i++) {=0A=
+ M[i] =3D (in[3]<<24) | (in[2]<<16) | (in[1]<<8) | in[0];=0A=
+ in +=3D 4;=0A=
+ }=0A=
+}=0A=
+=0A=
+static void copy4(uchar* out, uint32 x)=0A=
+{=0A=
+ out[0] =3D (x>> 0)&0xFF;=0A=
+ out[1] =3D (x>> 8)&0xFF;=0A=
+ out[2] =3D (x>>16)&0xFF;=0A=
+ out[3] =3D (x>>24)&0xFF;=0A=
+}=0A=
+=0A=
+/* produce a md4 message digest from data of length n bytes */=0A=
+void mdfour(uchar out[16], const uchar* in, int n)=0A=
+{=0A=
+ uchar buf[128];=0A=
+ uint32 M[16];=0A=
+ uint32 V[4];=0A=
+ uint32 b =3D n * 8;=0A=
+ int i;=0A=
+=0A=
+ V[0] =3D 0x67452301;=0A=
+ V[1] =3D 0xefcdab89;=0A=
+ V[2] =3D 0x98badcfe;=0A=
+ V[3] =3D 0x10325476;=0A=
+=0A=
+ while(n > 64) {=0A=
+ copy64(M, in);=0A=
+ mdfour64(V, M);=0A=
+ in +=3D 64;=0A=
+ n -=3D 64;=0A=
+ }=0A=
+=0A=
+ memset(buf, 0, sizeof(buf));=0A=
+ memcpy(buf, in, n);=0A=
+ buf[n] =3D 0x80;=0A=
+=0A=
+ if(n <=3D 55) {=0A=
+ copy4(buf+56, b);=0A=
+ copy64(M, buf);=0A=
+ mdfour64(V, M);=0A=
+ } else {=0A=
+ copy4(buf+120, b); =0A=
+ copy64(M, buf);=0A=
+ mdfour64(V, M);=0A=
+ copy64(M, buf+64);=0A=
+ mdfour64(V, M);=0A=
+ }=0A=
+=0A=
+ memset(buf, 0, sizeof(buf));=0A=
+ copy64(M, buf);=0A=
+=0A=
+ copy4(&out[ 0], V[0]);=0A=
+ copy4(&out[ 4], V[1]);=0A=
+ copy4(&out[ 8], V[2]);=0A=
+ copy4(&out[12], V[3]);=0A=
+=0A=
+ memset(V, 0, sizeof(V));=0A=
+}=0A=
+=0A=
+/* =0A=
+ * Creates the MD4 Hash of the users password in NT UNICODE.=0A=
+ */=0A=
+#define CWMAX 128=0A=
+int ntmd4hash(uchar p16[16], const char* passwd)=0A=
+{=0A=
+ uint16 wpwd[CWMAX];=0A=
+ uint16* pwpwd;=0A=
+ int wlen;=0A=
+ int n;=0A=
+=0A=
+ /* Password must be converted to NT unicode (i.e.: UCS-2) */=0A=
+ n =3D strlen(passwd);=0A=
+ for(pwpwd =3D wpwd; pwpwd < &wpwd[CWMAX] && n > 0; ++pwpwd) {=0A=
+ wchar_t wc;=0A=
+ const int nc =3D mbtowc(&wc, passwd, n);=0A=
+=0A=
+ if(nc <=3D 0 || (wc>>16) !=3D 0) {=0A=
+ /* The password failed unicode conversion or *=0A=
+ * is too long. */=0A=
+ memset(wpwd, 0, sizeof(wpwd));=0A=
+ return(0);=0A=
+ }=0A=
+=0A=
+ passwd +=3D nc;=0A=
+ n -=3D nc;=0A=
+ *pwpwd =3D (uint16)wc;=0A=
+ }=0A=
+=0A=
+ /* Computes final size of the UCS-2 version of passwd */=0A=
+ wlen =3D (int)(pwpwd - wpwd);=0A=
+=0A=
+ /* Right-pads with null */=0A=
+ memset(pwpwd, 0, (CWMAX - wlen) * sizeof(*wpwd));=0A=
+=0A=
+ /* Inits hashed output and starts MD4 hash computing */=0A=
+ memset(p16, 0, sizeof(p16));=0A=
+ mdfour(p16, (uchar*)wpwd, wlen * sizeof(*wpwd));=0A=
+=0A=
+ /* Security reasons impose to clear the UCS-2 version of the *=0A=
+ * cleartext password... */=0A=
+ memset(wpwd, 0, sizeof(wpwd));=0A=
+=0A=
+ /* Conversion successfully accomplished */=0A=
+ return(1);=0A=
+}=0A=
+=0A=
+#ifdef TEST=0A=
+static void PrintIt(const uchar p[16])=0A=
+{=0A=
+ int i;=0A=
+=0A=
+ for(i =3D 0; i < 16; ++i)=0A=
+ printf("%02X", p[i]);=0A=
+}=0A=
+=0A=
+#ifndef LC_CTYPE=0A=
+# include <locale.h>=0A=
+#endif=0A=
+=0A=
+int main(int argc, char** argv)=0A=
+{=0A=
+ static const char* nmLocale =3D "it_IT"; /* Locale for test */=0A=
+ static const char* aPasswords[] =3D {=0A=
+ "",=0A=
+ "test",=0A=
+ "SiMpLeMiNdEd",=0A=
+ "\305-unit",=0A=
+ "\340ncora", /* IT for anchor */=0A=
+ "anc\362ra", /* IT for again */=0A=
+ "stra\337e", /* GE for street */=0A=
+ "t\351l\351ph\351rique" /* FR for IT teleferica :) */=0A=
+ };=0A=
+ static const uchar aHashes[] =3D {=0A=
+ /* "" */=0A=
+ 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,=0A=
+ 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0,=0A=
+=0A=
+ /* "test" */=0A=
+ 0x0C, 0xB6, 0x94, 0x88, 0x05, 0xF7, 0x97, 0xBF,=0A=
+ 0x2A, 0x82, 0x80, 0x79, 0x73, 0xB8, 0x95, 0x37,=0A=
+=0A=
+ /* "SiMpLeMiNdEd" */=0A=
+ 0xDF, 0x81, 0x06, 0xDB, 0x08, 0x84, 0x85, 0x0A,=0A=
+ 0xE7, 0xE9, 0xF8, 0xEF, 0x0B, 0x7C, 0xC9, 0x0F,=0A=
+=0A=
+ /* "\305-unit" */=0A=
+ 0x24, 0xBA, 0x2C, 0xF6, 0xF1, 0xC8, 0x70, 0x24,=0A=
+ 0x19, 0x8F, 0xA5, 0x08, 0x09, 0x30, 0xBC, 0xB6,=0A=
+=0A=
+ /* "\340ncora" */=0A=
+ 0xEC, 0x02, 0x38, 0xD8, 0xF0, 0x85, 0x96, 0x7B,=0A=
+ 0xAF, 0x24, 0x0E, 0xE1, 0xD2, 0x6C, 0x54, 0x0C,=0A=
+=0A=
+ /* "anc\362ra" */=0A=
+ 0x99, 0x53, 0x70, 0xEE, 0xE5, 0xB3, 0xD0, 0x2D,=0A=
+ 0x70, 0x53, 0xB9, 0xB2, 0x28, 0x11, 0x98, 0x27,=0A=
+=0A=
+ /* "stra\337e" */=0A=
+ 0x68, 0xF0, 0x84, 0x7D, 0xE0, 0x5B, 0xDE, 0xFE,=0A=
+ 0xF9, 0x80, 0xC8, 0x45, 0x98, 0x76, 0x3A, 0x71,=0A=
+=0A=
+ /* "t\351l\351ph\351rique" */=0A=
+ 0xEB, 0xFE, 0x00, 0x6C, 0x00, 0x66, 0xA4, 0x9F,=0A=
+ 0xEE, 0xF9, 0xD6, 0xA9, 0x35, 0x23, 0x17, 0x42=0A=
+ };=0A=
+ uchar p[16];=0A=
+ int rv =3D 0;=0A=
+ int i;=0A=
+=0A=
+ if(setlocale(LC_ALL, "") =3D=3D NULL) {=0A=
+ perror("setting user-defined locale");=0A=
+ fputs("Test can't be performed.\n", stderr);=0A=
+ return(2);=0A=
+ }=0A=
+=0A=
+ if(argc > 1) {=0A=
+ for(i =3D 1; i < argc; ++i) {=0A=
+ putchar('"');=0A=
+ fputs(argv[1], stdout);=0A=
+ putchar('"');=0A=
+=0A=
+ if(ntmd4hash(p, argv[1])) {=0A=
+ PrintIt(p);=0A=
+ putchar('\n');=0A=
+ } else {=0A=
+ puts(": UCS-2 conversion FAILED!!!");=0A=
+ rv =3D 1;=0A=
+ }=0A=
+ }=0A=
+ } else {=0A=
+ if(setlocale(LC_CTYPE, nmLocale) =3D=3D NULL) {=0A=
+ perror("setting locale");=0A=
+ fprintf(=0A=
+ stderr,=0A=
+ "Test can't be performed without setting locale %s.\n",=0A=
+ nmLocale=0A=
+ );=0A=
+ return(2);=0A=
+ }=0A=
+=0A=
+ for(i =3D 0 ; i < sizeof(aPasswords)/sizeof(*aPasswords); ++i) {=0A=
+ putchar('"');=0A=
+ fputs(aPasswords[i], stdout);=0A=
+ putchar('"');=0A=
+=0A=
+ if(ntmd4hash(p, aPasswords[i])) {=0A=
+ fputs(" -> 0x", stdout);=0A=
+ PrintIt(p);=0A=
+=0A=
+ if(memcmp(p, &aHashes[16*i], sizeof(p)) =3D=3D 0)=0A=
+ puts(": Ok\n");=0A=
+ else {=0A=
+ puts(": MISMATCH!!!");=0A=
+ rv =3D 1;=0A=
+ }=0A=
+ } else {=0A=
+ puts(": UCS-2 conversion FAILED!!!");=0A=
+ rv =3D 1;=0A=
+ }=0A=
+ }=0A=
+ }=0A=
+=0A=
+ return(rv);=0A=
+}=0A=
+#endif /* TEST */=0A=
diff -urdN ../openldap-2.1.4/libraries/liblutil/passwd.c =
./libraries/liblutil/passwd.c=0A=
--- ../openldap-2.1.4/libraries/liblutil/passwd.c Fri Aug 16 19:30:47 =
2002=0A=
+++ ./libraries/liblutil/passwd.c Mon Sep 23 22:25:05 2002=0A=
@@ -124,6 +124,82 @@=0A=
const struct berval *cred );=0A=
#endif=0A=
=0A=
+/* pw_string is only called when SLAPD_LMHASH, SLAPD_CRYPT or =
SLAPD_NTMD4=0A=
+ is defined */=0A=
+#if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT) || =
defined(SLAPD_NTMD4)=0A=
+static struct berval* pw_string(=0A=
+ const struct pw_scheme* sc,=0A=
+ const struct berval* passwd=0A=
+) {=0A=
+ struct berval *pw =3D ber_memalloc( sizeof( struct berval ) );=0A=
+ if( pw =3D=3D NULL ) return NULL;=0A=
+=0A=
+ pw->bv_len =3D sc->name.bv_len + passwd->bv_len;=0A=
+ pw->bv_val =3D ber_memalloc( pw->bv_len + 1 );=0A=
+=0A=
+ if( pw->bv_val =3D=3D NULL ) {=0A=
+ ber_memfree( pw );=0A=
+ return NULL;=0A=
+ }=0A=
+=0A=
+ AC_MEMCPY( pw->bv_val, sc->name.bv_val, sc->name.bv_len );=0A=
+ AC_MEMCPY( &pw->bv_val[sc->name.bv_len], passwd->bv_val, =
passwd->bv_len );=0A=
+=0A=
+ pw->bv_val[pw->bv_len] =3D '\0';=0A=
+ return pw;=0A=
+}=0A=
+#endif /* SLAPD_LMHASH || SLAPD_CRYPT || SLAPD_NTMD4 */=0A=
+=0A=
+#ifdef SLAPD_NTMD4=0A=
+static struct berval* hash_ntmd4(=0A=
+ const struct pw_scheme* scheme,=0A=
+ const struct berval* passwd=0A=
+) {=0A=
+ extern int ntmd4hash(=0A=
+ unsigned char p16[16],=0A=
+ const char* passwd=0A=
+ );=0A=
+ static const char a16s[] =3D "0123456789abcdef";=0A=
+ struct berval hash;=0A=
+ unsigned char p16[16];=0A=
+ char mdhash[2*sizeof(p16) + 1];=0A=
+ int i;=0A=
+=0A=
+ for(i =3D 0; i < passwd->bv_len; i++)=0A=
+ if(passwd->bv_val[i] =3D=3D '\0')=0A=
+ /* NUL character in password */=0A=
+ return(NULL);=0A=
+=0A=
+ if(passwd->bv_val[i] !=3D '\0')=0A=
+ /* passwd must behave like a string */=0A=
+ return(NULL);=0A=
+=0A=
+ if(!ntmd4hash(p16, passwd->bv_val))=0A=
+ /* Password must be convertible to UCS-2 */=0A=
+ return(NULL);=0A=
+=0A=
+ for(i =3D 0; i < sizeof(p16)/sizeof(*p16); ++i) {=0A=
+ unsigned char c =3D p16[i];=0A=
+ mdhash[2*i + 0] =3D a16s[c >> 4];=0A=
+ mdhash[2*i + 1] =3D a16s[c & 0x0f];=0A=
+ }=0A=
+ mdhash[2*i + 0] =3D '\0';=0A=
+=0A=
+ hash.bv_val =3D mdhash;=0A=
+ hash.bv_len =3D sizeof(mdhash) - 1;=0A=
+ return(pw_string(scheme, &hash));=0A=
+}=0A=
+=0A=
+static int chk_ntmd4(=0A=
+ const struct pw_scheme* scheme,=0A=
+ const struct berval* passwd,=0A=
+ const struct berval* cred=0A=
+) {=0A=
+ struct berval* hash =3D hash_ntmd4(scheme, cred);=0A=
+ return(memcmp(&hash->bv_val[scheme->name.bv_len], passwd->bv_val, 32));=0A=
+}=0A=
+#endif /* SLAPD_NTMD4 */=0A=
+=0A=
#ifdef SLAPD_SPASSWD=0A=
static int chk_sasl(=0A=
const struct pw_scheme *scheme,=0A=
@@ -204,6 +280,10 @@=0A=
{ {sizeof("{LANMAN}")-1, "{LANMAN}"}, chk_lanman, hash_lanman },=0A=
#endif /* SLAPD_LMHASH */=0A=
=0A=
+#ifdef SLAPD_NTMD4=0A=
+ { {sizeof("{NT}")-1, "{NT}"}, chk_ntmd4, hash_ntmd4 },=0A=
+#endif /* SLAPD_NTMD4 */=0A=
+=0A=
#ifdef SLAPD_SPASSWD=0A=
{ {sizeof("{SASL}")-1, "{SASL}"}, chk_sasl, NULL },=0A=
#endif=0A=
@@ -375,31 +455,6 @@=0A=
=0A=
return (sc->hash_fn)( sc, passwd );=0A=
}=0A=
-=0A=
-/* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined =
*/=0A=
-#if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT)=0A=
-static struct berval * pw_string(=0A=
- const struct pw_scheme *sc,=0A=
- const struct berval *passwd )=0A=
-{=0A=
- struct berval *pw =3D ber_memalloc( sizeof( struct berval ) );=0A=
- if( pw =3D=3D NULL ) return NULL;=0A=
-=0A=
- pw->bv_len =3D sc->name.bv_len + passwd->bv_len;=0A=
- pw->bv_val =3D ber_memalloc( pw->bv_len + 1 );=0A=
-=0A=
- if( pw->bv_val =3D=3D NULL ) {=0A=
- ber_memfree( pw );=0A=
- return NULL;=0A=
- }=0A=
-=0A=
- AC_MEMCPY( pw->bv_val, sc->name.bv_val, sc->name.bv_len );=0A=
- AC_MEMCPY( &pw->bv_val[sc->name.bv_len], passwd->bv_val, =
passwd->bv_len );=0A=
-=0A=
- pw->bv_val[pw->bv_len] =3D '\0';=0A=
- return pw;=0A=
-}=0A=
-#endif /* SLAPD_LMHASH || SLAPD_CRYPT */=0A=
=0A=
static struct berval * pw_string64(=0A=
const struct pw_scheme *sc,=0A=
------=_NextPart_000_0000_01C26364.32FA7770--