X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fpasswd.c;h=a262a9911aa74009a485b084d9ad4139f9e2d982;hb=4a8d8eb78a610baefde7f5b3e0a371961dafff84;hp=c0adac5763db8a9bb91d6bf0141461384cd01c18;hpb=fda3d6260e25f1d0b9c035b0d520b2c9d0f22e49;p=openldap diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index c0adac5763..a262a9911a 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 @@ -27,6 +27,7 @@ #include #include +#include static const char *defhash[] = { #ifdef LUTIL_SHA1_BYTES @@ -43,13 +44,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 +83,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,19 +109,30 @@ 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 */ if(!( !SLAP_SHADOW( op->o_bd ) || be_isupdate( op ))) { /* we SHOULD return a referral in this case */ BerVarray defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : SLAPD_GLOBAL(default_referral); + ? op->o_bd->be_update_refs : default_referral; if( defref != NULL ) { rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs, @@ -153,6 +166,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 ); @@ -173,9 +188,9 @@ int passwd_extop( ml = ch_malloc( sizeof(Modifications) ); if ( !qpw->rs_modtail ) qpw->rs_modtail = &ml->sml_next; - if ( SLAPD_GLOBAL(default_passwd_hash) ) { - for ( nhash = 0; SLAPD_GLOBAL(default_passwd_hash)[nhash]; nhash++ ); - hashes = SLAPD_GLOBAL(default_passwd_hash); + if ( default_passwd_hash ) { + for ( nhash = 0; default_passwd_hash[nhash]; nhash++ ); + hashes = default_passwd_hash; } else { nhash = 1; hashes = (char **)defhash; @@ -202,27 +217,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, + 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 +245,7 @@ int passwd_extop( } rc = rs->sr_err; + op->oq_extended = qext; error_return:; if ( !BER_BVISNULL( &op->o_req_dn ) ) { @@ -384,25 +400,37 @@ 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( &SLAPD_GLOBAL(passwd_mutex) ); + ldap_pvt_thread_mutex_lock( &passwd_mutex ); #ifdef SLAPD_SPASSWD - lutil_passwd_sasl_conn = conn->c_sasl_authctx; + lutil_passwd_sasl_conn = op->o_conn->c_sasl_authctx; #endif #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; } @@ -412,7 +440,7 @@ slap_passwd_check( #ifdef SLAPD_SPASSWD lutil_passwd_sasl_conn = NULL; #endif - ldap_pvt_thread_mutex_unlock( &SLAPD_GLOBAL(passwd_mutex) ); + ldap_pvt_thread_mutex_unlock( &passwd_mutex ); #endif return result; @@ -445,13 +473,13 @@ slap_passwd_hash_type( assert( hash ); #if defined( SLAPD_CRYPT ) || defined( SLAPD_SPASSWD ) - ldap_pvt_thread_mutex_lock( &SLAPD_GLOBAL(passwd_mutex) ); + 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( &SLAPD_GLOBAL(passwd_mutex) ); + ldap_pvt_thread_mutex_unlock( &passwd_mutex ); #endif } @@ -462,8 +490,8 @@ slap_passwd_hash( const char **text ) { char *hash = NULL; - if ( SLAPD_GLOBAL(default_passwd_hash) ) { - hash = SLAPD_GLOBAL(default_passwd_hash)[0]; + if ( default_passwd_hash ) { + hash = default_passwd_hash[0]; } if ( !hash ) { hash = (char *)defhash[0];