]> git.sur5r.net Git - openldap/commitdiff
ldap_back_dobind_int() may need to free a connection
authorPierangelo Masarati <ando@openldap.org>
Mon, 11 Sep 2006 22:45:19 +0000 (22:45 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 11 Sep 2006 22:45:19 +0000 (22:45 +0000)
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/proto-ldap.h

index d408252bce72f563ccfafc9291f5fbc8dddd0d41..1fc7623da2484a4059224208c0b52592e1d70d92 100644 (file)
@@ -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;
index d37eea9cbf782eb2cf3c03ab4eb6b4eed8084ce1..7e505507815f54f2697d29c0b6e83e40b51971b5 100644 (file)
@@ -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 );