]> git.sur5r.net Git - openldap/commitdiff
fix previous commit
authorPierangelo Masarati <ando@openldap.org>
Sat, 8 Apr 2006 14:45:19 +0000 (14:45 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 8 Apr 2006 14:45:19 +0000 (14:45 +0000)
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/search.c

index 2242a6d23f8d5c1a32a776783969889622c805b3..b6b449cd8228bcf0383146d03cd1e4bef1478a97 100644 (file)
@@ -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 );
 
index 5e0c2682c75e7017e9d59dcb4fc126b9fc1aba8e..e0537e870f24b123bf671736c5b48b8498d54205 100644 (file)
@@ -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;
index cdb9c581ee8347882b4f72433de59311fe65750e..de4180e65aba33d65eeed5195a14b468a44c2f74 100644 (file)
@@ -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;