]> git.sur5r.net Git - openldap/blob - libraries/liblutil/passwd.c
c1bfa79e9bf5b4d2705594a9731cd61f08efed81
[openldap] / libraries / liblutil / passwd.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2003 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 #ifdef SLAPD_KPASSWD
45 #       include <ac/krb.h>
46 #       include <ac/krb5.h>
47 #endif
48
49 /* KPASSWD/krb.h brings in a conflicting des.h so don't use both.
50  * configure currently requires OpenSSL to enable LMHASH. Obviously
51  * this requirement can be fulfilled by the KRB DES library as well.
52  */
53 #if defined(SLAPD_LMHASH) && !defined(DES_ENCRYPT)
54 #       include <openssl/des.h>
55 #endif /* SLAPD_LMHASH */
56
57 #include <ac/param.h>
58
59 #ifdef SLAPD_CRYPT
60 # include <ac/crypt.h>
61
62 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
63 #  ifdef HAVE_SHADOW_H
64 #       include <shadow.h>
65 #  endif
66 #  ifdef HAVE_PWD_H
67 #       include <pwd.h>
68 #  endif
69 #  ifdef HAVE_AIX_SECURITY
70 #       include <userpw.h>
71 #  endif
72 # endif
73 #endif
74
75 #include <lber.h>
76
77 #include "ldap_pvt.h"
78 #include "lber_pvt.h"
79
80 #include "lutil_md5.h"
81 #include "lutil_sha1.h"
82 #include "lutil.h"
83
84 static const unsigned char crypt64[] =
85         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./";
86
87 #ifdef SLAPD_CRYPT
88 static char *salt_format = NULL;
89 #endif
90
91 struct pw_scheme {
92         struct berval name;
93         LUTIL_PASSWD_CHK_FUNC *chk_fn;
94         LUTIL_PASSWD_HASH_FUNC *hash_fn;
95 };
96
97 struct pw_slist {
98         struct pw_slist *next;
99         struct pw_scheme s;
100 };
101
102 /* password check routines */
103
104 #define SALT_SIZE       4
105
106 static LUTIL_PASSWD_CHK_FUNC chk_md5;
107 static LUTIL_PASSWD_CHK_FUNC chk_smd5;
108 static LUTIL_PASSWD_HASH_FUNC hash_smd5;
109 static LUTIL_PASSWD_HASH_FUNC hash_md5;
110
111
112 #ifdef LUTIL_SHA1_BYTES
113 static LUTIL_PASSWD_CHK_FUNC chk_ssha1;
114 static LUTIL_PASSWD_CHK_FUNC chk_sha1;
115 static LUTIL_PASSWD_HASH_FUNC hash_sha1;
116 static LUTIL_PASSWD_HASH_FUNC hash_ssha1;
117 #endif
118
119 #ifdef SLAPD_LMHASH
120 static LUTIL_PASSWD_CHK_FUNC chk_lanman;
121 static LUTIL_PASSWD_HASH_FUNC hash_lanman;
122 #endif
123
124 #ifdef SLAPD_NS_MTA_MD5
125 static LUTIL_PASSWD_CHK_FUNC chk_ns_mta_md5;
126 #endif
127
128 #ifdef SLAPD_SPASSWD
129 static LUTIL_PASSWD_CHK_FUNC chk_sasl;
130 #endif
131
132 #ifdef SLAPD_KPASSWD
133 static LUTIL_PASSWD_CHK_FUNC chk_kerberos;
134 #endif
135
136 #ifdef SLAPD_CRYPT
137 static LUTIL_PASSWD_CHK_FUNC chk_crypt;
138 static LUTIL_PASSWD_HASH_FUNC hash_crypt;
139
140 #if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
141 static LUTIL_PASSWD_CHK_FUNC chk_unix;
142 #endif
143 #endif
144
145 /* password hash routines */
146
147 #ifdef SLAPD_CLEARTEXT
148 static LUTIL_PASSWD_HASH_FUNC hash_clear;
149 #endif
150
151 static struct pw_slist *pw_schemes;
152
153 static const struct pw_scheme pw_schemes_default[] =
154 {
155 #ifdef LUTIL_SHA1_BYTES
156         { BER_BVC("{SSHA}"),            chk_ssha1, hash_ssha1 },
157         { BER_BVC("{SHA}"),                     chk_sha1, hash_sha1 },
158 #endif
159
160         { BER_BVC("{SMD5}"),            chk_smd5, hash_smd5 },
161         { BER_BVC("{MD5}"),                     chk_md5, hash_md5 },
162
163 #ifdef SLAPD_LMHASH
164         { BER_BVC("{LANMAN}"),          chk_lanman, hash_lanman },
165 #endif /* SLAPD_LMHASH */
166
167 #ifdef SLAPD_NS_MTA_MD5
168         { BER_BVC("{NS-MTA-MD5}"),      chk_ns_mta_md5, NULL },
169 #endif /* SLAPD_NS_MTA_MD5 */
170
171 #ifdef SLAPD_SPASSWD
172         { BER_BVC("{SASL}"),            chk_sasl, NULL },
173 #endif
174
175 #ifdef SLAPD_KPASSWD
176         { BER_BVC("{KERBEROS}"),        chk_kerberos, NULL },
177 #endif
178
179 #ifdef SLAPD_CRYPT
180         { BER_BVC("{CRYPT}"),           chk_crypt, hash_crypt },
181 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
182         { BER_BVC("{UNIX}"),            chk_unix, NULL },
183 # endif
184 #endif
185
186 #ifdef SLAPD_CLEARTEXT
187         /* pseudo scheme */
188         { {0, "{CLEARTEXT}"},           NULL, hash_clear },
189 #endif
190
191         { BER_BVNULL, NULL, NULL }
192 };
193
194 int lutil_passwd_add(
195         struct berval *scheme,
196         LUTIL_PASSWD_CHK_FUNC *chk,
197         LUTIL_PASSWD_HASH_FUNC *hash )
198 {
199         struct pw_slist *ptr;
200
201         ptr = ber_memalloc( sizeof( struct pw_slist ));
202         if (!ptr) return -1;
203         ptr->next = pw_schemes;
204         ptr->s.name = *scheme;
205         ptr->s.chk_fn = chk;
206         ptr->s.hash_fn = hash;
207         pw_schemes = ptr;
208         return 0;
209 }
210
211 void lutil_passwd_init()
212 {
213         struct pw_slist *ptr;
214         struct pw_scheme *s;
215
216         for( s=(struct pw_scheme *)pw_schemes_default; s->name.bv_val; s++) {
217                 if ( lutil_passwd_add( &s->name, s->chk_fn, s->hash_fn )) break;
218         }
219 }
220
221 void lutil_passwd_destroy()
222 {
223         struct pw_slist *ptr, *next;
224
225         for( ptr=pw_schemes; ptr; ptr=next ) {
226                 next = ptr->next;
227                 ber_memfree( ptr );
228         }
229 }
230
231 static const struct pw_scheme *get_scheme(
232         const char* scheme )
233 {
234         struct pw_slist *pws;
235
236         if (!pw_schemes) lutil_passwd_init();
237
238         for( pws=pw_schemes; pws; pws=pws->next ) {
239                 if( strcasecmp(scheme, pws->s.name.bv_val ) == 0 ) {
240                         return &(pws->s);
241                 }
242         }
243
244         return NULL;
245 }
246
247 int lutil_passwd_scheme(
248         const char* scheme )
249 {
250         if( scheme == NULL ) {
251                 return 0;
252         }
253
254         return get_scheme(scheme) != NULL;
255 }
256
257
258 static int is_allowed_scheme( 
259         const char* scheme,
260         const char** schemes )
261 {
262         int i;
263
264         if( schemes == NULL ) return 1;
265
266         for( i=0; schemes[i] != NULL; i++ ) {
267                 if( strcasecmp( scheme, schemes[i] ) == 0 ) {
268                         return 1;
269                 }
270         }
271         return 0;
272 }
273
274 static struct berval *passwd_scheme(
275         const struct pw_scheme *scheme,
276         const struct berval * passwd,
277         struct berval *bv,
278         const char** allowed )
279 {
280         if( !is_allowed_scheme( scheme->name.bv_val, allowed ) ) {
281                 return NULL;
282         }
283
284         if( passwd->bv_len >= scheme->name.bv_len ) {
285                 if( strncasecmp( passwd->bv_val, scheme->name.bv_val, scheme->name.bv_len ) == 0 ) {
286                         bv->bv_val = &passwd->bv_val[scheme->name.bv_len];
287                         bv->bv_len = passwd->bv_len - scheme->name.bv_len;
288
289                         return bv;
290                 }
291         }
292
293         return NULL;
294 }
295
296 /*
297  * Return 0 if creds are good.
298  */
299 int
300 lutil_passwd(
301         const struct berval *passwd,    /* stored passwd */
302         const struct berval *cred,              /* user cred */
303         const char **schemes,
304         const char **text )
305 {
306         struct pw_slist *pws;
307
308         if ( text ) *text = NULL;
309
310         if (cred == NULL || cred->bv_len == 0 ||
311                 passwd == NULL || passwd->bv_len == 0 )
312         {
313                 return -1;
314         }
315
316         if (!pw_schemes) lutil_passwd_init();
317
318         for( pws=pw_schemes; pws; pws=pws->next ) {
319                 if( pws->s.chk_fn ) {
320                         struct berval x;
321                         struct berval *p = passwd_scheme( &(pws->s),
322                                 passwd, &x, schemes );
323
324                         if( p != NULL ) {
325                                 return (pws->s.chk_fn)( &(pws->s.name), p, cred, text );
326                         }
327                 }
328         }
329
330 #ifdef SLAPD_CLEARTEXT
331         if( is_allowed_scheme("{CLEARTEXT}", schemes ) ) {
332                 return (( passwd->bv_len == cred->bv_len ) &&
333                                 ( passwd->bv_val[0] != '{' /*'}'*/ ))
334                         ? memcmp( passwd->bv_val, cred->bv_val, passwd->bv_len )
335                         : 1;
336         }
337 #endif
338         return 1;
339 }
340
341 struct berval * lutil_passwd_generate( ber_len_t len )
342 {
343         struct berval *pw;
344
345         if( len < 1 ) return NULL;
346
347         pw = ber_memalloc( sizeof( struct berval ) );
348         if( pw == NULL ) return NULL;
349
350         pw->bv_len = len;
351         pw->bv_val = ber_memalloc( len + 1 );
352
353         if( pw->bv_val == NULL ) {
354                 ber_memfree( pw );
355                 return NULL;
356         }
357
358         if( lutil_entropy( (unsigned char *) pw->bv_val, pw->bv_len) < 0 ) {
359                 ber_bvfree( pw );
360                 return NULL; 
361         }
362
363         for( len = 0; len < pw->bv_len; len++ ) {
364                 pw->bv_val[len] = crypt64[
365                         pw->bv_val[len] % (sizeof(crypt64)-1) ];
366         }
367
368         pw->bv_val[len] = '\0';
369         
370         return pw;
371 }
372
373 struct berval * lutil_passwd_hash(
374         const struct berval * passwd,
375         const char * method,
376         const char **text )
377 {
378         const struct pw_scheme *sc = get_scheme( method );
379
380         if( text ) *text = NULL;
381         if( sc == NULL ) return NULL;
382         if( ! sc->hash_fn ) return NULL;
383
384         return (sc->hash_fn)( &sc->name, passwd, text );
385 }
386
387 /* pw_string is only called when SLAPD_LMHASH or SLAPD_CRYPT is defined */
388 #if defined(SLAPD_LMHASH) || defined(SLAPD_CRYPT)
389 static struct berval * pw_string(
390         const struct berval *sc,
391         const struct berval *passwd )
392 {
393         struct berval *pw = ber_memalloc( sizeof( struct berval ) );
394         if( pw == NULL ) return NULL;
395
396         pw->bv_len = sc->bv_len + passwd->bv_len;
397         pw->bv_val = ber_memalloc( pw->bv_len + 1 );
398
399         if( pw->bv_val == NULL ) {
400                 ber_memfree( pw );
401                 return NULL;
402         }
403
404         AC_MEMCPY( pw->bv_val, sc->bv_val, sc->bv_len );
405         AC_MEMCPY( &pw->bv_val[sc->bv_len], passwd->bv_val, passwd->bv_len );
406
407         pw->bv_val[pw->bv_len] = '\0';
408         return pw;
409 }
410 #endif /* SLAPD_LMHASH || SLAPD_CRYPT */
411
412 static struct berval * pw_string64(
413         const struct berval *sc,
414         const struct berval *hash,
415         const struct berval *salt )
416 {
417         int rc;
418         struct berval string;
419         struct berval *b64 = ber_memalloc( sizeof(struct berval) );
420         size_t b64len;
421
422         if( b64 == NULL ) return NULL;
423
424         if( salt ) {
425                 /* need to base64 combined string */
426                 string.bv_len = hash->bv_len + salt->bv_len;
427                 string.bv_val = ber_memalloc( string.bv_len + 1 );
428
429                 if( string.bv_val == NULL ) {
430                         ber_memfree( b64 );
431                         return NULL;
432                 }
433
434                 AC_MEMCPY( string.bv_val, hash->bv_val,
435                         hash->bv_len );
436                 AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,
437                         salt->bv_len );
438                 string.bv_val[string.bv_len] = '\0';
439
440         } else {
441                 string = *hash;
442         }
443
444         b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;
445         b64->bv_len = b64len + sc->bv_len;
446         b64->bv_val = ber_memalloc( b64->bv_len + 1 );
447
448         if( b64->bv_val == NULL ) {
449                 if( salt ) ber_memfree( string.bv_val );
450                 ber_memfree( b64 );
451                 return NULL;
452         }
453
454         AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);
455
456         rc = lutil_b64_ntop(
457                 (unsigned char *) string.bv_val, string.bv_len,
458                 &b64->bv_val[sc->bv_len], b64len );
459
460         if( salt ) ber_memfree( string.bv_val );
461         
462         if( rc < 0 ) {
463                 ber_bvfree( b64 );
464                 return NULL;
465         }
466
467         /* recompute length */
468         b64->bv_len = sc->bv_len + rc;
469         assert( strlen(b64->bv_val) == b64->bv_len );
470         return b64;
471 }
472
473 /* PASSWORD CHECK ROUTINES */
474
475 #ifdef LUTIL_SHA1_BYTES
476 static int chk_ssha1(
477         const struct berval *sc,
478         const struct berval * passwd,
479         const struct berval * cred,
480         const char **text )
481 {
482         lutil_SHA1_CTX SHA1context;
483         unsigned char SHA1digest[LUTIL_SHA1_BYTES];
484         int rc;
485         unsigned char *orig_pass = NULL;
486
487         /* safety check */
488         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <
489                 sizeof(SHA1digest)+SALT_SIZE) {
490                 return -1;
491         }
492
493         /* decode base64 password */
494         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
495                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
496
497         if( orig_pass == NULL ) return -1;
498
499         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
500
501         if (rc < (int)(sizeof(SHA1digest)+SALT_SIZE)) {
502                 ber_memfree(orig_pass);
503                 return -1;
504         }
505  
506         /* hash credentials with salt */
507         lutil_SHA1Init(&SHA1context);
508         lutil_SHA1Update(&SHA1context,
509                 (const unsigned char *) cred->bv_val, cred->bv_len);
510         lutil_SHA1Update(&SHA1context,
511                 (const unsigned char *) &orig_pass[sizeof(SHA1digest)],
512                 rc - sizeof(SHA1digest));
513         lutil_SHA1Final(SHA1digest, &SHA1context);
514  
515         /* compare */
516         rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
517         ber_memfree(orig_pass);
518         return rc ? 1 : 0;
519 }
520
521 static int chk_sha1(
522         const struct berval *sc,
523         const struct berval * passwd,
524         const struct berval * cred,
525         const char **text )
526 {
527         lutil_SHA1_CTX SHA1context;
528         unsigned char SHA1digest[LUTIL_SHA1_BYTES];
529         int rc;
530         unsigned char *orig_pass = NULL;
531  
532         /* safety check */
533         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(SHA1digest)) {
534                 return -1;
535         }
536
537         /* base64 un-encode password */
538         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
539                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
540
541         if( orig_pass == NULL ) return -1;
542
543         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
544
545         if( rc != sizeof(SHA1digest) ) {
546                 ber_memfree(orig_pass);
547                 return -1;
548         }
549  
550         /* hash credentials with salt */
551         lutil_SHA1Init(&SHA1context);
552         lutil_SHA1Update(&SHA1context,
553                 (const unsigned char *) cred->bv_val, cred->bv_len);
554         lutil_SHA1Final(SHA1digest, &SHA1context);
555  
556         /* compare */
557         rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
558         ber_memfree(orig_pass);
559         return rc ? 1 : 0;
560 }
561 #endif
562
563 static int chk_smd5(
564         const struct berval *sc,
565         const struct berval * passwd,
566         const struct berval * cred,
567         const char **text )
568 {
569         lutil_MD5_CTX MD5context;
570         unsigned char MD5digest[LUTIL_MD5_BYTES];
571         int rc;
572         unsigned char *orig_pass = NULL;
573
574         /* safety check */
575         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) <
576                 sizeof(MD5digest)+SALT_SIZE) {
577                 return -1;
578         }
579
580         /* base64 un-encode password */
581         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
582                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
583
584         if( orig_pass == NULL ) return -1;
585
586         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
587
588         if (rc < (int)(sizeof(MD5digest)+SALT_SIZE)) {
589                 ber_memfree(orig_pass);
590                 return -1;
591         }
592
593         /* hash credentials with salt */
594         lutil_MD5Init(&MD5context);
595         lutil_MD5Update(&MD5context,
596                 (const unsigned char *) cred->bv_val,
597                 cred->bv_len );
598         lutil_MD5Update(&MD5context,
599                 &orig_pass[sizeof(MD5digest)],
600                 rc - sizeof(MD5digest));
601         lutil_MD5Final(MD5digest, &MD5context);
602
603         /* compare */
604         rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
605         ber_memfree(orig_pass);
606         return rc ? 1 : 0;
607 }
608
609 static int chk_md5(
610         const struct berval *sc,
611         const struct berval * passwd,
612         const struct berval * cred,
613         const char **text )
614 {
615         lutil_MD5_CTX MD5context;
616         unsigned char MD5digest[LUTIL_MD5_BYTES];
617         int rc;
618         unsigned char *orig_pass = NULL;
619
620         /* safety check */
621         if (LUTIL_BASE64_DECODE_LEN(passwd->bv_len) < sizeof(MD5digest)) {
622                 return -1;
623         }
624
625         /* base64 un-encode password */
626         orig_pass = (unsigned char *) ber_memalloc( (size_t) (
627                 LUTIL_BASE64_DECODE_LEN(passwd->bv_len) + 1) );
628
629         if( orig_pass == NULL ) return -1;
630
631         rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);
632         if ( rc != sizeof(MD5digest) ) {
633                 ber_memfree(orig_pass);
634                 return -1;
635         }
636
637         /* hash credentials with salt */
638         lutil_MD5Init(&MD5context);
639         lutil_MD5Update(&MD5context,
640                 (const unsigned char *) cred->bv_val,
641                 cred->bv_len );
642         lutil_MD5Final(MD5digest, &MD5context);
643
644         /* compare */
645         rc = memcmp((char *)orig_pass, (char *)MD5digest, sizeof(MD5digest));
646         ber_memfree(orig_pass);
647         return rc ? 1 : 0;
648 }
649
650 #ifdef SLAPD_LMHASH
651 /* pseudocode from RFC2433
652  * A.2 LmPasswordHash()
653  * 
654  *    LmPasswordHash(
655  *    IN  0-to-14-oem-char Password,
656  *    OUT 16-octet         PasswordHash )
657  *    {
658  *       Set UcasePassword to the uppercased Password
659  *       Zero pad UcasePassword to 14 characters
660  * 
661  *       DesHash( 1st 7-octets of UcasePassword,
662  *                giving 1st 8-octets of PasswordHash )
663  * 
664  *       DesHash( 2nd 7-octets of UcasePassword,
665  *                giving 2nd 8-octets of PasswordHash )
666  *    }
667  * 
668  * 
669  * A.3 DesHash()
670  * 
671  *    DesHash(
672  *    IN  7-octet Clear,
673  *    OUT 8-octet Cypher )
674  *    {
675  *        *
676  *        * Make Cypher an irreversibly encrypted form of Clear by
677  *        * encrypting known text using Clear as the secret key.
678  *        * The known text consists of the string
679  *        *
680  *        *              KGS!@#$%
681  *        *
682  * 
683  *       Set StdText to "KGS!@#$%"
684  *       DesEncrypt( StdText, Clear, giving Cypher )
685  *    }
686  * 
687  * 
688  * A.4 DesEncrypt()
689  * 
690  *    DesEncrypt(
691  *    IN  8-octet Clear,
692  *    IN  7-octet Key,
693  *    OUT 8-octet Cypher )
694  *    {
695  *        *
696  *        * Use the DES encryption algorithm [4] in ECB mode [9]
697  *        * to encrypt Clear into Cypher such that Cypher can
698  *        * only be decrypted back to Clear by providing Key.
699  *        * Note that the DES algorithm takes as input a 64-bit
700  *        * stream where the 8th, 16th, 24th, etc.  bits are
701  *        * parity bits ignored by the encrypting algorithm.
702  *        * Unless you write your own DES to accept 56-bit input
703  *        * without parity, you will need to insert the parity bits
704  *        * yourself.
705  *        *
706  *    }
707  */
708
709 static void lmPasswd_to_key(
710         const unsigned char *lmPasswd,
711         des_cblock *key)
712 {
713         /* make room for parity bits */
714         ((char *)key)[0] = lmPasswd[0];
715         ((char *)key)[1] = ((lmPasswd[0]&0x01)<<7) | (lmPasswd[1]>>1);
716         ((char *)key)[2] = ((lmPasswd[1]&0x03)<<6) | (lmPasswd[2]>>2);
717         ((char *)key)[3] = ((lmPasswd[2]&0x07)<<5) | (lmPasswd[3]>>3);
718         ((char *)key)[4] = ((lmPasswd[3]&0x0F)<<4) | (lmPasswd[4]>>4);
719         ((char *)key)[5] = ((lmPasswd[4]&0x1F)<<3) | (lmPasswd[5]>>5);
720         ((char *)key)[6] = ((lmPasswd[5]&0x3F)<<2) | (lmPasswd[6]>>6);
721         ((char *)key)[7] = ((lmPasswd[6]&0x7F)<<1);
722                 
723         des_set_odd_parity( key );
724 }       
725
726 static int chk_lanman(
727         const struct berval *scheme,
728         const struct berval *passwd,
729         const struct berval *cred,
730         const char **text )
731 {
732         int i;
733         char UcasePassword[15];
734         des_cblock key;
735         des_key_schedule schedule;
736         des_cblock StdText = "KGS!@#$%";
737         des_cblock PasswordHash1, PasswordHash2;
738         char PasswordHash[33], storedPasswordHash[33];
739         
740         for( i=0; i<cred->bv_len; i++) {
741                 if(cred->bv_val[i] == '\0') {
742                         return -1;      /* NUL character in password */
743                 }
744         }
745         
746         if( cred->bv_val[i] != '\0' ) {
747                 return -1;      /* passwd must behave like a string */
748         }
749         
750         strncpy( UcasePassword, cred->bv_val, 14 );
751         UcasePassword[14] = '\0';
752         ldap_pvt_str2upper( UcasePassword );
753         
754         lmPasswd_to_key( UcasePassword, &key );
755         des_set_key_unchecked( &key, schedule );
756         des_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
757         
758         lmPasswd_to_key( &UcasePassword[7], &key );
759         des_set_key_unchecked( &key, schedule );
760         des_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
761         
762         sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
763                 PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
764                 PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
765                 PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
766                 PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
767         
768         /* as a precaution convert stored password hash to lower case */
769         strncpy( storedPasswordHash, passwd->bv_val, 32 );
770         storedPasswordHash[32] = '\0';
771         ldap_pvt_str2lower( storedPasswordHash );
772         
773         return memcmp( PasswordHash, storedPasswordHash, 32) ? 1 : 0;
774 }
775 #endif /* SLAPD_LMHASH */
776
777 #ifdef SLAPD_NS_MTA_MD5
778 static int chk_ns_mta_md5(
779         const struct berval *scheme,
780         const struct berval *passwd,
781         const struct berval *cred,
782         const char **text )
783 {
784         lutil_MD5_CTX MD5context;
785         unsigned char MD5digest[LUTIL_MD5_BYTES], c;
786         char buffer[LUTIL_MD5_BYTES*2];
787         int i;
788
789         if( passwd->bv_len != LUTIL_MD5_BYTES*2 ) {
790                 return 1;
791         }
792
793         /* hash credentials with salt */
794         lutil_MD5Init(&MD5context);
795         lutil_MD5Update(&MD5context,
796                 (const unsigned char *) &passwd->bv_val[32],
797                 32 );
798
799         c = 0x59;
800         lutil_MD5Update(&MD5context,
801                 (const unsigned char *) &c,
802                 1 );
803
804         lutil_MD5Update(&MD5context,
805                 (const unsigned char *) cred->bv_val,
806                 cred->bv_len );
807
808         c = 0xF7;
809         lutil_MD5Update(&MD5context,
810                 (const unsigned char *) &c,
811                 1 );
812
813         lutil_MD5Update(&MD5context,
814                 (const unsigned char *) &passwd->bv_val[32],
815                 32 );
816
817         lutil_MD5Final(MD5digest, &MD5context);
818
819         for( i=0; i < sizeof( MD5digest ); i++ ) {
820                 buffer[i+i]   = "0123456789abcdef"[(MD5digest[i]>>4) & 0x0F]; 
821                 buffer[i+i+1] = "0123456789abcdef"[ MD5digest[i] & 0x0F]; 
822         }
823
824         /* compare */
825         return memcmp((char *)passwd->bv_val,
826                 (char *)buffer, sizeof(buffer)) ? 1 : 0;
827 }
828 #endif
829
830 #ifdef SLAPD_SPASSWD
831 #ifdef HAVE_CYRUS_SASL
832 sasl_conn_t *lutil_passwd_sasl_conn = NULL;
833 #endif
834
835 static int chk_sasl(
836         const struct berval *sc,
837         const struct berval * passwd,
838         const struct berval * cred,
839         const char **text )
840 {
841         unsigned int i;
842         int rtn;
843
844         for( i=0; i<cred->bv_len; i++) {
845                 if(cred->bv_val[i] == '\0') {
846                         return 1;       /* NUL character in password */
847                 }
848         }
849
850         if( cred->bv_val[i] != '\0' ) {
851                 return 1;       /* cred must behave like a string */
852         }
853
854         for( i=0; i<passwd->bv_len; i++) {
855                 if(passwd->bv_val[i] == '\0') {
856                         return 1;       /* NUL character in password */
857                 }
858         }
859
860         if( passwd->bv_val[i] != '\0' ) {
861                 return 1;       /* passwd must behave like a string */
862         }
863
864         rtn = 1;
865
866 #ifdef HAVE_CYRUS_SASL
867         if( lutil_passwd_sasl_conn != NULL ) {
868                 int sc;
869 # if SASL_VERSION_MAJOR < 2
870                 sc = sasl_checkpass( lutil_passwd_sasl_conn,
871                         passwd->bv_val, passwd->bv_len,
872                         cred->bv_val, cred->bv_len,
873                         text );
874 # else
875                 sc = sasl_checkpass( lutil_passwd_sasl_conn,
876                         passwd->bv_val, passwd->bv_len,
877                         cred->bv_val, cred->bv_len );
878 # endif
879                 rtn = ( sc != SASL_OK );
880         }
881 #endif
882
883         return rtn;
884 }
885 #endif
886
887 #ifdef SLAPD_KPASSWD
888 static int chk_kerberos(
889         const struct berval *sc,
890         const struct berval * passwd,
891         const struct berval * cred,
892         const char **text )
893 {
894         unsigned int i;
895         int rtn;
896
897         for( i=0; i<cred->bv_len; i++) {
898                 if(cred->bv_val[i] == '\0') {
899                         return 1;       /* NUL character in password */
900                 }
901         }
902
903         if( cred->bv_val[i] != '\0' ) {
904                 return 1;       /* cred must behave like a string */
905         }
906
907         for( i=0; i<passwd->bv_len; i++) {
908                 if(passwd->bv_val[i] == '\0') {
909                         return 1;       /* NUL character in password */
910                 }
911         }
912
913         if( passwd->bv_val[i] != '\0' ) {
914                 return 1;       /* passwd must behave like a string */
915         }
916
917         rtn = 1;
918
919 #ifdef HAVE_KRB5 /* HAVE_HEIMDAL_KRB5 */
920         {
921 /* Portions:
922  * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\xf6gskolan
923  * (Royal Institute of Technology, Stockholm, Sweden).
924  * All rights reserved.
925  *
926  * Redistribution and use in source and binary forms, with or without
927  * modification, are permitted provided that the following conditions
928  * are met:
929  *
930  * 1. Redistributions of source code must retain the above copyright
931  *    notice, this list of conditions and the following disclaimer.
932  *
933  * 2. Redistributions in binary form must reproduce the above copyright
934  *    notice, this list of conditions and the following disclaimer in the
935  *    documentation and/or other materials provided with the distribution.
936  *
937  * 3. Neither the name of the Institute nor the names of its contributors
938  *    may be used to endorse or promote products derived from this software
939  *    without specific prior written permission.
940  *
941  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
942  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
943  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
944  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
945  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
946  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
947  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
948  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
949  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
950  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
951  * SUCH DAMAGE.
952  */
953
954                 krb5_context context;
955                 krb5_error_code ret;
956                 krb5_creds creds;
957                 krb5_get_init_creds_opt get_options;
958                 krb5_verify_init_creds_opt verify_options;
959                 krb5_principal client, server;
960 #ifdef notdef
961                 krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
962 #endif
963
964                 ret = krb5_init_context( &context );
965                 if (ret) {
966                         return 1;
967                 }
968
969 #ifdef notdef
970                 krb5_get_init_creds_opt_set_preauth_list(&get_options,
971                         pre_auth_types, 1);
972 #endif
973
974                 krb5_get_init_creds_opt_init( &get_options );
975
976                 krb5_verify_init_creds_opt_init( &verify_options );
977         
978                 ret = krb5_parse_name( context, passwd->bv_val, &client );
979
980                 if (ret) {
981                         krb5_free_context( context );
982                         return 1;
983                 }
984
985                 ret = krb5_get_init_creds_password( context,
986                         &creds, client, cred->bv_val, NULL,
987                         NULL, 0, NULL, &get_options );
988
989                 if (ret) {
990                         krb5_free_principal( context, client );
991                         krb5_free_context( context );
992                         return 1;
993                 }
994
995                 {
996                         char *host = ldap_pvt_get_fqdn( NULL );
997
998                         if( host == NULL ) {
999                                 krb5_free_principal( context, client );
1000                                 krb5_free_context( context );
1001                                 return 1;
1002                         }
1003
1004                         ret = krb5_sname_to_principal( context,
1005                                 host, "ldap", KRB5_NT_SRV_HST, &server );
1006
1007                         ber_memfree( host );
1008                 }
1009
1010                 if (ret) {
1011                         krb5_free_principal( context, client );
1012                         krb5_free_context( context );
1013                         return 1;
1014                 }
1015
1016                 ret = krb5_verify_init_creds( context,
1017                         &creds, server, NULL, NULL, &verify_options );
1018
1019                 krb5_free_principal( context, client );
1020                 krb5_free_principal( context, server );
1021                 krb5_free_cred_contents( context, &creds );
1022                 krb5_free_context( context );
1023
1024                 rtn = !!ret;
1025         }
1026 #elif   defined(HAVE_KRB4)
1027         {
1028                 /* Borrowed from Heimdal kpopper */
1029 /* Portions:
1030  * Copyright (c) 1989 Regents of the University of California.
1031  * All rights reserved.  The Berkeley software License Agreement
1032  * specifies the terms and conditions for redistribution.
1033  */
1034
1035                 int status;
1036                 char lrealm[REALM_SZ];
1037                 char tkt[MAXHOSTNAMELEN];
1038
1039                 status = krb_get_lrealm(lrealm,1);
1040                 if (status == KFAILURE) {
1041                         return 1;
1042                 }
1043
1044                 snprintf(tkt, sizeof(tkt), "%s_slapd.%u",
1045                         TKT_ROOT, (unsigned)getpid());
1046                 krb_set_tkt_string (tkt);
1047
1048                 status = krb_verify_user( passwd->bv_val, "", lrealm,
1049                         cred->bv_val, 1, "ldap");
1050
1051                 dest_tkt(); /* no point in keeping the tickets */
1052
1053                 return status == KFAILURE;
1054         }
1055 #endif
1056
1057         return rtn;
1058 }
1059 #endif /* SLAPD_KPASSWD */
1060
1061 #ifdef SLAPD_CRYPT
1062 static int chk_crypt(
1063         const struct berval *sc,
1064         const struct berval * passwd,
1065         const struct berval * cred,
1066         const char **text )
1067 {
1068         char *cr;
1069         unsigned int i;
1070
1071         for( i=0; i<cred->bv_len; i++) {
1072                 if(cred->bv_val[i] == '\0') {
1073                         return 1;       /* NUL character in password */
1074                 }
1075         }
1076
1077         if( cred->bv_val[i] != '\0' ) {
1078                 return -1;      /* cred must behave like a string */
1079         }
1080
1081         if( passwd->bv_len < 2 ) {
1082                 return -1;      /* passwd must be at least two characters long */
1083         }
1084
1085         for( i=0; i<passwd->bv_len; i++) {
1086                 if(passwd->bv_val[i] == '\0') {
1087                         return -1;      /* NUL character in password */
1088                 }
1089         }
1090
1091         if( passwd->bv_val[i] != '\0' ) {
1092                 return -1;      /* passwd must behave like a string */
1093         }
1094
1095         cr = crypt( cred->bv_val, passwd->bv_val );
1096
1097         if( cr == NULL || cr[0] == '\0' ) {
1098                 /* salt must have been invalid */
1099                 return -1;
1100         }
1101
1102         return strcmp( passwd->bv_val, cr ) ? 1 : 0;
1103 }
1104
1105 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
1106 static int chk_unix(
1107         const struct berval *sc,
1108         const struct berval * passwd,
1109         const struct berval * cred,
1110         const char **text )
1111 {
1112         unsigned int i;
1113         char *pw,*cr;
1114
1115         for( i=0; i<cred->bv_len; i++) {
1116                 if(cred->bv_val[i] == '\0') {
1117                         return -1;      /* NUL character in password */
1118                 }
1119         }
1120         if( cred->bv_val[i] != '\0' ) {
1121                 return -1;      /* cred must behave like a string */
1122         }
1123
1124         for( i=0; i<passwd->bv_len; i++) {
1125                 if(passwd->bv_val[i] == '\0') {
1126                         return -1;      /* NUL character in password */
1127                 }
1128         }
1129
1130         if( passwd->bv_val[i] != '\0' ) {
1131                 return -1;      /* passwd must behave like a string */
1132         }
1133
1134         {
1135                 struct passwd *pwd = getpwnam(passwd->bv_val);
1136
1137                 if(pwd == NULL) {
1138                         return -1;      /* not found */
1139                 }
1140
1141                 pw = pwd->pw_passwd;
1142         }
1143 #  ifdef HAVE_GETSPNAM
1144         {
1145                 struct spwd *spwd = getspnam(passwd->bv_val);
1146
1147                 if(spwd != NULL) {
1148                         pw = spwd->sp_pwdp;
1149                 }
1150         }
1151 #  endif
1152 #  ifdef HAVE_AIX_SECURITY
1153         {
1154                 struct userpw *upw = getuserpw(passwd->bv_val);
1155
1156                 if (upw != NULL) {
1157                         pw = upw->upw_passwd;
1158                 }
1159         }
1160 #  endif
1161
1162         if( pw == NULL || pw[0] == '\0' || pw[1] == '\0' ) {
1163                 /* password must must be at least two characters long */
1164                 return -1;
1165         }
1166
1167         cr = crypt(cred->bv_val, pw);
1168
1169         if( cr == NULL || cr[0] == '\0' ) {
1170                 /* salt must have been invalid */
1171                 return -1;
1172         }
1173
1174         return strcmp(pw, cr) ? 1 : 0;
1175
1176 }
1177 # endif
1178 #endif
1179
1180 /* PASSWORD GENERATION ROUTINES */
1181
1182 #ifdef LUTIL_SHA1_BYTES
1183 static struct berval *hash_ssha1(
1184         const struct berval *scheme,
1185         const struct berval  *passwd,
1186         const char **text )
1187 {
1188         lutil_SHA1_CTX  SHA1context;
1189         unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
1190         char            saltdata[SALT_SIZE];
1191         struct berval digest;
1192         struct berval salt;
1193
1194         digest.bv_val = (char *) SHA1digest;
1195         digest.bv_len = sizeof(SHA1digest);
1196         salt.bv_val = saltdata;
1197         salt.bv_len = sizeof(saltdata);
1198
1199         if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
1200                 return NULL; 
1201         }
1202
1203         lutil_SHA1Init( &SHA1context );
1204         lutil_SHA1Update( &SHA1context,
1205                 (const unsigned char *)passwd->bv_val, passwd->bv_len );
1206         lutil_SHA1Update( &SHA1context,
1207                 (const unsigned char *)salt.bv_val, salt.bv_len );
1208         lutil_SHA1Final( SHA1digest, &SHA1context );
1209
1210         return pw_string64( scheme, &digest, &salt);
1211 }
1212
1213 static struct berval *hash_sha1(
1214         const struct berval *scheme,
1215         const struct berval  *passwd,
1216         const char **text )
1217 {
1218         lutil_SHA1_CTX  SHA1context;
1219         unsigned char   SHA1digest[LUTIL_SHA1_BYTES];
1220         struct berval digest;
1221         digest.bv_val = (char *) SHA1digest;
1222         digest.bv_len = sizeof(SHA1digest);
1223      
1224         lutil_SHA1Init( &SHA1context );
1225         lutil_SHA1Update( &SHA1context,
1226                 (const unsigned char *)passwd->bv_val, passwd->bv_len );
1227         lutil_SHA1Final( SHA1digest, &SHA1context );
1228             
1229         return pw_string64( scheme, &digest, NULL);
1230 }
1231 #endif
1232
1233 static struct berval *hash_smd5(
1234         const struct berval *scheme,
1235         const struct berval  *passwd,
1236         const char **text )
1237 {
1238         lutil_MD5_CTX   MD5context;
1239         unsigned char   MD5digest[LUTIL_MD5_BYTES];
1240         char            saltdata[SALT_SIZE];
1241         struct berval digest;
1242         struct berval salt;
1243
1244         digest.bv_val = (char *) MD5digest;
1245         digest.bv_len = sizeof(MD5digest);
1246         salt.bv_val = saltdata;
1247         salt.bv_len = sizeof(saltdata);
1248
1249         if( lutil_entropy( (unsigned char *) salt.bv_val, salt.bv_len) < 0 ) {
1250                 return NULL; 
1251         }
1252
1253         lutil_MD5Init( &MD5context );
1254         lutil_MD5Update( &MD5context,
1255                 (const unsigned char *) passwd->bv_val, passwd->bv_len );
1256         lutil_MD5Update( &MD5context,
1257                 (const unsigned char *) salt.bv_val, salt.bv_len );
1258         lutil_MD5Final( MD5digest, &MD5context );
1259
1260         return pw_string64( scheme, &digest, &salt );
1261 }
1262
1263 static struct berval *hash_md5(
1264         const struct berval *scheme,
1265         const struct berval  *passwd,
1266         const char **text )
1267 {
1268         lutil_MD5_CTX   MD5context;
1269         unsigned char   MD5digest[LUTIL_MD5_BYTES];
1270
1271         struct berval digest;
1272
1273         digest.bv_val = (char *) MD5digest;
1274         digest.bv_len = sizeof(MD5digest);
1275
1276         lutil_MD5Init( &MD5context );
1277         lutil_MD5Update( &MD5context,
1278                 (const unsigned char *) passwd->bv_val, passwd->bv_len );
1279         lutil_MD5Final( MD5digest, &MD5context );
1280
1281         return pw_string64( scheme, &digest, NULL );
1282 ;
1283 }
1284
1285 #ifdef SLAPD_LMHASH 
1286 static struct berval *hash_lanman(
1287         const struct berval *scheme,
1288         const struct berval *passwd,
1289         const char **text )
1290 {
1291
1292         int i;
1293         char UcasePassword[15];
1294         des_cblock key;
1295         des_key_schedule schedule;
1296         des_cblock StdText = "KGS!@#$%";
1297         des_cblock PasswordHash1, PasswordHash2;
1298         char PasswordHash[33];
1299         struct berval hash;
1300         
1301         for( i=0; i<passwd->bv_len; i++) {
1302                 if(passwd->bv_val[i] == '\0') {
1303                         return NULL;    /* NUL character in password */
1304                 }
1305         }
1306         
1307         if( passwd->bv_val[i] != '\0' ) {
1308                 return NULL;    /* passwd must behave like a string */
1309         }
1310         
1311         strncpy( UcasePassword, passwd->bv_val, 14 );
1312         UcasePassword[14] = '\0';
1313         ldap_pvt_str2upper( UcasePassword );
1314         
1315         lmPasswd_to_key( UcasePassword, &key );
1316         des_set_key_unchecked( &key, schedule );
1317         des_ecb_encrypt( &StdText, &PasswordHash1, schedule , DES_ENCRYPT );
1318         
1319         lmPasswd_to_key( &UcasePassword[7], &key );
1320         des_set_key_unchecked( &key, schedule );
1321         des_ecb_encrypt( &StdText, &PasswordHash2, schedule , DES_ENCRYPT );
1322         
1323         sprintf( PasswordHash, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
1324                 PasswordHash1[0],PasswordHash1[1],PasswordHash1[2],PasswordHash1[3],
1325                 PasswordHash1[4],PasswordHash1[5],PasswordHash1[6],PasswordHash1[7],
1326                 PasswordHash2[0],PasswordHash2[1],PasswordHash2[2],PasswordHash2[3],
1327                 PasswordHash2[4],PasswordHash2[5],PasswordHash2[6],PasswordHash2[7] );
1328         
1329         hash.bv_val = PasswordHash;
1330         hash.bv_len = 32;
1331         
1332         return pw_string( scheme, &hash );
1333 }
1334 #endif /* SLAPD_LMHASH */
1335
1336 #ifdef SLAPD_CRYPT
1337 static struct berval *hash_crypt(
1338         const struct berval *scheme,
1339         const struct berval *passwd,
1340         const char **text )
1341 {
1342         struct berval hash;
1343         unsigned char salt[32]; /* salt suitable for most anything */
1344         unsigned int i;
1345
1346         for( i=0; i<passwd->bv_len; i++) {
1347                 if(passwd->bv_val[i] == '\0') {
1348                         return NULL;    /* NUL character in password */
1349                 }
1350         }
1351
1352         if( passwd->bv_val[i] != '\0' ) {
1353                 return NULL;    /* passwd must behave like a string */
1354         }
1355
1356         if( lutil_entropy( salt, sizeof( salt ) ) < 0 ) {
1357                 return NULL; 
1358         }
1359
1360         for( i=0; i< ( sizeof(salt) - 1 ); i++ ) {
1361                 salt[i] = crypt64[ salt[i] % (sizeof(crypt64)-1) ];
1362         }
1363         salt[sizeof( salt ) - 1 ] = '\0';
1364
1365         if( salt_format != NULL ) {
1366                 /* copy the salt we made into entropy before snprintfing
1367                    it back into the salt */
1368                 char entropy[sizeof(salt)];
1369                 strcpy( entropy, (char *) salt );
1370                 snprintf( (char *) salt, sizeof(entropy), salt_format, entropy );
1371         }
1372
1373         hash.bv_val = crypt( passwd->bv_val, (char *) salt );
1374
1375         if( hash.bv_val == NULL ) return NULL;
1376
1377         hash.bv_len = strlen( hash.bv_val );
1378
1379         if( hash.bv_len == 0 ) {
1380                 return NULL;
1381         }
1382
1383         return pw_string( scheme, &hash );
1384 }
1385 #endif
1386
1387 int lutil_salt_format(const char *format)
1388 {
1389 #ifdef SLAPD_CRYPT
1390         free( salt_format );
1391
1392         salt_format = format != NULL ? strdup( format ) : NULL;
1393 #endif
1394
1395         return 0;
1396 }
1397
1398 #ifdef SLAPD_CLEARTEXT
1399 static struct berval *hash_clear(
1400         const struct berval *scheme,
1401         const struct berval  *passwd,
1402         const char **text )
1403 {
1404         return ber_bvdup( (struct berval *) passwd );
1405 }
1406 #endif
1407