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 );