]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-mdb/dn2id.c
ITS#7705,#7800 fix back-mdb pagedResults search
[openldap] / servers / slapd / back-mdb / dn2id.c
index ceacb1796fe166bef342f42821d70fbfd7093249..b0e6905c7b439e1029b3e186dc8079707e4f3c0a 100644 (file)
@@ -703,7 +703,7 @@ mdb_idscopes(
        ID2 id2;
        char    *ptr;
        int             rc = 0;
-       unsigned int x;
+       unsigned int x, y;
        unsigned int nrlen, rlen;
        diskNode *d;
 
@@ -723,6 +723,7 @@ mdb_idscopes(
                return MDB_SUCCESS;
        }
 
+       isc->sctmp[0].mid = 0;
        while (id) {
                if ( !rc ) {
                        key.mv_data = &id;
@@ -742,21 +743,34 @@ mdb_idscopes(
                isc->numrdns++;
 
                if (!rc && id != isc->id) {
+                       /* remember our chain of parents */
                        id2.mid = id;
                        id2.mval = data;
-                       mdb_id2l_insert( isc->scopes, &id2 );
+                       mdb_id2l_insert( isc->sctmp, &id2 );
                }
                ptr = data.mv_data;
                ptr += data.mv_size - sizeof(ID);
                memcpy( &id, ptr, sizeof(ID) );
+               y = x;
                x = mdb_id2l_search( isc->scopes, id );
                if ( x <= isc->scopes[0].mid && isc->scopes[x].mid == id ) {
                        if ( !isc->scopes[x].mval.mv_data ) {
+                               /* This node is in scope, add parent chain to scope */
+                               int i = isc->sctmp[0].mid;
+                               for ( i = 1; i <= isc->sctmp[0].mid; i++ )
+                                       mdb_id2l_insert( isc->scopes, &isc->sctmp[i] );
+                               /* check id again since inserts may have changed its position */
+                               if ( isc->scopes[x].mid != id )
+                                       x = mdb_id2l_search( isc->scopes, id );
                                isc->nscope = x;
                                return MDB_SUCCESS;
                        }
                        data = isc->scopes[x].mval;
                        rc = 1;
+               } else {
+                       /* If we didn't advance, some parent is missing */
+                       if ( x == y )
+                               return MDB_NOTFOUND;
                }
                if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
                        break;