]> git.sur5r.net Git - openldap/blob - libraries/liblutil/passwd.c
fix ITS#3499 (may need further testing)
[openldap] / libraries / liblutil / passwd.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2005 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15
16 /*
17  * int lutil_passwd(
18  *      const struct berval *passwd,
19  *      const struct berval *cred,
20  *      const char **schemes )
21  *
22  * Returns true if user supplied credentials (cred) matches
23  * the stored password (passwd). 
24  *
25  * Due to the use of the crypt(3) function 
26  * this routine is NOT thread-safe.
27  */
28
29 #include "portable.h"
30
31 #include <stdio.h>
32 #include <ac/stdlib.h>
33 #include <ac/string.h>
34 #include <ac/unistd.h>
35
36 #ifdef SLAPD_SPASSWD
37 #       ifdef HAVE_SASL_SASL_H
38 #               include <sasl/sasl.h>
39 #       else
40 #               include <sasl.h>
41 #       endif
42 #endif
43
44 #if defined(SLAPD_LMHASH)
45 #       include <openssl/des.h>
46 #endif /* SLAPD_LMHASH */
47
48 #include <ac/param.h>
49
50 #ifdef SLAPD_CRYPT
51 # include <ac/crypt.h>
52
53 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
54 #  ifdef HAVE_SHADOW_H
55 #       include <shadow.h>
56 #  endif
57 #  ifdef HAVE_PWD_H
58 #       include <pwd.h>
59 #  endif
60 #  ifdef HAVE_AIX_SECURITY
61 #       include <userpw.h>
62 #  endif
63 # endif
64 #endif
65
66 #include <lber.h>
67
68 #include "ldap_pvt.h"
69 #include "lber_pvt.h"
70
71 #include "lutil_md5.h"
72 #include "lutil_sha1.h"
73 #include "lutil.h"
74
75 static const unsigned char crypt64[] =
76         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
77
78 #ifdef SLAPD_CRYPT
79 static char *salt_format = NULL;
80 #endif
81
82 struct pw_scheme {
83         struct berval name;
84         LUTIL_PASSWD_CHK_FUNC *chk_fn;
85         LUTIL_PASSWD_HASH_FUNC *hash_fn;
86 };
87
88 struct pw_slist {
89         struct pw_slist *next;
90         struct pw_scheme s;
91 };
92
93 /* password check routines */
94
95 #define SALT_SIZE       4
96
97 static LUTIL_PASSWD_CHK_FUNC chk_md5;
98 static LUTIL_PASSWD_CHK_FUNC chk_smd5;
99 static LUTIL_PASSWD_HASH_FUNC hash_smd5;
100 static LUTIL_PASSWD_HASH_FUNC hash_md5;
101
102
103 #ifdef LUTIL_SHA1_BYTES
104 static LUTIL_PASSWD_CHK_FUNC chk_ssha1;
105 static LUTIL_PASSWD_CHK_FUNC chk_sha1;
106 static LUTIL_PASSWD_HASH_FUNC hash_sha1;
107 static LUTIL_PASSWD_HASH_FUNC hash_ssha1;
108 #endif
109
110 #ifdef SLAPD_LMHASH
111 static LUTIL_PASSWD_CHK_FUNC chk_lanman;
112 static LUTIL_PASSWD_HASH_FUNC hash_lanman;
113 #endif
114
115 #ifdef SLAPD_SPASSWD
116 static LUTIL_PASSWD_CHK_FUNC chk_sasl;
117 #endif
118
119 #ifdef SLAPD_CRYPT
120 static LUTIL_PASSWD_CHK_FUNC chk_crypt;
121 static LUTIL_PASSWD_HASH_FUNC hash_crypt;
122
123 #if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
124 static LUTIL_PASSWD_CHK_FUNC chk_unix;
125 #endif
126 #endif
127
128 /* password hash routines */
129
130 #ifdef SLAPD_CLEARTEXT
131 static LUTIL_PASSWD_HASH_FUNC hash_clear;
132 #endif
133
134 static struct pw_slist *pw_schemes;
135 static int pw_inited;
136
137 static const struct pw_scheme pw_schemes_default[] =
138 {
139 #ifdef LUTIL_SHA1_BYTES
140         { BER_BVC("{SSHA}"),            chk_ssha1, hash_ssha1 },
141         { BER_BVC("{SHA}"),                     chk_sha1, hash_sha1 },
142 #endif
143
144         { BER_BVC("{SMD5}"),            chk_smd5, hash_smd5 },
145         { BER_BVC("{MD5}"),                     chk_md5, hash_md5 },
146
147 #ifdef SLAPD_LMHASH
148         { BER_BVC("{LANMAN}"),          chk_lanman, hash_lanman },
149 #endif /* SLAPD_LMHASH */
150
151 #ifdef SLAPD_SPASSWD
152         { BER_BVC("{SASL}"),            chk_sasl, NULL },
153 #endif
154
155 #ifdef SLAPD_CRYPT
156         { BER_BVC("{CRYPT}"),           chk_crypt, hash_crypt },
157 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
158         { BER_BVC("{UNIX}"),            chk_unix, NULL },
159 # endif
160 #endif
161
162 #ifdef SLAPD_CLEARTEXT
163         /* pseudo scheme */
164         { {0, "{CLEARTEXT}"},           NULL, hash_clear },
165 #endif
166
167         { BER_BVNULL, NULL, NULL }
168 };
169
170 int lutil_passwd_add(
171         struct berval *scheme,
172         LUTIL_PASSWD_CHK_FUNC *chk,
173         LUTIL_PASSWD_HASH_FUNC *hash )
174 {
175         struct pw_slist *ptr;
176
177         if (!pw_inited) lutil_passwd_init();
178
179         ptr = ber_memalloc( sizeof( struct pw_slist ));
180         if (!ptr) return -1;
181         ptr->next = pw_schemes;
182         ptr->s.name = *scheme;
183         ptr->s.chk_fn = chk;
184         ptr->s.hash_fn = hash;
185         pw_schemes = ptr;
186         return 0;
187 }
188
189 void lutil_passwd_init()
190 {
191         struct pw_scheme *s;
192
193         pw_inited = 1;
194
195         for( s=(struct pw_scheme *)pw_schemes_default; s->name.bv_val; s++) {
196                 if ( lutil_passwd_add( &s->name, s->chk_fn, s->hash_fn ) ) break;
197         }
198 }
199
200 void lutil_passwd_destroy()
201 {
202         struct pw_slist *ptr, *next;
203
204         for( ptr=pw_schemes; ptr; ptr=next ) {
205                 next = ptr->next;
206                 ber_memfree( ptr );
207         }
208 }
209
210 static const struct pw_scheme *get_scheme(
211         const char* scheme )
212 {
213         struct pw_slist *pws;
214
215         if (!pw_inited) lutil_passwd_init();
216
217         for( pws=pw_schemes; pws; pws=pws->next ) {
218                 if( strcasecmp(scheme, pws->s.name.bv_val ) == 0 ) {
219                         return &(pws->s);
220                 }
221         }
222
223         return NULL;
224 }
225
226 int lutil_passwd_scheme(
227         const char* scheme )
228 {
229         if( scheme == NULL ) {
230                 return 0;
231         }
232
233         return get_scheme(scheme) != NULL;
234 }
235
236
237 static int is_allowed_scheme( 
238         const char* scheme,
239         const char** schemes )
240 {
241         int i;
242
243         if( schemes == NULL ) return 1;
244
245         for( i=0; schemes[i] != NULL; i++ ) {
246                 if( strcasecmp( scheme, schemes[i] ) == 0 ) {
247                         return 1;
248                 }
249         }
250         return 0;
251 }
252
253 static struct berval *passwd_scheme(
254         const struct pw_scheme *scheme,
255         const struct berval * passwd,
256         struct berval *bv,
257         const char** allowed )
258 {
259         if( !is_allowed_scheme( scheme->name.bv_val, allowed ) ) {
260                 return NULL;
261         }
262
263         if( passwd->bv_len >= scheme->name.bv_len ) {
264                 if( strncasecmp( passwd->bv_val, scheme->name.bv_val, scheme->name.bv_len ) == 0 ) {
265                         bv->bv_val = &passwd->bv_val[scheme->name.bv_len];
266                         bv->bv_len = passwd->bv_len - scheme->name.bv_len;
267
268                         return bv;
269                 }
270         }
271
272         return NULL;
273 }
274
275 /*
276  * Return 0 if creds are good.
277  */
278 int
279 lutil_passwd(
280         const struct berval *passwd,    /* stored passwd */
281         const struct berval *cred,              /* user cred */
282         const char **schemes,
283         const char **text )
284 {
285         struct pw_slist *pws;
286
287         if ( text ) *text = NULL;
288
289         if (cred == NULL || cred->bv_len == 0 ||
290                 passwd == NULL || passwd->bv_len == 0 )
291         {
292                 return -1;
293         }
294
295         if (!pw_inited) lutil_passwd_init();
296
297         for( pws=pw_schemes; pws; pws=pws->next ) {
298                 if( pws->s.chk_fn ) {
299                         struct berval x;
300                         struct berval *p = passwd_scheme( &(pws->s),
301                                 passwd, &x, schemes );
302
303                         if( p != NULL ) {
304                                 return (pws->s.chk_fn)( &(pws->s.name), p, cred, text );
305                         }
306                 }
307         }
308
309 #ifdef SLAPD_CLEARTEXT
310         if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
311                 return (( passwd->bv_len == cred->bv_len ) &&
312                                 ( passwd->bv_val[0] != '{' /*'}'*/ ))
313                         ? memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
314                         : 1;
315         }
316 #endif
317         return 1;
318 }
319
320 int lutil_passwd_generate( struct berval *pw, ber_len_t len )
321 {
322
323         if( len < 1 ) return -1;
324
325         pw->bv_len = len;
326         pw->bv_val = ber_memalloc( len + 1 );
327
328         if( pw->bv_val == NULL ) {
329                 return -1;
330         }
331
332         if( lutil_entropy( (unsigned char *) pw->bv_val, pw->bv_len) < 0 ) {
333                 return -1; 
334         }
335
336         for( len = 0; len < pw->bv_len; len++ ) {
337                 pw->bv_val[len] = crypt64[
338                         pw->bv_val[len] % (sizeof(crypt64)-1) ];
339         }
340
341         pw->bv_val[len] = '\0';
342         
343         return 0;
344 }
345
346 int lutil_passwd_hash(
347         const struct berval * passwd,
348         const char * method,
349         struct berval *hash,
350         const char **text )
351 {
352         const struct pw_scheme *sc = get_scheme( method );
353
354         hash->bv_val = NULL;
355         hash->bv_len = 0;
356
357         if( sc == NULL ) {
358                 if( text ) *text = "scheme not recognized";
359                 return -1;
360         }
361
362         if( ! sc->hash_fn ) {
363                 if( text ) *text = "scheme provided no hash function";
364                 return -1;
365         }
366
367         if( text ) *text = NULL;
368
369         return (sc->hash_fn)( &sc->name, passwd, hash, text );
370 }
371
372 /* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined */
373 #if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT)
374 static int pw_string(
375         const struct berval *sc,
376         struct berval *passwd )
377 {
378         struct berval pw;
379
380         pw.bv_len = sc->bv_len + passwd->bv_len;
381         pw.bv_val = ber_memalloc( pw.bv_len + 1 );
382
383         if( pw.bv_val == NULL ) {
384                 return LUTIL_PASSWD_ERR;
385         }
386
387         AC_MEMCPY( pw.bv_val, sc->bv_val, sc->bv_len );
388         AC_MEMCPY( &pw.bv_val[sc->bv_len], passwd->bv_val, passwd->bv_len );
389
390         pw.bv_val[pw.bv_len] = '\0';
391         *passwd = pw;
392
393         return LUTIL_PASSWD_OK;
394 }
395 #endif /* SLAPD_LMHASH || SLAPD_CRYPT */
396
397 static int pw_string64(
398         const struct berval *sc,
399         const struct berval *hash,
400         struct berval *b64,
401         const struct berval *salt )
402 {
403         int rc;
404         struct berval string;
405         size_t b64len;
406
407         if( salt ) {
408                 /* need to base64 combined string */
409                 string.bv_len = hash->bv_len + salt->bv_len;
410                 string.bv_val = ber_memalloc( string.bv_len + 1 );
411
412                 if( string.bv_val == NULL ) {
413                         return LUTIL_PASSWD_ERR;
414                 }
415
416                 AC_MEMCPY( string.bv_val, hash->bv_val,
417                         hash->bv_len );
418                 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
419                         salt->bv_len );
420                 string.bv_val[string.bv_len] = '\0';
421
422         } else {
423                 string = *hash;
424         }
425
426         b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
427         b64->bv_len = b64len + sc->bv_len;
428         b64->bv_val = ber_memalloc( b64->bv_len + 1 );
429
430         if( b64->bv_val == NULL ) {
431                 if( salt ) ber_memfree( string.bv_val );
432                 return LUTIL_PASSWD_ERR;
433         }
434
435         AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
436
437         rc = lutil_b64_ntop(
438                 (unsigned char *) string.bv_val, string.bv_len,
439                 &b64->bv_val[sc->bv_len], b64len );
440
441         if( salt ) ber_memfree( string.bv_val );
442         
443         if( rc < 0 ) {
444                 return LUTIL_PASSWD_ERR;
445         }
446
447         /* recompute length */
448         b64->bv_len = sc->bv_len + rc;
449         assert( strlen(b64->bv_val) == b64->bv_len );
450         return LUTIL_PASSWD_OK;
451 }
452
453 /* PASSWORD CHECK ROUTINES */
454
455 #ifdef LUTIL_SHA1_BYTES
456 static int chk_ssha1(
457         const struct berval *sc,
458         const struct berval * passwd,
459         const struct berval * cred,
460         const char **text )
461 {
462         lutil_SHA1_CTX SHA1context;
463         unsigned char SHA1digest[LUTIL_SHA1_BYTES];
464         int rc;
465         unsigned char *orig_pass = NULL;
466
467         /* safety check -- must have some salt */
468         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(SHA1digest)) {
469                 return LUTIL_PASSWD_ERR;
470         }
471
472         /* decode base64 password */
473         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
474                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
475
476         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
477
478         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
479
480         /* safety check -- must have some salt */
481         if (rc <= (int)(sizeof(SHA1digest))) {
482                 ber_memfree(orig_pass);
483                 return LUTIL_PASSWD_ERR;
484         }
485  
486         /* hash credentials with salt */
487         lutil_SHA1Init(&SHA1context);
488         lutil_SHA1Update(&SHA1context,
489                 (const unsigned char *) cred->bv_val, cred->bv_len);
490         lutil_SHA1Update(&SHA1context,
491                 (const unsigned char *) &orig_pass[sizeof(SHA1digest)],
492                 rc - sizeof(SHA1digest));
493         lutil_SHA1Final(SHA1digest, &SHA1context);
494  
495         /* compare */
496         rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
497         ber_memfree(orig_pass);
498         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
499 }
500
501 static int chk_sha1(
502         const struct berval *sc,
503         const struct berval * passwd,
504         const struct berval * cred,
505         const char **text )
506 {
507         lutil_SHA1_CTX SHA1context;
508         unsigned char SHA1digest[LUTIL_SHA1_BYTES];
509         int rc;
510         unsigned char *orig_pass = NULL;
511  
512         /* safety check */
513         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(SHA1digest)) {
514                 return LUTIL_PASSWD_ERR;
515         }
516
517         /* base64 un-encode password */
518         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
519                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
520
521         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
522
523         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
524
525         if( rc != sizeof(SHA1digest) ) {
526                 ber_memfree(orig_pass);
527                 return LUTIL_PASSWD_ERR;
528         }
529  
530         /* hash credentials with salt */
531         lutil_SHA1Init(&SHA1context);
532         lutil_SHA1Update(&SHA1context,
533                 (const unsigned char *) cred->bv_val, cred->bv_len);
534         lutil_SHA1Final(SHA1digest, &SHA1context);
535  
536         /* compare */
537         rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
538         ber_memfree(orig_pass);
539         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
540 }
541 #endif
542
543 static int chk_smd5(
544         const struct berval *sc,
545         const struct berval * passwd,
546         const struct berval * cred,
547         const char **text )
548 {
549         lutil_MD5_CTX MD5context;
550         unsigned char MD5digest[LUTIL_MD5_BYTES];
551         int rc;
552         unsigned char *orig_pass = NULL;
553
554         /* safety check */
555         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <= sizeof(MD5digest)) {
556                 return LUTIL_PASSWD_ERR;
557         }
558
559         /* base64 un-encode password */
560         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
561                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
562
563         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
564
565         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
566
567         if (rc <= (int)(sizeof(MD5digest))) {
568                 ber_memfree(orig_pass);
569                 return LUTIL_PASSWD_ERR;
570         }
571
572         /* hash credentials with salt */
573         lutil_MD5Init(&MD5context);
574         lutil_MD5Update(&MD5context,
575                 (const unsigned char *) cred->bv_val,
576                 cred->bv_len );
577         lutil_MD5Update(&MD5context,
578                 &orig_pass[sizeof(MD5digest)],
579                 rc - sizeof(MD5digest));
580         lutil_MD5Final(MD5digest, &MD5context);
581
582         /* compare */
583         rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
584         ber_memfree(orig_pass);
585         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
586 }
587
588 static int chk_md5(
589         const struct berval *sc,
590         const struct berval * passwd,
591         const struct berval * cred,
592         const char **text )
593 {
594         lutil_MD5_CTX MD5context;
595         unsigned char MD5digest[LUTIL_MD5_BYTES];
596         int rc;
597         unsigned char *orig_pass = NULL;
598
599         /* safety check */
600         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(MD5digest)) {
601                 return LUTIL_PASSWD_ERR;
602         }
603
604         /* base64 un-encode password */
605         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
606                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
607
608         if( orig_pass == NULL ) return LUTIL_PASSWD_ERR;
609
610         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
611         if ( rc != sizeof(MD5digest) ) {
612                 ber_memfree(orig_pass);
613                 return LUTIL_PASSWD_ERR;
614         }
615
616         /* hash credentials with salt */
617         lutil_MD5Init(&MD5context);
618         lutil_MD5Update(&MD5context,
619                 (const unsigned char *) cred->bv_val,
620                 cred->bv_len );
621         lutil_MD5Final(MD5digest, &MD5context);
622
623         /* compare */
624         rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
625         ber_memfree(orig_pass);
626         return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
627 }
628
629 #ifdef SLAPD_LMHASH
630 /* pseudocode from RFC2433
631  * A.2 LmPasswordHash()
632  * 
633  *    LmPasswordHash(
634  *    IN  0-to-14-oem-char Password,
635  *    OUT 16-octet         PasswordHash )
636  *    {
637  *       Set UcasePassword to the uppercased Password
638  *       Zero pad UcasePassword to 14 characters
639  * 
640  *       DesHash( 1st 7-octets of UcasePassword,
641  *                giving 1st 8-octets of PasswordHash )
642  * 
643  *       DesHash( 2nd 7-octets of UcasePassword,
644  *                giving 2nd 8-octets of PasswordHash )
645  *    }
646  * 
647  * 
648  * A.3 DesHash()
649  * 
650  *    DesHash(
651  *    IN  7-octet Clear,
652  *    OUT 8-octet Cypher )
653  *    {
654  *        *
655  *        * Make Cypher an irreversibly encrypted form of Clear by
656  *        * encrypting known text using Clear as the secret key.
657  *        * The known text consists of the string
658  *        *
659  *        *              KGS!@#$%
660  *        *
661  * 
662  *       Set StdText to "KGS!@#$%"
663  *       DesEncrypt( StdText, Clear, giving Cypher )
664  *    }
665  * 
666  * 
667  * A.4 DesEncrypt()
668  * 
669  *    DesEncrypt(
670  *    IN  8-octet Clear,
671  *    IN  7-octet Key,
672  *    OUT 8-octet Cypher )
673  *    {
674  *        *
675  *        * Use the DES encryption algorithm [4] in ECB mode [9]
676  *        * to encrypt Clear into Cypher such that Cypher can
677  *        * only be decrypted back to Clear by providing Key.
678  *        * Note that the DES algorithm takes as input a 64-bit
679  *        * stream where the 8th, 16th, 24th, etc.  bits are
680  *        * parity bits ignored by the encrypting algorithm.
681  *        * Unless you write your own DES to accept 56-bit input
682  *        * without parity, you will need to insert the parity bits
683  *        * yourself.
684  *        *
685  *    }
686  */
687
688 static void lmPasswd_to_key(
689         const unsigned char *lmPasswd,
690         des_cblock *key)
691 {
692         /* make room for parity bits */
693         ((char *)key)[0] = lmPasswd[0];
694         ((char *)key)[1] = ((lmPasswd[0]&0x01)<<7) | (lmPasswd[1]>>1);
695         ((char *)key)[2] = ((lmPasswd[1]&0x03)<<6) | (lmPasswd[2]>>2);
696         ((char *)key)[3] = ((lmPasswd[2]&0x07)<<5) | (lmPasswd[3]>>3);
697         ((char *)key)[4] = ((lmPasswd[3]&0x0F)<<4) | (lmPasswd[4]>>4);
698         ((char *)key)[5] = ((lmPasswd[4]&0x1F)<<3) | (lmPasswd[5]>>5);
699         ((char *)key)[6] = ((lmPasswd[5]&0x3F)<<2) | (lmPasswd[6]>>6);
700         ((char *)key)[7] = ((lmPasswd[6]&0x7F)<<1);
701                 
702         des_set_odd_parity( key );
703 }       
704
705 static int chk_lanman(
706         const struct berval *scheme,
707         const struct berval *passwd,
708         const struct berval *cred,
709         const char **text )
710 {
711         int i;
712         char UcasePassword[15];
713         des_cblock key;
714         des_key_schedule schedule;
715         des_cblock StdText = "KGS!@#$%";
716         des_cblock PasswordHash1, PasswordHash2;
717         char PasswordHash[33], storedPasswordHash[33];
718         
719         for( i=0; i<cred->bv_len; i++) {
720                 if(cred->bv_val[i] == '\0') {
721                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
722                 }
723         }
724         
725         if( cred->bv_val[i] != '\0' ) {
726                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
727         }
728         
729         strncpy( UcasePassword, cred->bv_val, 14 );
730         UcasePassword[14] = '\0';
731         ldap_pvt_str2upper( UcasePassword );
732         
733         lmPasswd_to_key( UcasePassword, &key );
734         des_set_key_unchecked( &key, schedule );
735         des_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
736         
737         lmPasswd_to_key( &UcasePassword[7], &key );
738         des_set_key_unchecked( &key, schedule );
739         des_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
740         
741         sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
742                 PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
743                 PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
744                 PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
745                 PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
746         
747         /* as a precaution convert stored password hash to lower case */
748         strncpy( storedPasswordHash, passwd->bv_val, 32 );
749         storedPasswordHash[32] = '\0';
750         ldap_pvt_str2lower( storedPasswordHash );
751         
752         return memcmp( PasswordHash, storedPasswordHash, 32) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
753 }
754 #endif /* SLAPD_LMHASH */
755
756 #ifdef SLAPD_SPASSWD
757 #ifdef HAVE_CYRUS_SASL
758 sasl_conn_t *lutil_passwd_sasl_conn = NULL;
759 #endif
760
761 static int chk_sasl(
762         const struct berval *sc,
763         const struct berval * passwd,
764         const struct berval * cred,
765         const char **text )
766 {
767         unsigned int i;
768         int rtn;
769
770         for( i=0; i<cred->bv_len; i++) {
771                 if(cred->bv_val[i] == '\0') {
772                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
773                 }
774         }
775
776         if( cred->bv_val[i] != '\0' ) {
777                 return LUTIL_PASSWD_ERR;        /* cred must behave like a string */
778         }
779
780         for( i=0; i<passwd->bv_len; i++) {
781                 if(passwd->bv_val[i] == '\0') {
782                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
783                 }
784         }
785
786         if( passwd->bv_val[i] != '\0' ) {
787                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
788         }
789
790         rtn = LUTIL_PASSWD_ERR;
791
792 #ifdef HAVE_CYRUS_SASL
793         if( lutil_passwd_sasl_conn != NULL ) {
794                 int sc;
795 # if SASL_VERSION_MAJOR < 2
796                 sc = sasl_checkpass( lutil_passwd_sasl_conn,
797                         passwd->bv_val, passwd->bv_len,
798                         cred->bv_val, cred->bv_len,
799                         text );
800 # else
801                 sc = sasl_checkpass( lutil_passwd_sasl_conn,
802                         passwd->bv_val, passwd->bv_len,
803                         cred->bv_val, cred->bv_len );
804 # endif
805                 rtn = ( sc != SASL_OK ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
806         }
807 #endif
808
809         return rtn;
810 }
811 #endif
812
813 #ifdef SLAPD_CRYPT
814 static int chk_crypt(
815         const struct berval *sc,
816         const struct berval * passwd,
817         const struct berval * cred,
818         const char **text )
819 {
820         char *cr;
821         unsigned int i;
822
823         for( i=0; i<cred->bv_len; i++) {
824                 if(cred->bv_val[i] == '\0') {
825                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
826                 }
827         }
828
829         if( cred->bv_val[i] != '\0' ) {
830                 return LUTIL_PASSWD_ERR;        /* cred must behave like a string */
831         }
832
833         if( passwd->bv_len < 2 ) {
834                 return LUTIL_PASSWD_ERR;        /* passwd must be at least two characters long */
835         }
836
837         for( i=0; i<passwd->bv_len; i++) {
838                 if(passwd->bv_val[i] == '\0') {
839                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
840                 }
841         }
842
843         if( passwd->bv_val[i] != '\0' ) {
844                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
845         }
846
847         cr = crypt( cred->bv_val, passwd->bv_val );
848
849         if( cr == NULL || cr[0] == '\0' ) {
850                 /* salt must have been invalid */
851                 return LUTIL_PASSWD_ERR;
852         }
853
854         return strcmp( passwd->bv_val, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
855 }
856
857 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
858 static int chk_unix(
859         const struct berval *sc,
860         const struct berval * passwd,
861         const struct berval * cred,
862         const char **text )
863 {
864         unsigned int i;
865         char *pw,*cr;
866
867         for( i=0; i<cred->bv_len; i++) {
868                 if(cred->bv_val[i] == '\0') {
869                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
870                 }
871         }
872         if( cred->bv_val[i] != '\0' ) {
873                 return LUTIL_PASSWD_ERR;        /* cred must behave like a string */
874         }
875
876         for( i=0; i<passwd->bv_len; i++) {
877                 if(passwd->bv_val[i] == '\0') {
878                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
879                 }
880         }
881
882         if( passwd->bv_val[i] != '\0' ) {
883                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
884         }
885
886         {
887                 struct passwd *pwd = getpwnam(passwd->bv_val);
888
889                 if(pwd == NULL) {
890                         return LUTIL_PASSWD_ERR;        /* not found */
891                 }
892
893                 pw = pwd->pw_passwd;
894         }
895 #  ifdef HAVE_GETSPNAM
896         {
897                 struct spwd *spwd = getspnam(passwd->bv_val);
898
899                 if(spwd != NULL) {
900                         pw = spwd->sp_pwdp;
901                 }
902         }
903 #  endif
904 #  ifdef HAVE_AIX_SECURITY
905         {
906                 struct userpw *upw = getuserpw(passwd->bv_val);
907
908                 if (upw != NULL) {
909                         pw = upw->upw_passwd;
910                 }
911         }
912 #  endif
913
914         if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
915                 /* password must must be at least two characters long */
916                 return LUTIL_PASSWD_ERR;
917         }
918
919         cr = crypt(cred->bv_val, pw);
920
921         if( cr == NULL || cr[0] == '\0' ) {
922                 /* salt must have been invalid */
923                 return LUTIL_PASSWD_ERR;
924         }
925
926         return strcmp(pw, cr) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
927
928 }
929 # endif
930 #endif
931
932 /* PASSWORD GENERATION ROUTINES */
933
934 #ifdef LUTIL_SHA1_BYTES
935 static int hash_ssha1(
936         const struct berval *scheme,
937         const struct berval  *passwd,
938         struct berval *hash,
939         const char **text )
940 {
941         lutil_SHA1_CTX  SHA1context;
942         unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
943         char            saltdata[SALT_SIZE];
944         struct berval digest;
945         struct berval salt;
946
947         digest.bv_val = (char *) SHA1digest;
948         digest.bv_len = sizeof(SHA1digest);
949         salt.bv_val = saltdata;
950         salt.bv_len = sizeof(saltdata);
951
952         if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
953                 return LUTIL_PASSWD_ERR; 
954         }
955
956         lutil_SHA1Init( &SHA1context );
957         lutil_SHA1Update( &SHA1context,
958                 (const unsigned char *)passwd->bv_val, passwd->bv_len );
959         lutil_SHA1Update( &SHA1context,
960                 (const unsigned char *)salt.bv_val, salt.bv_len );
961         lutil_SHA1Final( SHA1digest, &SHA1context );
962
963         return pw_string64( scheme, &digest, hash, &salt);
964 }
965
966 static int hash_sha1(
967         const struct berval *scheme,
968         const struct berval  *passwd,
969         struct berval *hash,
970         const char **text )
971 {
972         lutil_SHA1_CTX  SHA1context;
973         unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
974         struct berval digest;
975         digest.bv_val = (char *) SHA1digest;
976         digest.bv_len = sizeof(SHA1digest);
977      
978         lutil_SHA1Init( &SHA1context );
979         lutil_SHA1Update( &SHA1context,
980                 (const unsigned char *)passwd->bv_val, passwd->bv_len );
981         lutil_SHA1Final( SHA1digest, &SHA1context );
982             
983         return pw_string64( scheme, &digest, hash, NULL);
984 }
985 #endif
986
987 static int hash_smd5(
988         const struct berval *scheme,
989         const struct berval  *passwd,
990         struct berval *hash,
991         const char **text )
992 {
993         lutil_MD5_CTX   MD5context;
994         unsigned char   MD5digest[LUTIL_MD5_BYTES];
995         char            saltdata[SALT_SIZE];
996         struct berval digest;
997         struct berval salt;
998
999         digest.bv_val = (char *) MD5digest;
1000         digest.bv_len = sizeof(MD5digest);
1001         salt.bv_val = saltdata;
1002         salt.bv_len = sizeof(saltdata);
1003
1004         if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
1005                 return LUTIL_PASSWD_ERR; 
1006         }
1007
1008         lutil_MD5Init( &MD5context );
1009         lutil_MD5Update( &MD5context,
1010                 (const unsigned char *) passwd->bv_val, passwd->bv_len );
1011         lutil_MD5Update( &MD5context,
1012                 (const unsigned char *) salt.bv_val, salt.bv_len );
1013         lutil_MD5Final( MD5digest, &MD5context );
1014
1015         return pw_string64( scheme, &digest, hash, &salt );
1016 }
1017
1018 static int hash_md5(
1019         const struct berval *scheme,
1020         const struct berval  *passwd,
1021         struct berval *hash,
1022         const char **text )
1023 {
1024         lutil_MD5_CTX   MD5context;
1025         unsigned char   MD5digest[LUTIL_MD5_BYTES];
1026
1027         struct berval digest;
1028
1029         digest.bv_val = (char *) MD5digest;
1030         digest.bv_len = sizeof(MD5digest);
1031
1032         lutil_MD5Init( &MD5context );
1033         lutil_MD5Update( &MD5context,
1034                 (const unsigned char *) passwd->bv_val, passwd->bv_len );
1035         lutil_MD5Final( MD5digest, &MD5context );
1036
1037         return pw_string64( scheme, &digest, hash, NULL );
1038 ;
1039 }
1040
1041 #ifdef SLAPD_LMHASH 
1042 static int hash_lanman(
1043         const struct berval *scheme,
1044         const struct berval *passwd,
1045         struct berval *hash,
1046         const char **text )
1047 {
1048
1049         int i;
1050         char UcasePassword[15];
1051         des_cblock key;
1052         des_key_schedule schedule;
1053         des_cblock StdText = "KGS!@#$%";
1054         des_cblock PasswordHash1, PasswordHash2;
1055         char PasswordHash[33];
1056         
1057         for( i=0; i<passwd->bv_len; i++) {
1058                 if(passwd->bv_val[i] == '\0') {
1059                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
1060                 }
1061         }
1062         
1063         if( passwd->bv_val[i] != '\0' ) {
1064                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
1065         }
1066         
1067         strncpy( UcasePassword, passwd->bv_val, 14 );
1068         UcasePassword[14] = '\0';
1069         ldap_pvt_str2upper( UcasePassword );
1070         
1071         lmPasswd_to_key( UcasePassword, &key );
1072         des_set_key_unchecked( &key, schedule );
1073         des_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
1074         
1075         lmPasswd_to_key( &UcasePassword[7], &key );
1076         des_set_key_unchecked( &key, schedule );
1077         des_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
1078         
1079         sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
1080                 PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
1081                 PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
1082                 PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
1083                 PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
1084         
1085         hash->bv_val = PasswordHash;
1086         hash->bv_len = 32;
1087         
1088         return pw_string( scheme, hash );
1089 }
1090 #endif /* SLAPD_LMHASH */
1091
1092 #ifdef SLAPD_CRYPT
1093 static int hash_crypt(
1094         const struct berval *scheme,
1095         const struct berval *passwd,
1096         struct berval *hash,
1097         const char **text )
1098 {
1099         unsigned char salt[32]; /* salt suitable for most anything */
1100         unsigned int i;
1101
1102         for( i=0; i<passwd->bv_len; i++) {
1103                 if(passwd->bv_val[i] == '\0') {
1104                         return LUTIL_PASSWD_ERR;        /* NUL character in password */
1105                 }
1106         }
1107
1108         if( passwd->bv_val[i] != '\0' ) {
1109                 return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
1110         }
1111
1112         if( lutil_entropy( salt, sizeof( salt ) ) < 0 ) {
1113                 return LUTIL_PASSWD_ERR; 
1114         }
1115
1116         for( i=0; i< ( sizeof(salt) - 1 ); i++ ) {
1117                 salt[i] = crypt64[ salt[i] % (sizeof(crypt64)-1) ];
1118         }
1119         salt[sizeof( salt ) - 1 ] = '\0';
1120
1121         if( salt_format != NULL ) {
1122                 /* copy the salt we made into entropy before snprintfing
1123                    it back into the salt */
1124                 char entropy[sizeof(salt)];
1125                 strcpy( entropy, (char *) salt );
1126                 snprintf( (char *) salt, sizeof(entropy), salt_format, entropy );
1127         }
1128
1129         hash->bv_val = crypt( passwd->bv_val, (char *) salt );
1130
1131         if( hash->bv_val == NULL ) return -1;
1132
1133         hash->bv_len = strlen( hash->bv_val );
1134
1135         if( hash->bv_len == 0 ) {
1136                 return LUTIL_PASSWD_ERR;
1137         }
1138
1139         return pw_string( scheme, hash );
1140 }
1141 #endif
1142
1143 int lutil_salt_format(const char *format)
1144 {
1145 #ifdef SLAPD_CRYPT
1146         free( salt_format );
1147
1148         salt_format = format != NULL ? strdup( format ) : NULL;
1149 #endif
1150
1151         return 0;
1152 }
1153
1154 #ifdef SLAPD_CLEARTEXT
1155 static int hash_clear(
1156         const struct berval *scheme,
1157         const struct berval  *passwd,
1158         struct berval *hash,
1159         const char **text )
1160 {
1161         ber_dupbv( hash, (struct berval *)passwd );
1162         return LUTIL_PASSWD_OK;
1163 }
1164 #endif
1165