diff --git a/CHANGES b/CHANGES index b53d1603139037588c9cee52cd192f1bc0be2133..8160307fcda08327dccd7e66ff23f75af2e48d96 100644 --- a/CHANGES +++ b/CHANGES @@ -75,6 +75,7 @@ OpenLDAP 2.4.24 Engineering Fixed slapd-meta to correctly rebind as user (ITS#6574) Fixed slapd-meta with SASL/EXTERNAL (ITS#6642) Fixed slapd-meta matchedDN return code (ITS#6774) + Fixed slapd-meta candidate selection (ITS#6799) Fixed slapd-monitor hasSubordinates generation (ITS#6712) Fixed slapd-monitor abandon processing (ITS#6783) Fixed slapd-monitor entry locks (ITS#6787) diff --git a/servers/slapd/back-meta/candidates.c b/servers/slapd/back-meta/candidates.c index 4543c76ca8ee9ac249a4cb56b2eac87fa78c2cae..be29071ebdc5557eba847f2420a08225113ba5de 100644 --- a/servers/slapd/back-meta/candidates.c +++ b/servers/slapd/back-meta/candidates.c @@ -63,7 +63,14 @@ meta_back_is_candidate( struct berval *ndn, int scope ) { - if ( dnIsSuffix( ndn, &mt->mt_nsuffix ) ) { + struct berval rdn; + int d = ndn->bv_len - mt->mt_nsuffix.bv_len; + + if ( d >= 0 ) { + if ( !dnIsSuffix( ndn, &mt->mt_nsuffix ) ) { + return META_NOT_CANDIDATE; + } + if ( mt->mt_subtree_exclude ) { int i; @@ -80,18 +87,16 @@ meta_back_is_candidate( return META_CANDIDATE; case LDAP_SCOPE_SUBORDINATE: - if ( ndn->bv_len > mt->mt_nsuffix.bv_len ) { + if ( d > 0 ) { return META_CANDIDATE; } break; /* nearly useless; not allowed by config */ case LDAP_SCOPE_ONELEVEL: - if ( ndn->bv_len > mt->mt_nsuffix.bv_len ) { - struct berval rdn = *ndn; - - rdn.bv_len -= mt->mt_nsuffix.bv_len - + STRLENOF( "," ); + if ( d > 0 ) { + rdn.bv_val = ndn->bv_val; + rdn.bv_len = (ber_len_t)d - STRLENOF( "," ); if ( dnIsOneLevelRDN( &rdn ) ) { return META_CANDIDATE; } @@ -100,20 +105,33 @@ meta_back_is_candidate( /* nearly useless; not allowed by config */ case LDAP_SCOPE_BASE: - if ( ndn->bv_len == mt->mt_nsuffix.bv_len ) { + if ( d == 0 ) { return META_CANDIDATE; } break; } - return META_NOT_CANDIDATE; - } + } else /* if ( d < 0 ) */ { + if ( !dnIsSuffix( &mt->mt_nsuffix, ndn ) ) { + return META_NOT_CANDIDATE; + } + + switch ( scope ) { + case LDAP_SCOPE_SUBTREE: + case LDAP_SCOPE_SUBORDINATE: + /* + * suffix longer than dn, but common part matches + */ + return META_CANDIDATE; - if ( scope == LDAP_SCOPE_SUBTREE && dnIsSuffix( &mt->mt_nsuffix, ndn ) ) { - /* - * suffix longer than dn, but common part matches - */ - return META_CANDIDATE; + case LDAP_SCOPE_ONELEVEL: + rdn.bv_val = mt->mt_nsuffix.bv_val; + rdn.bv_len = (ber_len_t)(-d) - STRLENOF( "," ); + if ( dnIsOneLevelRDN( &rdn ) ) { + return META_CANDIDATE; + } + break; + } } return META_NOT_CANDIDATE; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 3014212d7e40770b846ea34a3f290879ef3d1bde..52a5f82d2316b47cb266e055d112aeaf1e9d41ac 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -1537,7 +1537,7 @@ retry_lock2:; if ( i == cached || meta_back_is_candidate( mt, &op->o_req_ndn, - LDAP_SCOPE_SUBTREE ) ) + op->o_tag == LDAP_REQ_SEARCH ? op->ors_scope : LDAP_SCOPE_SUBTREE ) ) { /*