From: Howard Chu Date: Wed, 24 Apr 2013 10:11:14 +0000 (-0700) Subject: ITS#7577 alias fixes X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=fb537d747c6fd43e08986e99b1fe7781660feaf3;p=openldap ITS#7577 alias fixes --- diff --git a/servers/slapd/back-mdb/dn2id.c b/servers/slapd/back-mdb/dn2id.c index 1f2c4ea33e..64c5634e24 100644 --- a/servers/slapd/back-mdb/dn2id.c +++ b/servers/slapd/back-mdb/dn2id.c @@ -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 ); diff --git a/servers/slapd/back-mdb/idl.h b/servers/slapd/back-mdb/idl.h index bd18864a70..8ce742a8c1 100644 --- a/servers/slapd/back-mdb/idl.h +++ b/servers/slapd/back-mdb/idl.h @@ -89,6 +89,7 @@ typedef struct IdScopes { ID2L scopes; int numrdns; int nscope; + int oscope; struct berval rdns[MAXRDNS]; struct berval nrdns[MAXRDNS]; } IdScopes; diff --git a/servers/slapd/back-mdb/search.c b/servers/slapd/back-mdb/search.c index 09bdf60c96..30e2eeda65 100644 --- a/servers/slapd/back-mdb/search.c +++ b/servers/slapd/back-mdb/search.c @@ -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 );