Reorganiza SLAPD_CRYPT and SLAPD_SPASSWD support for better reentrancy

This commit is contained in:
Howard Chu 2005-03-18 06:06:38 +00:00
parent d69a0871cf
commit 2da2336ac6
7 changed files with 170 additions and 146 deletions

View 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 )

View file

@ -33,14 +33,6 @@
#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 )
{
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 */
}
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;
#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;
}
#endif
#ifdef SLAPD_CRYPT
static int lutil_crypt(
const char *key,
const char *salt,
char **hash )
{
char *cr = crypt( key, salt );
int rc;
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;
}
}
return rc;
}
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 );
if( hash->bv_len == 0 ) {
return LUTIL_PASSWD_ERR;
}
save = hash->bv_val;
return pw_string( scheme, hash );
if( hash->bv_len == 0 ) {
rc = LUTIL_PASSWD_ERR;
} else {
rc = 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;

View 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;

View 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();

View file

@ -23,6 +23,10 @@
#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 */

View 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

View 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 );