X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fpasswd.c;h=0480f3216c50e92303a92fa792f7e0eb74a67067;hb=af866c3b44ba37577671f2bffd482499f4b8bc00;hp=f0e97b6b9bd5e008812bc90bb39437fe6e20458c;hpb=dbb4593d756a3a6d54739a1945da59198d5af5cc;p=openldap diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index f0e97b6b9b..0480f3216c 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2004 The OpenLDAP Foundation. + * Copyright 1998-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,10 +23,15 @@ #include #include +#ifdef SLAPD_CRYPT +#include +#endif + #include "slap.h" #include #include +#include static const char *defhash[] = { #ifdef LUTIL_SHA1_BYTES @@ -43,13 +48,14 @@ int passwd_extop( { struct berval id = {0, NULL}, hash, *rsp = NULL; req_pwdexop_s *qpw = &op->oq_pwdexop; + req_extended_s qext = op->oq_extended; Modifications *ml; - Operation op2; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL }; int i, nhash; char **hashes; int rc; + BackendDB *op_be; cb2.sc_next = &cb; @@ -81,7 +87,7 @@ int passwd_extop( rc = rs->sr_err; goto error_return; } - op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + op->o_bd = select_backend( &op->o_req_ndn, 0, 1 ); } else { ber_dupbv_x( &op->o_req_dn, &op->o_dn, op->o_tmpmemctx ); @@ -107,12 +113,23 @@ int passwd_extop( goto error_return; } + /* If we've got a glued backend, check the real backend */ + op_be = op->o_bd; + if ( SLAP_GLUE_INSTANCE( op->o_bd )) { + op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); + } + if (backend_check_restrictions( op, rs, (struct berval *)&slap_EXOP_MODIFY_PASSWD ) != LDAP_SUCCESS) { rc = rs->sr_err; goto error_return; } + /* check for referrals */ + if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) { + rc = rs->sr_err; + goto error_return; + } #ifndef SLAPD_MULTIMASTER /* This does not apply to multi-master case */ @@ -153,6 +170,8 @@ int passwd_extop( goto error_return; } + op->o_bd = op_be; + /* Give the backend a chance to handle this itself */ if ( op->o_bd->be_extended ) { rs->sr_err = op->o_bd->be_extended( op, rs ); @@ -202,27 +221,27 @@ int passwd_extop( rs->sr_err = LDAP_OTHER; } else { - op2 = *op; - op2.o_tag = LDAP_REQ_MODIFY; - op2.o_callback = &cb2; - op2.orm_modlist = qpw->rs_mods; + slap_callback *sc = op->o_callback; + + op->o_tag = LDAP_REQ_MODIFY; + op->o_callback = &cb2; + op->orm_modlist = qpw->rs_mods; cb2.sc_private = qpw; /* let Modify know this was pwdMod, * if it cares... */ - rs->sr_err = slap_mods_opattrs( &op2, ml, qpw->rs_modtail, &rs->sr_text, - NULL, 0 ); + rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text, + NULL, 0, 1 ); if ( rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = op2.o_bd->be_modify( &op2, rs ); - /* FIXME: in case it got rewritten... */ - op->o_req_dn = op2.o_req_dn; - op->o_req_ndn = op2.o_req_ndn; + rs->sr_err = op->o_bd->be_modify( op, rs ); } if ( rs->sr_err == LDAP_SUCCESS ) { rs->sr_rspdata = rsp; } else if ( rsp ) { ber_bvfree( rsp ); } + op->o_tag = LDAP_REQ_EXTENDED; + op->o_callback = sc; } slap_mods_free( qpw->rs_mods ); if ( rsp ) { @@ -230,6 +249,7 @@ int passwd_extop( } rc = rs->sr_err; + op->oq_extended = qext; error_return:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { @@ -269,13 +289,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "{" /*}*/ ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: decoding error\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: decoding error\n", 0, 0, 0 ); -#endif rc = LDAP_PROTOCOL_ERROR; goto done; } @@ -283,13 +298,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_peek_tag( ber, &len ); if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) { if( id == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID not allowed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID not allowed.\n", 0, 0, 0 ); -#endif *text = "user must change own password"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -299,13 +309,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", id ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID parse failed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -315,13 +320,8 @@ int slap_passwd_parse( struct berval *reqdata, if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ) { if( oldpass == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: OLD not allowed.\n" , 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD not allowed.\n", 0, 0, 0 ); -#endif *text = "use bind to verify old password"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -331,13 +331,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", oldpass ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: ID parse failed.\n" , 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n", + Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -347,13 +342,8 @@ int slap_passwd_parse( struct berval *reqdata, if( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ) { if( newpass == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: NEW not allowed.\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW not allowed.\n", 0, 0, 0 ); -#endif *text = "user specified passwords disallowed"; rc = LDAP_UNWILLING_TO_PERFORM; @@ -363,13 +353,8 @@ int slap_passwd_parse( struct berval *reqdata, tag = ber_scanf( ber, "m", newpass ); if( tag == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: OLD parse failed.\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n", + Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW parse failed.\n", 0, 0, 0 ); -#endif goto decoding_error; } @@ -379,14 +364,9 @@ int slap_passwd_parse( struct berval *reqdata, if( len != 0 ) { decoding_error: -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "slap_passwd_parse: decoding error, len=%ld\n", (long)len, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: decoding error, len=%ld\n", (long) len, 0, 0 ); -#endif *text = "data decoding error"; rc = LDAP_PROTOCOL_ERROR; @@ -407,13 +387,8 @@ struct berval * slap_passwd_return( assert( cred != NULL ); -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, - "slap_passwd_return: %ld\n",(long)cred->bv_len, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_return: %ld\n", (long) cred->bv_len, 0, 0 ); -#endif ber_init_w_nullc( ber, LBER_USE_DER ); @@ -429,35 +404,43 @@ struct berval * slap_passwd_return( return bv; } +/* + * if "e" is provided, access to each value of the password is checked first + */ int slap_passwd_check( - Connection *conn, - Attribute *a, - struct berval *cred, - const char **text ) + Operation *op, + Entry *e, + Attribute *a, + struct berval *cred, + const char **text ) { - int result = 1; - struct berval *bv; + int result = 1; + struct berval *bv; + AccessControlState acl_state = ACL_STATE_INIT; -#if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD ) - ldap_pvt_thread_mutex_lock( &passwd_mutex ); #ifdef SLAPD_SPASSWD - lutil_passwd_sasl_conn = conn->c_sasl_authctx; -#endif + 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( !lutil_passwd( bv, cred, NULL, text ) ) { + /* if e is provided, check access */ + if ( e && access_allowed( op, e, a->a_desc, bv, + ACL_AUTH, &acl_state ) == 0 ) + { + continue; + } + + if ( !lutil_passwd( bv, cred, NULL, text ) ) { result = 0; break; } } -#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; @@ -466,11 +449,7 @@ slap_passwd_check( void slap_passwd_generate( struct berval *pass ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, "slap_passwd_generate: begin\n", 0, 0, 0 ); -#else Debug( LDAP_DEBUG_TRACE, "slap_passwd_generate\n", 0, 0, 0 ); -#endif pass->bv_val = NULL; pass->bv_len = 0; @@ -493,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( @@ -520,3 +490,40 @@ 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; + +static 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 */ + +void slap_passwd_init() +{ +#ifdef SLAPD_CRYPT + ldap_pvt_thread_mutex_init( &passwd_mutex ); + lutil_cryptptr = slapd_crypt; +#endif +} +