From 55b56854257314bf2d43012cfd0204c225532728 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 11 Sep 2006 22:45:19 +0000 Subject: [PATCH] ldap_back_dobind_int() may need to free a connection --- servers/slapd/back-ldap/bind.c | 23 ++++++++++++++++------- servers/slapd/back-ldap/proto-ldap.h | 4 ++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index d408252bce..1fc7623da2 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -821,11 +821,13 @@ void ldap_back_release_conn_lock( Operation *op, SlapReply *rs, - ldapconn_t *lc, + ldapconn_t **lcp, int dolock ) { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; + ldapconn_t *lc = *lcp; + if ( dolock ) { ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); } @@ -834,6 +836,7 @@ ldap_back_release_conn_lock( lc->lc_refcnt--; if ( LDAP_BACK_CONN_TAINTED( lc ) ) { ldap_back_freeconn( op, lc, 0 ); + *lcp = NULL; } if ( dolock ) { ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); @@ -918,7 +921,7 @@ done:; */ static int ldap_back_dobind_int( - ldapconn_t *lc, + ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok, @@ -927,6 +930,8 @@ ldap_back_dobind_int( { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; + ldapconn_t *lc = *lcp; + int rc, isbound, binding = 0; @@ -1108,6 +1113,7 @@ retry:; /* FIXME: one binding-- too many? */ lc->lc_binding--; ldap_back_freeconn( op, lc, dolock ); + *lcp = NULL; rs->sr_err = slap_map_api2result( rs ); if ( LDAP_BACK_QUARANTINE( li ) ) { @@ -1128,7 +1134,7 @@ done:; LDAP_BACK_CONN_BINDING_CLEAR( lc ); rc = LDAP_BACK_CONN_ISBOUND( lc ); if ( !rc ) { - ldap_back_release_conn_lock( op, rs, lc, dolock ); + ldap_back_release_conn_lock( op, rs, lcp, dolock ); } return rc; @@ -1139,7 +1145,10 @@ ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t { ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private; - return ldap_back_dobind_int( lc, op, rs, sendok, li->li_nretries, 1 ); + /* NOTE: ldap_back_dobind_int() may free lc; + * callers of ldap_back_dobind() MUST no longer deal with lc + * in case of failure */ + return ldap_back_dobind_int( &lc, op, rs, sendok, li->li_nretries, 1 ); } /* @@ -1474,7 +1483,7 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ rc = 0; } else { - rc = ldap_back_dobind_int( *lcp, op, rs, sendok, 0, 0 ); + rc = ldap_back_dobind_int( lcp, op, rs, sendok, 0, 0 ); if ( rc == 0 && *lcp != NULL ) { /* freeit, because lc_refcnt == 1 */ (*lcp)->lc_refcnt = 0; @@ -1490,8 +1499,8 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_ (void *)(*lcp), (*lcp)->lc_refcnt, 0 ); LDAP_BACK_CONN_TAINTED_SET( *lcp ); - ldap_back_release_conn_lock( op, rs, *lcp, 0 ); - *lcp = NULL; + ldap_back_release_conn_lock( op, rs, lcp, 0 ); + assert( *lcp == NULL ); if ( sendok ) { rs->sr_err = LDAP_UNAVAILABLE; diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index d37eea9cbf..7e50550781 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -49,8 +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_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) +void ldap_back_release_conn_lock( Operation *op, SlapReply *rs, ldapconn_t **lcp, 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 ); -- 2.39.5