From deaa34dd66dfc5b6a650413b9837850a97f66fb1 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Mon, 16 Jan 2006 22:13:40 +0000 Subject: [PATCH] Misc fixes from HEAD --- servers/slapd/back-ldap/bind.c | 63 ++++++++++++++++++++-------- servers/slapd/back-ldap/proto-ldap.h | 3 +- servers/slapd/back-ldap/search.c | 15 +++++-- servers/slapd/back-meta/back-meta.h | 19 +++++++-- servers/slapd/back-meta/bind.c | 29 ++++++------- servers/slapd/back-meta/conn.c | 29 ++++++++++--- tests/scripts/test020-proxycache | 7 +--- 7 files changed, 112 insertions(+), 53 deletions(-) diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 55984982f6..33d4545f8a 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -42,7 +42,7 @@ static LDAP_REBIND_PROC ldap_back_default_rebind; LDAP_REBIND_PROC *ldap_back_rebind_f = ldap_back_default_rebind; static int -ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ); +ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); static int ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); @@ -80,7 +80,7 @@ ldap_back_bind( Operation *op, SlapReply *rs ) * bind with the configured identity assertion */ /* NOTE: use with care */ if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { - ldap_back_proxy_authz_bind( lc, op, rs ); + ldap_back_proxy_authz_bind( lc, op, rs, LDAP_BACK_SENDERR ); if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) { rc = 1; goto done; @@ -620,18 +620,23 @@ done:; } void -ldap_back_release_conn( +ldap_back_release_conn_lock( Operation *op, SlapReply *rs, - ldapconn_t *lc ) + ldapconn_t *lc, + int dolock ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + } assert( lc->lc_refcnt > 0 ); lc->lc_refcnt--; LDAP_BACK_CONN_BINDING_CLEAR( lc ); - ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + } } /* @@ -665,10 +670,20 @@ ldap_back_dobind_int( while ( lc->lc_refcnt > 1 ) { ldap_pvt_thread_yield(); - if (( rc = LDAP_BACK_CONN_ISBOUND( lc ))) + rc = LDAP_BACK_CONN_ISBOUND( lc ); + if ( rc ) { return rc; + } } + if ( dolock ) { + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + } + LDAP_BACK_CONN_BINDING_SET( lc ); + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + } + /* * FIXME: we need to let clients use proxyAuthz * otherwise we cannot do symmetric pools of servers; @@ -696,7 +711,7 @@ ldap_back_dobind_int( ( BER_BVISNULL( &lc->lc_bound_ndn ) || ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) { - (void)ldap_back_proxy_authz_bind( lc, op, rs ); + (void)ldap_back_proxy_authz_bind( lc, op, rs, sendok ); goto done; } @@ -785,13 +800,14 @@ retry:; rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok ); if ( rc == LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_SET( lc ); - - } else { - ldap_back_release_conn( op, rs, lc ); } done:; + LDAP_BACK_CONN_BINDING_CLEAR( lc ); rc = LDAP_BACK_CONN_ISBOUND( lc ); + if ( !rc ) { + ldap_back_release_conn_lock( op, rs, lc, dolock ); + } return rc; } @@ -997,7 +1013,7 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ } static int -ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) +ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; struct berval binddn = slap_empty_bv; @@ -1054,7 +1070,9 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) if ( BER_BVISNULL( &ndn ) && li->li_idassert_authz == NULL ) { if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { rs->sr_err = LDAP_INAPPROPRIATE_AUTH; - send_ldap_result( op, rs ); + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + } LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); } else { @@ -1079,7 +1097,9 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) &authcDN, &authcDN ); if ( rs->sr_err != LDAP_SUCCESS ) { if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { - send_ldap_result( op, rs ); + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + } LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); } else { @@ -1144,7 +1164,10 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) (void *)li->li_idassert_secprops ); if ( rs->sr_err != LDAP_OPT_SUCCESS ) { - send_ldap_result( op, rs ); + rs->sr_err = LDAP_OTHER; + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + } LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); goto done; } @@ -1165,7 +1188,9 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) rs->sr_err = slap_map_api2result( rs ); if ( rs->sr_err != LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); - send_ldap_result( op, rs ); + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + } } else { LDAP_BACK_CONN_ISBOUND_SET( lc ); @@ -1195,11 +1220,13 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs ) /* unsupported! */ LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED; - send_ldap_result( op, rs ); + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + } goto done; } - rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDERR ); + rc = ldap_back_op_result( lc, op, rs, msgid, 0, sendok ); if ( rc == LDAP_SUCCESS ) { LDAP_BACK_CONN_ISBOUND_SET( lc ); } diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index 13cbd9589a..7ac221b6b4 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -49,7 +49,8 @@ extern BI_entry_get_rw ldap_back_entry_get; int ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ); ldapconn_t *ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ); -void ldap_back_release_conn( Operation *op, SlapReply *rs, ldapconn_t *lc ); +void ldap_back_release_conn_lock( Operation *op, SlapReply *rs, ldapconn_t *lc, int dolock ); +#define ldap_back_release_conn(op, rs, lc) ldap_back_release_conn_lock((op), (rs), (lc), 1) int ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); int ldap_back_map_result( SlapReply *rs ); diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 30f8d4a153..d0840b0be0 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -153,7 +153,7 @@ ldap_back_search( int i; char **attrs = NULL; int freetext = 0; - int do_retry = 1; + int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; /* FIXME: shouldn't this be null? */ const char *save_matched = rs->sr_matched; @@ -282,8 +282,15 @@ retry: rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; goto finish; } + continue; + + } else { + /* don't retry any more */ + dont_retry = 1; + } + - } else if ( rc == LDAP_RES_SEARCH_ENTRY ) { + if ( rc == LDAP_RES_SEARCH_ENTRY ) { Entry ent = { 0 }; struct berval bdn = BER_BVNULL; @@ -432,10 +439,10 @@ retry: } } - if ( rc == -1 ) { + if ( rc == -1 && dont_retry == 0 ) { if ( do_retry ) { do_retry = 0; - if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) { + if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) { goto retry; } } diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 4f27415c37..5e2dbaf78e 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -230,7 +230,7 @@ typedef struct metatarget_t { time_t mt_network_timeout; time_t mt_idle_timeout; struct timeval mt_bind_timeout; -#define META_BIND_TIMEOUT 10000 +#define META_BIND_TIMEOUT LDAP_BACK_RESULT_UTIMEOUT time_t mt_timeout[ LDAP_BACK_OP_LAST ]; } metatarget_t; @@ -301,12 +301,15 @@ meta_back_release_conn( metaconn_t *mc ); extern int -meta_back_retry( +meta_back_retry_lock( Operation *op, SlapReply *rs, metaconn_t *mc, int candidate, - ldap_back_send_t sendok ); + ldap_back_send_t sendok, + int dolock ); +#define meta_back_retry(op, rs, mc, candidate, sendok) \ + meta_back_retry_lock((op), (rs), (mc), (candidate), (sendok), 1) extern void meta_back_conn_free( @@ -322,6 +325,14 @@ meta_back_init_one_conn( int ispriv, ldap_back_send_t sendok ); +extern int +meta_back_single_bind( + Operation *op, + SlapReply *rs, + metaconn_t *mc, + int candidate, + int massage ); + extern int meta_back_dobind( Operation *op, @@ -329,7 +340,7 @@ meta_back_dobind( metaconn_t *mc, ldap_back_send_t sendok ); -int +extern int meta_back_single_dobind( Operation *op, SlapReply *rs, diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 32389a75c1..0540c23ec3 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -41,14 +41,6 @@ static LDAP_REBIND_PROC meta_back_default_rebind; */ LDAP_REBIND_PROC *meta_back_rebind_f = meta_back_default_rebind; -static int -meta_back_single_bind( - Operation *op, - SlapReply *rs, - metaconn_t *mc, - int candidate, - int massage ); - int meta_back_bind( Operation *op, SlapReply *rs ) { @@ -272,7 +264,7 @@ retry_lock:; * * attempts to perform a bind with creds */ -static int +int meta_back_single_bind( Operation *op, SlapReply *rs, @@ -345,7 +337,7 @@ retry:; switch ( ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) { case 0: snprintf( buf, sizeof( buf ), - "ldap_result=0 nretries=%d%s\n", + "ldap_result=0 nretries=%d%s", nretries, rebinding ? " rebinding" : "" ); Debug( LDAP_DEBUG_ANY, "%s meta_back_single_bind[%d]: %s.\n", @@ -359,6 +351,7 @@ retry:; tv = mt->mt_bind_timeout; goto retry; } + rs->sr_err = LDAP_BUSY; if ( rebinding ) { ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); @@ -375,7 +368,7 @@ retry:; case -1: ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, - &rs->sr_err ); + &rs->sr_err ); if ( rebinding ) { ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); @@ -530,8 +523,8 @@ retry:; /* fallthru */ case -1: - ldap_get_option( msc->msc_ld, - LDAP_OPT_ERROR_NUMBER, &rs->sr_err ); + ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, + &rs->sr_err ); if ( rebinding ) { ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL ); @@ -648,7 +641,7 @@ meta_back_dobind( for ( i = 0; i < mi->mi_ntargets; i++ ) { metatarget_t *mt = &mi->mi_targets[ i ]; metasingleconn_t *msc = &mc->mc_conns[ i ]; - int rc; + int rc, do_retry = 1; char *rootdn = NULL; /* @@ -668,6 +661,7 @@ meta_back_dobind( continue; } +retry:; if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) ) { Operation op2 = *op; @@ -690,6 +684,13 @@ meta_back_dobind( if ( rc != LDAP_SUCCESS ) { char buf[ SLAP_TEXT_BUFLEN ]; + if ( rc == LDAP_UNAVAILABLE && do_retry ) { + do_retry = 0; + if ( meta_back_retry_lock( op, rs, mc, i, LDAP_BACK_DONTSEND, 0 ) ) { + goto retry; + } + } + snprintf( buf, sizeof( buf ), "meta_back_dobind[%d]: (%s) err=%d.", i, rootdn ? rootdn : "anonymous", rc ); diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 08fcbea92c..cd5bad958a 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -444,17 +444,18 @@ error_return:; } /* - * meta_back_retry + * meta_back_retry_lock * * Retries one connection */ int -meta_back_retry( +meta_back_retry_lock( Operation *op, SlapReply *rs, metaconn_t *mc, int candidate, - ldap_back_send_t sendok ) + ldap_back_send_t sendok, + int dolock ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metatarget_t *mt = &mi->mi_targets[ candidate ]; @@ -469,7 +470,7 @@ retry_lock:; if ( mc->mc_refcnt == 1 ) { char buf[ SLAP_TEXT_BUFLEN ]; - while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) { + while ( dolock && ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) { ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex ); ldap_pvt_thread_yield(); goto retry_lock; @@ -494,11 +495,27 @@ retry_lock:; LDAP_BACK_CONN_ISPRIV( mc ), sendok ); if ( rc == LDAP_SUCCESS ) { - rc = meta_back_single_dobind( op, rs, mc, candidate, + if ( be_isroot( op ) && !BER_BVISNULL( &mi->mi_targets[ candidate ].mt_pseudorootdn ) ) + { + Operation op2 = *op; + + op2.o_tag = LDAP_REQ_BIND; + op2.o_req_dn = mi->mi_targets[ candidate ].mt_pseudorootdn; + op2.o_req_ndn = mi->mi_targets[ candidate ].mt_pseudorootdn; + op2.orb_cred = mi->mi_targets[ candidate ].mt_pseudorootpw; + op2.orb_method = LDAP_AUTH_SIMPLE; + + rc = meta_back_single_bind( &op2, rs, mc, candidate, 0 ); + + } else { + rc = meta_back_single_dobind( op, rs, mc, candidate, sendok, mt->mt_nretries, 0 ); + } } - ldap_pvt_thread_mutex_unlock( &mc->mc_mutex ); + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &mc->mc_mutex ); + } } if ( rc != LDAP_SUCCESS ) { diff --git a/tests/scripts/test020-proxycache b/tests/scripts/test020-proxycache index a8170b9f8f..05466464e4 100755 --- a/tests/scripts/test020-proxycache +++ b/tests/scripts/test020-proxycache @@ -28,11 +28,6 @@ if test $BACKLDAP = "ldapno" ; then exit 0 fi -if test "x$LVL" = "x0" ; then - echo "test020 needs a minimal log level; setting to LDAP_DEBUG_NONE..." - LVL=2048 -fi - mkdir -p $TESTDIR $DBDIR1 $DBDIR2 # Test proxy caching: @@ -86,7 +81,7 @@ fi echo "Starting proxy cache on TCP/IP port $PORT2..." . $CONFFILTER < $PROXYCACHECONF > $CONF2 -$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 & +$SLAPD -f $CONF2 -h $URI2 -d $LVL -d trace > $LOG2 2>&1 & CACHEPID=$! if test $WAIT != 0 ; then echo CACHEPID $CACHEPID -- 2.39.5