]> git.sur5r.net Git - openldap/commitdiff
ITS#7577 alias fixes
authorHoward Chu <hyc@openldap.org>
Wed, 24 Apr 2013 10:11:14 +0000 (03:11 -0700)
committerHoward Chu <hyc@openldap.org>
Sun, 28 Apr 2013 19:25:58 +0000 (12:25 -0700)
servers/slapd/back-mdb/dn2id.c
servers/slapd/back-mdb/idl.h
servers/slapd/back-mdb/search.c

index 1f2c4ea33e77026a3490461ebc1ee28e1503fb2e..64c5634e24532cd74757bb2077be6a1ae66e41b4 100644 (file)
@@ -629,9 +629,9 @@ mdb_idscope(
        MDB_dbi dbi = mdb->mi_dn2id;
        MDB_val         key, data;
        MDB_cursor      *cursor;
-       ID ida, id, cid, ci0, idc = 0;
+       ID ida, id, cid = 0, ci0 = 0, idc = 0;
        char    *ptr;
-       int             rc;
+       int             rc, copy;
 
        key.mv_size = sizeof(ID);
 
@@ -649,17 +649,14 @@ mdb_idscope(
        }
 
        while (ida != NOID) {
+               copy = 1;
                id = ida;
                while (id) {
                        key.mv_data = &id;
                        rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
                        if ( rc ) {
-                               /* not found, move on to next */
-                               if (idc) {
-                                       if (ci0 != cid)
-                                               ids[ci0] = ids[cid];
-                                       ci0++;
-                               }
+                               /* not found, drop this from ids */
+                               copy = 0;
                                break;
                        }
                        ptr = data.mv_data;
@@ -668,19 +665,20 @@ mdb_idscope(
                        if ( id == base ) {
                                res[0]++;
                                res[res[0]] = ida;
-                               if (idc)
-                                       idc--;
+                               copy = 0;
                                break;
-                       } else {
-                               if (idc) {
-                                       if (ci0 != cid)
-                                               ids[ci0] = ids[cid];
-                                       ci0++;
-                               }
                        }
                        if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
                                break;
                }
+               if (idc) {
+                       if (copy) {
+                               if (ci0 != cid)
+                                       ids[ci0] = ids[cid];
+                               ci0++;
+                       } else
+                               idc--;
+               }
                ida = mdb_idl_next( ids, &cid );
        }
        if (!MDB_IDL_IS_RANGE( ids ))
@@ -777,11 +775,11 @@ mdb_dn2id_walk(
                isc->numrdns++;
                isc->nscope = 0;
                /* skip base if not a subtree walk */
-               if ( op->ors_scope == LDAP_SCOPE_SUBTREE ||
-                       op->ors_scope == LDAP_SCOPE_BASE )
+               if ( isc->oscope == LDAP_SCOPE_SUBTREE ||
+                       isc->oscope == LDAP_SCOPE_BASE )
                        return rc;
        }
-       if ( op->ors_scope == LDAP_SCOPE_BASE )
+       if ( isc->oscope == LDAP_SCOPE_BASE )
                return MDB_NOTFOUND;
 
        for (;;) {
@@ -819,7 +817,7 @@ mdb_dn2id_walk(
                        continue;
 
                } else if ( rc == MDB_NOTFOUND ) {
-                       if ( !isc->nscope && op->ors_scope != LDAP_SCOPE_ONELEVEL ) {
+                       if ( !isc->nscope && isc->oscope != LDAP_SCOPE_ONELEVEL ) {
                                /* reset to first dup */
                                mdb_cursor_get( isc->mc, &key, NULL, MDB_GET_CURRENT );
                                mdb_cursor_get( isc->mc, &key, &data, MDB_SET );
index bd18864a709afb87f8f4e0c828ddaf12e7133785..8ce742a8c1b2bfe7f355c33feb5e5ab25f61c409 100644 (file)
@@ -89,6 +89,7 @@ typedef struct IdScopes {
        ID2L scopes;
        int numrdns;
        int nscope;
+       int oscope;
        struct berval rdns[MAXRDNS];
        struct berval nrdns[MAXRDNS];
 } IdScopes;
index 09bdf60c96111c61ecd065599841595e625ac4ea..30e2eeda655b66a2ecdcfc1f9cbf17abcf3de18f 100644 (file)
@@ -218,6 +218,7 @@ static int search_aliases(
                                 */
                                mdb_entry_return( op, matched );
                                rs->sr_text = NULL;
+                               rs->sr_err = 0;
                        }
                }
                /* If this is a OneLevel search, we're done; oldsubs only had one
@@ -316,9 +317,10 @@ int
 mdb_search( Operation *op, SlapReply *rs )
 {
        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
-       ID              id, cursor, nsubs, ncand;
+       ID              id, cursor, nsubs, ncand, cscope;
        ID              lastid = NOID;
        ID              candidates[MDB_IDL_UM_SIZE];
+       ID              iscopes[MDB_IDL_DB_SIZE];
        ID2             *scopes;
        Entry           *e = NULL, *base = NULL;
        Entry           *matched = NULL;
@@ -366,6 +368,7 @@ mdb_search( Operation *op, SlapReply *rs )
        isc.mt = ltid;
        isc.mc = mcd;
        isc.scopes = scopes;
+       isc.oscope = op->ors_scope;
 
        if ( op->ors_deref & LDAP_DEREF_FINDING ) {
                MDB_IDL_ZERO(candidates);
@@ -636,6 +639,19 @@ dn2entry_retry:
        if ( nsubs < ncand ) {
                int rc;
                /* Do scope-based search */
+
+               /* if any alias scopes were set, save them */
+               if (scopes[0].mid > 1) {
+                       cursor = 1;
+                       for (cscope = 1; cscope <= scopes[0].mid; cscope++) {
+                               /* Ignore the original base */
+                               if (scopes[cscope].mid == base->e_id)
+                                       continue;
+                               iscopes[cursor++] = scopes[cscope].mid;
+                       }
+               }
+               iscopes[0] = scopes[0].mid - 1;
+
                isc.id = base->e_id;
                isc.numrdns = 0;
                rc = mdb_dn2id_walk( op, &isc );
@@ -643,6 +659,7 @@ dn2entry_retry:
                        id = NOID;
                else
                        id = isc.id;
+               cscope = 0;
        } else {
                id = mdb_idl_first( candidates, &cursor );
        }
@@ -989,9 +1006,30 @@ loop_continue:
 
                if ( nsubs < ncand ) {
                        int rc = mdb_dn2id_walk( op, &isc );
-                       if (rc)
+                       if (rc) {
                                id = NOID;
-                       else
+                               /* We got to the end of a subtree. If there are any
+                                * alias scopes left, search them too.
+                                */
+                               while (iscopes[0] && cscope < iscopes[0]) {
+                                       cscope++;
+                                       isc.id = iscopes[cscope];
+                                       if ( base )
+                                               mdb_entry_return( op, base );
+                                       rs->sr_err = mdb_id2entry(op, mci, isc.id, &base);
+                                       if ( !rs->sr_err ) {
+                                               mdb_id2name( op, ltid, &isc.mc, isc.id, &base->e_name, &base->e_nname );
+                                               isc.numrdns = 0;
+                                               if (isc.oscope == LDAP_SCOPE_ONELEVEL)
+                                                       isc.oscope = LDAP_SCOPE_BASE;
+                                               rc = mdb_dn2id_walk( op, &isc );
+                                               if ( !rc ) {
+                                                       id = isc.id;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       } else
                                id = isc.id;
                } else {
                        id = mdb_idl_next( candidates, &cursor );