]> git.sur5r.net Git - openldap/commitdiff
fix and improve candidate selection (ITS#6799)
authorPierangelo Masarati <ando@openldap.org>
Wed, 19 Jan 2011 17:36:35 +0000 (17:36 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 19 Jan 2011 17:36:35 +0000 (17:36 +0000)
servers/slapd/back-meta/candidates.c
servers/slapd/back-meta/conn.c

index 4543c76ca8ee9ac249a4cb56b2eac87fa78c2cae..be29071ebdc5557eba847f2420a08225113ba5de 100644 (file)
@@ -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;
index d96b890007d1132bbd7538bcab7addcf8be586a0..8f2b9bd335641a45e2e0f15779f93c5471a74a97 100644 (file)
@@ -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 ) )
                        {
 
                                /*