From: Pierangelo Masarati Date: Sat, 8 Apr 2006 14:45:19 +0000 (+0000) Subject: fix previous commit X-Git-Tag: OPENLDAP_REL_ENG_2_4_0ALPHA~10^2~7 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=cc8109db06b234474a6387875a3ffb1f7270a229;p=openldap fix previous commit --- diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 2242a6d23f..b6b449cd82 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -51,6 +51,9 @@ ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_b static int ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); +static int +ldap_back_conndnlc_cmp( const void *c1, const void *c2 ); + int ldap_back_bind( Operation *op, SlapReply *rs ) { @@ -114,6 +117,7 @@ done:; && !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) ) ) { int lerr = -1; + ldapconn_t *tmplc; /* wait for all other ops to release the connection */ retry_lock:; @@ -125,9 +129,9 @@ retry_lock:; } assert( lc->lc_refcnt == 1 ); - lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, - ldap_back_conndn_cmp ); - assert( lc != NULL ); + tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndnlc_cmp ); + assert( lc == tmplc ); if ( LDAP_BACK_CONN_ISBOUND( lc ) ) { ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn ); @@ -136,8 +140,14 @@ retry_lock:; } ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); - if ( lerr == -1 ) { - /* we can do this because lc_refcnt == 1 */ + switch ( lerr ) { + case 0: + break; + + case -1: + /* duplicate; someone else successfully bound + * on the same connection with the same identity; + * we can do this because lc_refcnt == 1 */ ldap_back_conn_free( lc ); lc = NULL; } @@ -290,17 +300,17 @@ int ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; + ldapconn_t *tmplc; if ( dolock ) { ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); } - assert( lc->lc_refcnt > 0 ); - if ( --lc->lc_refcnt == 0 ) { - lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, - ldap_back_conndn_cmp ); - assert( lc != NULL ); - + assert( lc->lc_refcnt >= 0 ); + tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndnlc_cmp ); + assert( LDAP_BACK_CONN_TAINTED( lc ) || tmplc == lc ); + if ( lc->lc_refcnt == 0 ) { ldap_back_conn_free( (void *)lc ); } @@ -672,6 +682,10 @@ retry_lock: goto retry_lock; } /* taint connection, so that it'll be freed when released */ + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + (void *)avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, + ldap_back_conndnlc_cmp ); + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); LDAP_BACK_CONN_TAINTED_SET( lc ); break; @@ -735,8 +749,8 @@ ldap_back_release_conn_lock( } assert( lc->lc_refcnt > 0 ); LDAP_BACK_CONN_BINDING_CLEAR( lc ); - if ( --lc->lc_refcnt == 0 && LDAP_BACK_CONN_TAINTED( lc ) ) { - ldap_back_freeconn( op, rs, 0 ); + if ( --lc->lc_refcnt == 0 || LDAP_BACK_CONN_TAINTED( lc ) ) { + ldap_back_freeconn( op, lc, 0 ); } if ( dolock ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); @@ -926,19 +940,33 @@ retry:; /* lc here must be the regular lc, reset and ready for init */ rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok ); + if ( rs->sr_err != LDAP_SUCCESS ) { + lc->lc_binding--; + lc->lc_refcnt = 0; + } } + if ( dolock ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); } + if ( rs->sr_err == LDAP_SUCCESS ) { if ( retries > 0 ) { retries--; } goto retry; } + + } else { + if ( dolock ) { + ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); + } + lc->lc_binding--; + if ( dolock ) { + ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); + } } - lc->lc_binding--; ldap_back_freeconn( op, lc, dolock ); rs->sr_err = slap_map_api2result( rs ); diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index 5e0c2682c7..e0537e870f 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -132,8 +132,7 @@ retry: if ( rc == LDAP_SUCCESS ) { if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) { ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc ); - ldap_back_freeconn( op, lc, 0 ); - lc = NULL; + rs->sr_err = rc; } else { /* sigh. parse twice, because parse_passwd @@ -172,6 +171,7 @@ retry: ldap_msgfree( res ); } } + if ( rc != LDAP_SUCCESS ) { rs->sr_err = slap_map_api2result( rs ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { @@ -190,6 +190,7 @@ retry: free( (char *)rs->sr_matched ); rs->sr_matched = NULL; } + if ( rs->sr_text ) { free( (char *)rs->sr_text ); rs->sr_text = NULL; @@ -229,8 +230,7 @@ retry: if ( rc == LDAP_SUCCESS ) { if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) { ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc ); - ldap_back_freeconn( op, lc, 0 ); - lc = NULL; + rs->sr_err = rc; } else { /* sigh. parse twice, because parse_passwd @@ -255,6 +255,7 @@ retry: ldap_msgfree( res ); } } + if ( rc != LDAP_SUCCESS ) { rs->sr_err = slap_map_api2result( rs ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { @@ -273,6 +274,7 @@ retry: free( (char *)rs->sr_matched ); rs->sr_matched = NULL; } + if ( rs->sr_text ) { free( (char *)rs->sr_text ); rs->sr_text = NULL; diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index cdb9c581ee..de4180e65a 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -224,14 +224,13 @@ retry: goto retry; } } + if ( lc == NULL ) { /* reset by ldap_back_retry ... */ rs->sr_err = slap_map_api2result( rs ); } else { rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); - ldap_back_freeconn( op, lc, 0 ); - lc = NULL; } goto finish;