From 2716646ed649e2283fe5bb8429370787034d3fdf Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 27 Aug 2012 14:08:06 -0700 Subject: [PATCH] Don't decode entries until we know they're in scope --- servers/slapd/back-mdb/id2entry.c | 15 ++++ servers/slapd/back-mdb/proto-mdb.h | 6 ++ servers/slapd/back-mdb/search.c | 112 +++++++++++++++-------------- 3 files changed, 78 insertions(+), 55 deletions(-) diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c index 29ff9c80ed..9927411bbd 100644 --- a/servers/slapd/back-mdb/id2entry.c +++ b/servers/slapd/back-mdb/id2entry.c @@ -114,6 +114,21 @@ int mdb_id2entry_update( return mdb_id2entry_put(op, txn, mc, e, 0); } +int mdb_id2edata( + Operation *op, + MDB_cursor *mc, + ID id, + MDB_val *data ) +{ + MDB_val key; + + key.mv_data = &id; + key.mv_size = sizeof(ID); + + /* fetch it */ + return mdb_cursor_get( mc, &key, data, MDB_SET ); +} + int mdb_id2entry( Operation *op, MDB_cursor *mc, diff --git a/servers/slapd/back-mdb/proto-mdb.h b/servers/slapd/back-mdb/proto-mdb.h index 799e817170..e989f0f75b 100644 --- a/servers/slapd/back-mdb/proto-mdb.h +++ b/servers/slapd/back-mdb/proto-mdb.h @@ -175,6 +175,12 @@ int mdb_id2entry( ID id, Entry **e); +int mdb_id2edata( + Operation *op, + MDB_cursor *mc, + ID id, + MDB_val *data); + int mdb_entry_return( Operation *op, Entry *e ); BI_entry_release_rw mdb_entry_release; BI_entry_get_rw mdb_entry_get; diff --git a/servers/slapd/back-mdb/search.c b/servers/slapd/back-mdb/search.c index fda36ebf11..f3d51cb550 100644 --- a/servers/slapd/back-mdb/search.c +++ b/servers/slapd/back-mdb/search.c @@ -129,7 +129,7 @@ static Entry * deref_base ( static int search_aliases( Operation *op, SlapReply *rs, - Entry *e, + ID e_id, MDB_txn *txn, MDB_cursor *mci, ID2L scopes, @@ -164,7 +164,7 @@ static int search_aliases( return rs->sr_err; } oldsubs[0] = 1; - oldsubs[1] = e->e_id; + oldsubs[1] = e_id; MDB_IDL_ZERO( visited ); MDB_IDL_ZERO( newsubs ); @@ -176,13 +176,7 @@ static int search_aliases( /* Set curscop to only the aliases in the current scope. Start with * all the aliases, then get the intersection with the scope. */ - rs->sr_err = mdb_idscope( op, txn, e->e_id, aliases, curscop ); - - if (first) { - first = 0; - } else { - mdb_entry_return( op, e ); - } + rs->sr_err = mdb_idscope( op, txn, e_id, aliases, curscop ); /* Dereference all of the aliases in the current scope. */ cursora = 0; @@ -248,9 +242,13 @@ nextido: * be found, ignore it and move on. This should never happen; * we should never see the ID of an entry that doesn't exist. */ - rs->sr_err = mdb_id2entry(op, mci, ido, &e); - if ( rs->sr_err != LDAP_SUCCESS ) { - goto nextido; + { + MDB_val edata; + rs->sr_err = mdb_id2edata(op, mci, ido, &edata); + if ( rs->sr_err != MDB_SUCCESS ) { + goto nextido; + } + e_id = ido; } } return rs->sr_err; @@ -605,6 +603,7 @@ dn2entry_retry: id != NOID ; id = mdb_idl_next( candidates, &cursor ) ) { int scopeok; + MDB_val edata; loop_begin: @@ -640,20 +639,8 @@ loop_begin: } else { /* get the entry */ - rs->sr_err = mdb_id2entry( op, mci, id, &e ); - - if (rs->sr_err == LDAP_BUSY) { - rs->sr_text = "ldap server busy"; - send_ldap_result( op, rs ); - goto done; - - } else if ( rs->sr_err == LDAP_OTHER ) { - rs->sr_text = "internal error"; - send_ldap_result( op, rs ); - goto done; - } - - if ( e == NULL ) { + rs->sr_err = mdb_id2edata( op, mci, id, &edata ); + if ( rs->sr_err == MDB_NOTFOUND ) { if( !MDB_IDL_IS_RANGE(candidates) ) { /* only complain for non-range IDLs */ Debug( LDAP_DEBUG_TRACE, @@ -676,28 +663,14 @@ loop_begin: } goto loop_continue; + } else if ( rs->sr_err ) { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "internal error in mdb_id2edata"; + send_ldap_result( op, rs ); + goto done; } } - if ( is_entry_subentry( e ) ) { - if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { - if(!get_subentries_visibility( op )) { - /* only subentries are visible */ - goto loop_continue; - } - - } else if ( get_subentries( op ) && - !get_subentries_visibility( op )) - { - /* only subentries are visible */ - goto loop_continue; - } - - } else if ( get_subentries_visibility( op )) { - /* only subentries are visible */ - goto loop_continue; - } - /* Does this candidate actually satisfy the search scope? */ scopeok = 0; @@ -725,6 +698,45 @@ loop_begin: break; } + /* Not in scope, ignore it */ + if ( !scopeok ) + { + Debug( LDAP_DEBUG_TRACE, + LDAP_XSTRING(mdb_search) + ": %ld scope not okay\n", + (long) id, 0, 0 ); + goto loop_continue; + } + + if ( id != base->e_id ) { + rs->sr_err = mdb_entry_decode( op, &edata, &e ); + if ( rs->sr_err ) { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "internal error in mdb_endtry_decode"; + send_ldap_result( op, rs ); + goto done; + } + } + + if ( is_entry_subentry( e ) ) { + if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { + if(!get_subentries_visibility( op )) { + /* only subentries are visible */ + goto loop_continue; + } + + } else if ( get_subentries( op ) && + !get_subentries_visibility( op )) + { + /* only subentries are visible */ + goto loop_continue; + } + + } else if ( get_subentries_visibility( op )) { + /* only subentries are visible */ + goto loop_continue; + } + /* aliases were already dereferenced in candidate list */ if ( op->ors_deref & LDAP_DEREF_SEARCHING ) { /* but if the search base is an alias, and we didn't @@ -738,16 +750,6 @@ loop_begin: } } - /* Not in scope, ignore it */ - if ( !scopeok ) - { - Debug( LDAP_DEBUG_TRACE, - LDAP_XSTRING(mdb_search) - ": %ld scope not okay\n", - (long) id, 0, 0 ); - goto loop_continue; - } - if ( !manageDSAit && is_entry_glue( e )) { goto loop_continue; } -- 2.39.5