]> git.sur5r.net Git - openldap/commitdiff
refine fix to ITS#4315; apply it to back-meta as well
authorPierangelo Masarati <ando@openldap.org>
Mon, 9 Jan 2006 14:20:37 +0000 (14:20 +0000)
committerPierangelo Masarati <ando@openldap.org>
Mon, 9 Jan 2006 14:20:37 +0000 (14:20 +0000)
servers/slapd/back-ldap/bind.c
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/conn.c

index 8fb0a7ad081d4f02baa9d0f5c613d2eab0c2272b..e8dc09a830c3c0e33dac23838dc88788fb1cb274 100644 (file)
@@ -468,7 +468,7 @@ ldapconn_t *
 ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
        ldapinfo_t      *li = (ldapinfo_t *)op->o_bd->be_private;
-       ldapconn_t      *lc,
+       ldapconn_t      *lc = NULL,
                        lc_curr = { 0 };
        int             refcnt = 1;
 
@@ -490,9 +490,7 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
        }
 
        /* Explicit Bind requests always get their own conn */
-       if ( sendok & LDAP_BACK_BINDING ) {
-               lc = NULL;
-       } else {
+       if ( !( sendok & LDAP_BACK_BINDING ) ) {
                /* Searches for a ldapconn in the avl tree */
 retry_lock:
                ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
@@ -500,13 +498,13 @@ retry_lock:
                lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, 
                                (caddr_t)&lc_curr, ldap_back_conn_cmp );
                if ( lc != NULL ) {
-                       refcnt = ++lc->lc_refcnt;
                        /* Don't reuse connections while they're still binding */
-                       if ( LDAP_BACK_CONN_BINDING( lc )) {
+                       if ( LDAP_BACK_CONN_BINDING( lc ) ) {
                                ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
                                ldap_pvt_thread_yield();
                                goto retry_lock;
                        }
+                       refcnt = ++lc->lc_refcnt;
                }
                ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
        }
@@ -516,9 +514,9 @@ retry_lock:
                if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
                        return NULL;
                }
-               if ( sendok & LDAP_BACK_BINDING )
+               if ( sendok & LDAP_BACK_BINDING ) {
                        LDAP_BACK_CONN_BINDING_SET( lc );
-
+               }
                lc->lc_conn = lc_curr.lc_conn;
                ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
 
index 54c669e7fcd54431f764b99757ccce30b90809b3..cc2b5bcb99788edcecebe6b410356a462388c06e 100644 (file)
@@ -91,7 +91,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
        /* we need meta_back_getconn() not send result even on error,
         * because we want to intercept the error and make it
         * invalidCredentials */
-       mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_DONTSEND );
+       mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_SERR );
        if ( !mc ) {
                char    buf[ SLAP_TEXT_BUFLEN ];
 
index b92b285f2891fae21bc78e31251204cd8b10a33d..08fcbea92c0f71447d372c62bda9d01a9079e112 100644 (file)
@@ -755,21 +755,31 @@ meta_back_getconn(
                }
        }
 
-       /* Searches for a metaconn in the avl tree */
-       ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-       mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
-               (caddr_t)&mc_curr, meta_back_conn_cmp );
-       if ( mc ) {
-               if ( mc->mc_tainted ) {
-                       rs->sr_err = LDAP_UNAVAILABLE;
-                       rs->sr_text = "remote server unavailable";
-                       ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
-                       return NULL;
-               }
+       /* Explicit Bind requests always get their own conn */
+       if ( !( sendok & LDAP_BACK_BINDING ) ) {
+               /* Searches for a metaconn in the avl tree */
+retry_lock:
+               ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+               mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
+                       (caddr_t)&mc_curr, meta_back_conn_cmp );
+               if ( mc ) {
+                       if ( mc->mc_tainted ) {
+                               rs->sr_err = LDAP_UNAVAILABLE;
+                               rs->sr_text = "remote server unavailable";
+                               ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+                               return NULL;
+                       }
                        
-               mc->mc_refcnt++;
+                       /* Don't reuse connections while they're still binding */
+                       if ( LDAP_BACK_CONN_BINDING( mc ) ) {
+                               ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
+                               ldap_pvt_thread_yield();
+                               goto retry_lock;
+                       }
+                       mc->mc_refcnt++;
+               }
+               ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
        }
-       ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
        switch ( op->o_tag ) {
        case LDAP_REQ_ADD:
@@ -822,6 +832,9 @@ meta_back_getconn(
                        mc->mc_conn = mc_curr.mc_conn;
                        ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                        new_conn = 1;
+                       if ( sendok & LDAP_BACK_BINDING ) {
+                               LDAP_BACK_CONN_BINDING_SET( mc );
+                       }
                }
 
                for ( i = 0; i < mi->mi_ntargets; i++ ) {
@@ -947,13 +960,15 @@ meta_back_getconn(
                        /* Retries searching for a metaconn in the avl tree
                         * the reason is that the connection might have been
                         * created by meta_back_get_candidate() */
-                       ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
-                       mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
-                               (caddr_t)&mc_curr, meta_back_conn_cmp );
-                       if ( mc != NULL ) {
-                               mc->mc_refcnt++;
+                       if ( !( sendok & LDAP_BACK_BINDING ) ) {
+                               ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
+                               mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree, 
+                                       (caddr_t)&mc_curr, meta_back_conn_cmp );
+                               if ( mc != NULL ) {
+                                       mc->mc_refcnt++;
+                               }
+                               ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
                        }
-                       ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
 
                        /* Looks like we didn't get a bind. Open a new session... */
                        if ( mc == NULL ) {
@@ -961,6 +976,9 @@ meta_back_getconn(
                                mc->mc_conn = mc_curr.mc_conn;
                                ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                                new_conn = 1;
+                               if ( sendok & LDAP_BACK_BINDING ) {
+                                       LDAP_BACK_CONN_BINDING_SET( mc );
+                               }
                        }
                }
 
@@ -1015,6 +1033,9 @@ meta_back_getconn(
                        mc->mc_conn = mc_curr.mc_conn;
                        ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
                        new_conn = 1;
+                       if ( sendok & LDAP_BACK_BINDING ) {
+                               LDAP_BACK_CONN_BINDING_SET( mc );
+                       }
                }
 
                for ( i = 0; i < mi->mi_ntargets; i++ ) {
@@ -1165,6 +1186,7 @@ meta_back_release_conn(
        ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
        assert( mc->mc_refcnt > 0 );
        mc->mc_refcnt--;
+       LDAP_BACK_CONN_BINDING_CLEAR( mc );
        if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
                (void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
                                meta_back_conn_cmp );