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