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);
 
        }
 
        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;
                        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 ))
                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 (;;) {
                        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 );
 
                                 */
                                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
 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;
        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);
        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 );
                        id = NOID;
                else
                        id = isc.id;
+               cscope = 0;
        } else {
                id = mdb_idl_first( candidates, &cursor );
        }
 
                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 );