]> git.sur5r.net Git - openldap/commitdiff
Reorganiza SLAPD_CRYPT and SLAPD_SPASSWD support for better reentrancy
authorHoward Chu <hyc@openldap.org>
Fri, 18 Mar 2005 06:06:38 +0000 (06:06 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 18 Mar 2005 06:06:38 +0000 (06:06 +0000)
include/lutil.h
libraries/liblutil/passwd.c
servers/slapd/backend.c
servers/slapd/init.c
servers/slapd/passwd.c
servers/slapd/proto-slap.h
servers/slapd/sasl.c

index ea2450c4a1264df3ed446301e06a235dff0b63af..abfc595867683e87cc83915179e5f9da863b51a0 100644 (file)
@@ -110,9 +110,12 @@ lutil_authpasswd_hash LDAP_P((
        struct berval **salt,   /* salt to store */
        const char *method ));
 
-#if defined( SLAPD_SPASSWD ) && defined( HAVE_CYRUS_SASL )
-       /* cheat to avoid pulling in <sasl.h> */
-LDAP_LUTIL_V( struct sasl_conn * ) lutil_passwd_sasl_conn;
+#ifdef SLAPD_CRYPT
+typedef int (lutil_cryptfunc) LDAP_P((
+       const char *key,
+       const char *salt,
+       char **hash ));
+LDAP_LUTIL_V (lutil_cryptfunc *) lutil_cryptptr;
 #endif
 
 LDAP_LUTIL_F( int )
index 8fe4673aadd184725eff458e7c6f0a4a8d791f42..5460b0376a9226050de5691404c1f206ca9df835 100644 (file)
 #include <ac/string.h>
 #include <ac/unistd.h>
 
-#ifdef SLAPD_SPASSWD
-#      ifdef HAVE_SASL_SASL_H
-#              include <sasl/sasl.h>
-#      else
-#              include <sasl.h>
-#      endif
-#endif
-
 #if defined(SLAPD_LMHASH)
 #      include <openssl/des.h>
 #endif /* SLAPD_LMHASH */
@@ -77,6 +69,8 @@ static const unsigned char crypt64[] =
 
 #ifdef SLAPD_CRYPT
 static char *salt_format = NULL;
+static lutil_cryptfunc lutil_crypt;
+lutil_cryptfunc *lutil_cryptptr = lutil_crypt;
 #endif
 
 struct pw_scheme {
@@ -112,10 +106,6 @@ static LUTIL_PASSWD_CHK_FUNC chk_lanman;
 static LUTIL_PASSWD_HASH_FUNC hash_lanman;
 #endif
 
-#ifdef SLAPD_SPASSWD
-static LUTIL_PASSWD_CHK_FUNC chk_sasl;
-#endif
-
 #ifdef SLAPD_CRYPT
 static LUTIL_PASSWD_CHK_FUNC chk_crypt;
 static LUTIL_PASSWD_HASH_FUNC hash_crypt;
@@ -148,10 +138,6 @@ static const struct pw_scheme pw_schemes_default[] =
        { BER_BVC("{LANMAN}"),          chk_lanman, hash_lanman },
 #endif /* SLAPD_LMHASH */
 
-#ifdef SLAPD_SPASSWD
-       { BER_BVC("{SASL}"),            chk_sasl, NULL },
-#endif
-
 #ifdef SLAPD_CRYPT
        { BER_BVC("{CRYPT}"),           chk_crypt, hash_crypt },
 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
@@ -753,64 +739,29 @@ static int chk_lanman(
 }
 #endif /* SLAPD_LMHASH */
 
-#ifdef SLAPD_SPASSWD
-#ifdef HAVE_CYRUS_SASL
-sasl_conn_t *lutil_passwd_sasl_conn = NULL;
-#endif
-
-static int chk_sasl(
-       const struct berval *sc,
-       const struct berval * passwd,
-       const struct berval * cred,
-       const char **text )
+#ifdef SLAPD_CRYPT
+static int lutil_crypt(
+       const char *key,
+       const char *salt,
+       char **hash )
 {
-       unsigned int i;
-       int rtn;
-
-       for( i=0; i<cred->bv_len; i++) {
-               if(cred->bv_val[i] == '\0') {
-                       return LUTIL_PASSWD_ERR;        /* NUL character in password */
-               }
-       }
-
-       if( cred->bv_val[i] != '\0' ) {
-               return LUTIL_PASSWD_ERR;        /* cred must behave like a string */
-       }
+       char *cr = crypt( key, salt );
+       int rc;
 
-       for( i=0; i<passwd->bv_len; i++) {
-               if(passwd->bv_val[i] == '\0') {
-                       return LUTIL_PASSWD_ERR;        /* NUL character in password */
+       if( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               rc = LUTIL_PASSWD_ERR;
+       } else {
+               if ( hash ) {
+                       *hash = ber_strdup( cr );
+                       rc = LUTIL_PASSWD_OK;
+               } else {
+                       rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
                }
        }
-
-       if( passwd->bv_val[i] != '\0' ) {
-               return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
-       }
-
-       rtn = LUTIL_PASSWD_ERR;
-
-#ifdef HAVE_CYRUS_SASL
-       if( lutil_passwd_sasl_conn != NULL ) {
-               int sc;
-# if SASL_VERSION_MAJOR < 2
-               sc = sasl_checkpass( lutil_passwd_sasl_conn,
-                       passwd->bv_val, passwd->bv_len,
-                       cred->bv_val, cred->bv_len,
-                       text );
-# else
-               sc = sasl_checkpass( lutil_passwd_sasl_conn,
-                       passwd->bv_val, passwd->bv_len,
-                       cred->bv_val, cred->bv_len );
-# endif
-               rtn = ( sc != SASL_OK ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
-       }
-#endif
-
-       return rtn;
+       return rc;
 }
-#endif
 
-#ifdef SLAPD_CRYPT
 static int chk_crypt(
        const struct berval *sc,
        const struct berval * passwd,
@@ -819,6 +770,7 @@ static int chk_crypt(
 {
        char *cr;
        unsigned int i;
+       int rc;
 
        for( i=0; i<cred->bv_len; i++) {
                if(cred->bv_val[i] == '\0') {
@@ -844,14 +796,7 @@ static int chk_crypt(
                return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
        }
 
-       cr = crypt( cred->bv_val, passwd->bv_val );
-
-       if( cr == NULL || cr[0] == '\0' ) {
-               /* salt must have been invalid */
-               return LUTIL_PASSWD_ERR;
-       }
-
-       return strcmp( passwd->bv_val, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
+       return lutil_cryptptr( cred->bv_val, passwd->bv_val, NULL );
 }
 
 # if defined( HAVE_GETPWNAM ) && defined( HAVE_PW_PASSWD )
@@ -916,15 +861,7 @@ static int chk_unix(
                return LUTIL_PASSWD_ERR;
        }
 
-       cr = crypt(cred->bv_val, pw);
-
-       if( cr == NULL || cr[0] == '\0' ) {
-               /* salt must have been invalid */
-               return LUTIL_PASSWD_ERR;
-       }
-
-       return strcmp(pw, cr) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
-
+       return lutil_cryptptr( cred->bv_val, pw, NULL );
 }
 # endif
 #endif
@@ -1098,6 +1035,8 @@ static int hash_crypt(
 {
        unsigned char salt[32]; /* salt suitable for most anything */
        unsigned int i;
+       char *save;
+       int rc;
 
        for( i=0; i<passwd->bv_len; i++) {
                if(passwd->bv_val[i] == '\0') {
@@ -1126,17 +1065,22 @@ static int hash_crypt(
                snprintf( (char *) salt, sizeof(entropy), salt_format, entropy );
        }
 
-       hash->bv_val = crypt( passwd->bv_val, (char *) salt );
+       rc = lutil_cryptptr( passwd->bv_val, (char *) salt, &hash->bv_val );
+       if ( rc != LUTIL_PASSWD_OK ) return rc;
 
        if( hash->bv_val == NULL ) return -1;
 
        hash->bv_len = strlen( hash->bv_val );
 
+       save = hash->bv_val;
+
        if( hash->bv_len == 0 ) {
-               return LUTIL_PASSWD_ERR;
+               rc = LUTIL_PASSWD_ERR;
+       } else {
+               rc = pw_string( scheme, hash );
        }
-
-       return pw_string( scheme, hash );
+       ber_memfree( save );
+       return rc;
 }
 #endif
 
@@ -1145,7 +1089,7 @@ int lutil_salt_format(const char *format)
 #ifdef SLAPD_CRYPT
        free( salt_format );
 
-       salt_format = format != NULL ? strdup( format ) : NULL;
+       salt_format = format != NULL ? ber_strdup( format ) : NULL;
 #endif
 
        return 0;
index f64e661ea75ba9fcd7ff92e61a44acbb2121ac16..1a0277f25cd89f1d3b1785864e436150629570d2 100644 (file)
@@ -747,20 +747,15 @@ be_isroot_pw( Operation *op )
                return 0;
        }
 
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-       ldap_pvt_thread_mutex_lock( &passwd_mutex );
 #ifdef SLAPD_SPASSWD
-       lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx;
-#endif
+       ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind,
+               op->o_conn->c_sasl_authctx, NULL );
 #endif
 
        result = lutil_passwd( &op->o_bd->be_rootpw, &op->orb_cred, NULL, NULL );
 
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
 #ifdef SLAPD_SPASSWD
-       lutil_passwd_sasl_conn = NULL;
-#endif
-       ldap_pvt_thread_mutex_unlock( &passwd_mutex );
+       ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind, NULL, NULL );
 #endif
 
        return result == 0;
index e606e3da9ee898c5e2a641f9b66931ec6a890be6..b711ef9840610fe7246bae15164966bdbbf86c3a 100644 (file)
@@ -68,9 +68,6 @@ int                   connection_pool_max = SLAP_MAX_WORKER_THREADS;
 #ifndef HAVE_GMTIME_R
 ldap_pvt_thread_mutex_t        gmtime_mutex;
 #endif
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-ldap_pvt_thread_mutex_t        passwd_mutex;
-#endif
 
 slap_counters_t                        slap_counters;
 
@@ -139,9 +136,7 @@ slap_init( int mode, const char *name )
 #ifndef HAVE_GMTIME_R
                ldap_pvt_thread_mutex_init( &gmtime_mutex );
 #endif
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-               ldap_pvt_thread_mutex_init( &passwd_mutex );
-#endif
+               slap_passwd_init();
 
                rc = slap_sasl_init();
 
index 265681c4a4aa34e303646cf56642dadc6bbccd94..65710aaff5367a49b31cb7ad6b317f587b769c81 100644 (file)
 #include <ac/string.h>
 #include <ac/unistd.h>
 
+#ifdef SLAPD_CRYPT
+#include <ac/crypt.h>
+#endif
+
 #include "slap.h"
 
 #include <lber_pvt.h>
@@ -415,38 +419,30 @@ slap_passwd_check(
        struct berval           *bv;
        AccessControlState      acl_state = ACL_STATE_INIT;
 
-       for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
-               int     rc;
+#ifdef SLAPD_SPASSWD
+       ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind,
+               op->o_conn->c_sasl_authctx, NULL );
+#endif
 
+       for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
                /* if e is provided, check access */
                if ( e && access_allowed( op, e, a->a_desc, bv,
                                        ACL_AUTH, &acl_state ) == 0 )
                {
                        continue;
                }
-
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-               ldap_pvt_thread_mutex_lock( &passwd_mutex );
-#ifdef SLAPD_SPASSWD
-               lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx;
-#endif
-#endif
-       
-               rc = lutil_passwd( bv, cred, NULL, text );
-
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-#ifdef SLAPD_SPASSWD
-               lutil_passwd_sasl_conn = NULL;
-#endif
-               ldap_pvt_thread_mutex_unlock( &passwd_mutex );
-#endif
-
-               if ( !rc ) {
+               
+               if ( !lutil_passwd( bv, cred, NULL, text ) ) {
                        result = 0;
                        break;
                }
        }
 
+#ifdef SLAPD_SPASSWD
+       ldap_pvt_thread_pool_setkey( op->o_threadctx, slap_sasl_bind,
+               NULL, NULL );
+#endif
+
        return result;
 }
 
@@ -476,16 +472,7 @@ slap_passwd_hash_type(
 
        assert( hash );
 
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-       ldap_pvt_thread_mutex_lock( &passwd_mutex );
-#endif
-
        lutil_passwd_hash( cred , hash, new, text );
-       
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-       ldap_pvt_thread_mutex_unlock( &passwd_mutex );
-#endif
-
 }
 void
 slap_passwd_hash(
@@ -503,3 +490,41 @@ slap_passwd_hash(
 
        slap_passwd_hash_type( cred, new, hash, text );
 }
+
+#ifdef SLAPD_CRYPT
+static ldap_pvt_thread_mutex_t passwd_mutex;
+static lutil_cryptfunc slapd_crypt;
+#endif
+
+void slap_passwd_init()
+{
+#ifdef SLAPD_CRYPT
+       ldap_pvt_thread_mutex_init( &passwd_mutex );
+       lutil_cryptptr = slapd_crypt;
+#endif
+}
+#ifdef SLAPD_CRYPT
+int slapd_crypt( const char *key, const char *salt, char **hash )
+{
+       char *cr;
+       int rc;
+
+       ldap_pvt_thread_mutex_lock( &passwd_mutex );
+
+       cr = crypt( key, salt );
+       if ( cr == NULL || cr[0] == '\0' ) {
+               /* salt must have been invalid */
+               rc = LUTIL_PASSWD_ERR;
+       } else {
+               if ( hash ) {
+                       *hash = ber_strdup( cr );
+                       rc = LUTIL_PASSWD_OK;
+               }
+               rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
+       }
+
+       ldap_pvt_thread_mutex_unlock( &passwd_mutex );
+       return rc;
+}
+#endif /* SLAPD_CRYPT */
+
index f91874a5aee67b688fe253a9af297f043ae6c603..bedbb5a36e2d7e8aceb6d4b729082d8796eb193e 100644 (file)
@@ -1071,6 +1071,8 @@ LDAP_SLAPD_F (int) slap_passwd_parse(
        struct berval           *newpass,
        const char              **text );
 
+LDAP_SLAPD_F (void) slap_passwd_init (void);
+
 /*
  * phonetic.c
  */
@@ -1463,9 +1465,6 @@ LDAP_SLAPD_V (int)                        connection_pool_max;
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) entry2str_mutex;
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) replog_mutex;
 
-#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD )
-LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) passwd_mutex;
-#endif
 #ifndef HAVE_GMTIME_R
 LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) gmtime_mutex;
 #endif
index 975df3755f30f02a5b1aea226faa47629982123a..bf068e85c1d3b59f76cd296700deec480a8bf76e 100644 (file)
@@ -768,7 +768,66 @@ slap_sasl_err2ldap( int saslerr )
 
        return rc;
 }
-#endif
+
+#ifdef SLAPD_SPASSWD
+
+static struct berval sasl_pwscheme = BER_BVC("{SASL}");
+
+static int chk_sasl(
+       const struct berval *sc,
+       const struct berval * passwd,
+       const struct berval * cred,
+       const char **text )
+{
+       unsigned int i;
+       int rtn;
+       void *ctx, *sconn = NULL;
+
+       for( i=0; i<cred->bv_len; i++) {
+               if(cred->bv_val[i] == '\0') {
+                       return LUTIL_PASSWD_ERR;        /* NUL character in password */
+               }
+       }
+
+       if( cred->bv_val[i] != '\0' ) {
+               return LUTIL_PASSWD_ERR;        /* cred must behave like a string */
+       }
+
+       for( i=0; i<passwd->bv_len; i++) {
+               if(passwd->bv_val[i] == '\0') {
+                       return LUTIL_PASSWD_ERR;        /* NUL character in password */
+               }
+       }
+
+       if( passwd->bv_val[i] != '\0' ) {
+               return LUTIL_PASSWD_ERR;        /* passwd must behave like a string */
+       }
+
+       rtn = LUTIL_PASSWD_ERR;
+
+       ctx = ldap_pvt_thread_pool_context();
+       ldap_pvt_thread_pool_getkey( ctx, slap_sasl_bind, &sconn, NULL );
+
+       if( sconn != NULL ) {
+               int sc;
+# if SASL_VERSION_MAJOR < 2
+               sc = sasl_checkpass( sconn,
+                       passwd->bv_val, passwd->bv_len,
+                       cred->bv_val, cred->bv_len,
+                       text );
+# else
+               sc = sasl_checkpass( sconn,
+                       passwd->bv_val, passwd->bv_len,
+                       cred->bv_val, cred->bv_len );
+# endif
+               rtn = ( sc != SASL_OK ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
+       }
+
+       return rtn;
+}
+#endif /* SLAPD_SPASSWD */
+
+#endif /* HAVE_CYRUS_SASL */
 
 int slap_sasl_init( void )
 {
@@ -840,6 +899,10 @@ int slap_sasl_init( void )
                return -1;
        }
 
+#ifdef SLAPD_SPASSWD
+       lutil_passwd_add( &sasl_pwscheme, chk_sasl, NULL );
+#endif
+
        Debug( LDAP_DEBUG_TRACE, "slap_sasl_init: initialized!\n",
                0, 0, 0 );