]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-meta/conn.c
don't lookup rootdn if the password is incorrect (ITS#4004)
[openldap] / servers / slapd / back-meta / conn.c
index 422107d78d7cb82693b8fffc00e4e2dd6ebd30d9..a0ae2801249fe69e0b607e747dff707e43900006 100644 (file)
@@ -526,6 +526,7 @@ meta_back_get_candidate(
                         * a candidate, try using it (FIXME: YMMV) */
                        if ( mi->mi_defaulttarget != META_DEFAULT_TARGET_NONE
                                && meta_back_is_candidate( &mi->mi_targets[ mi->mi_defaulttarget ].mt_nsuffix,
+                                               mi->mi_targets[ mi->mi_defaulttarget ].mt_scope,
                                                ndn, op->o_tag == LDAP_REQ_SEARCH ? op->ors_scope : LDAP_SCOPE_BASE ) )
                        {
                                candidate = mi->mi_defaulttarget;
@@ -538,11 +539,16 @@ meta_back_get_candidate(
                        }
                        break;
                }
+
+       } else {
+               rs->sr_err = LDAP_SUCCESS;
        }
 
        return candidate;
 }
 
+static void    *meta_back_candidates_dummy;
+
 static void
 meta_back_candidates_keyfree(
        void            *key,
@@ -564,7 +570,7 @@ meta_back_candidates_get( Operation *op )
                void            *data = NULL;
 
                ldap_pvt_thread_pool_getkey( op->o_threadctx,
-                               meta_back_candidates_keyfree, &data, NULL );
+                               &meta_back_candidates_dummy, &data, NULL );
                mc = (metacandidates_t *)data;
 
        } else {
@@ -580,7 +586,7 @@ meta_back_candidates_get( Operation *op )
 
                        data = (void *)mc;
                        ldap_pvt_thread_pool_setkey( op->o_threadctx,
-                                       meta_back_candidates_keyfree, data,
+                                       &meta_back_candidates_dummy, data,
                                        meta_back_candidates_keyfree );
 
                } else {
@@ -724,9 +730,11 @@ meta_back_getconn(
                         * The target is activated; if needed, it is
                         * also init'd
                         */
-                       int lerr = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
-                                       &mc->mc_conns[ i ], sendok );
-                       if ( lerr == LDAP_SUCCESS ) {
+                       candidates[ i ].sr_err =
+                               meta_back_init_one_conn( op, rs,
+                                               &mi->mi_targets[ i ],
+                                               &mc->mc_conns[ i ], sendok );
+                       if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
                                candidates[ i ].sr_tag = META_CANDIDATE;
                                ncandidates++;
                                
@@ -738,7 +746,7 @@ meta_back_getconn(
                                 * be tried?
                                 */
                                candidates[ i ].sr_tag = META_NOT_CANDIDATE;
-                               err = lerr;
+                               err = candidates[ i ].sr_err;
                                continue;
                        }
                }
@@ -795,6 +803,10 @@ meta_back_getconn(
                        }
        
                        if ( rs->sr_err != LDAP_SUCCESS ) {
+                               if ( mc != NULL ) {
+                                       meta_back_release_conn( op, mc );
+                               }
+
                                if ( sendok & LDAP_BACK_SENDERR ) {
                                        if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
                                                rs->sr_matched = op->o_bd->be_suffix[ 0 ].bv_val;
@@ -803,18 +815,24 @@ meta_back_getconn(
                                        rs->sr_text = NULL;
                                        rs->sr_matched = NULL;
                                }
+                       
                                return NULL;
                        }
                }
 
                if ( newparent && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
                {
+                       if ( mc != NULL ) {
+                               meta_back_release_conn( op, mc );
+                       }
+
                        rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
                        rs->sr_text = "cross-target rename not supported";
                        if ( sendok & LDAP_BACK_SENDERR ) {
                                send_ldap_result( op, rs );
                                rs->sr_text = NULL;
                        }
+
                        return NULL;
                }
 
@@ -872,6 +890,7 @@ meta_back_getconn(
                        return NULL;
                }
 
+               candidates[ i ].sr_err = LDAP_SUCCESS;
                candidates[ i ].sr_tag = META_CANDIDATE;
                ncandidates++;
 
@@ -894,6 +913,7 @@ meta_back_getconn(
                for ( i = 0; i < mi->mi_ntargets; i++ ) {
                        if ( i == cached 
                                || meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix,
+                                               mi->mi_targets[ i ].mt_scope,
                                                &op->o_req_ndn, LDAP_SCOPE_SUBTREE ) )
                        {
 
@@ -906,6 +926,7 @@ meta_back_getconn(
                                                &mc->mc_conns[ i ], sendok );
                                if ( lerr == LDAP_SUCCESS ) {
                                        candidates[ i ].sr_tag = META_CANDIDATE;
+                                       candidates[ i ].sr_err = LDAP_SUCCESS;
                                        ncandidates++;
 
                                        Debug( LDAP_DEBUG_TRACE, "%s: meta_back_init_one_conn(%d)\n",
@@ -921,7 +942,8 @@ meta_back_getconn(
                                        if ( new_conn ) {
                                                ( void )meta_clear_one_candidate( &mc->mc_conns[ i ] );
                                        }
-                                       candidates[ i ].sr_tag = META_NOT_CANDIDATE;
+                                       /* leave the target candidate, but record the error for later use */
+                                       candidates[ i ].sr_err = lerr;
                                        err = lerr;
 
                                        Debug( LDAP_DEBUG_ANY, "%s: meta_back_init_one_conn(%d) failed: %d\n",