X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fsearch.c;h=59f81ff9207b5035d1d8cdebfd2edad00309a651;hb=0af1940f3fb59fe57b2281ef253fe1341c505c2c;hp=b2f34ed8b7acaae61c529e9b57094421cb377b34;hpb=df3d8f3e30d896499540a49c9b662155909c3aaf;p=openldap diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index b2f34ed8b7..59f81ff920 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2005 The OpenLDAP Foundation. + * Copyright 2000-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,12 +64,17 @@ static Entry * deref_base ( rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM; rs->sr_text = "maximum deref depth exceeded"; - while (BDB_IDL_N(tmp) < op->o_bd->be_max_deref_depth) { + for (;;) { /* Remember the last entry we looked at, so we can * report broken links */ *matched = e; + if (BDB_IDL_N(tmp) >= op->o_bd->be_max_deref_depth) { + e = NULL; + break; + } + /* If this is part of a subtree or onelevel search, * have we seen this ID before? If so, quit. */ @@ -150,7 +155,11 @@ static int search_aliases( Entry *matched, *a; EntryInfo *ei; struct berval bv_alias = BER_BVC( "alias" ); +#ifdef LDAP_COMP_MATCH AttributeAssertion aa_alias = { NULL, BER_BVNULL, NULL }; +#else + AttributeAssertion aa_alias = { NULL, BER_BVNULL }; +#endif Filter af; DB_LOCK locka, lockr; int first = 1; @@ -310,7 +319,9 @@ bdb_search( Operation *op, SlapReply *rs ) Entry *matched = NULL; EntryInfo *ei, ei_root = {0}; struct berval realbase = BER_BVNULL; +#ifdef SLAP_ACL_HONOR_DISCLOSE slap_mask_t mask; +#endif int manageDSAit; int tentries = 0; ID lastid = NOID; @@ -354,6 +365,9 @@ bdb_search( Operation *op, SlapReply *rs ) ei = &ei_root; rs->sr_err = LDAP_SUCCESS; } else { + if ( op->ors_deref & LDAP_DEREF_FINDING ) { + BDB_IDL_ZERO(candidates); + } dn2entry_retry: /* get entry with reader lock */ rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, @@ -382,10 +396,26 @@ dn2entry_retry: return rs->sr_err; } - if ( e && (op->ors_deref & LDAP_DEREF_FINDING) && is_entry_alias(e) ) { - BDB_IDL_ZERO(candidates); - e = deref_base( op, rs, e, &matched, locker, &lock, - candidates, NULL ); + if ( op->ors_deref & LDAP_DEREF_FINDING ) { + if ( matched && is_entry_alias( matched )) { + struct berval stub; + + stub.bv_val = op->o_req_ndn.bv_val; + stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1; + e = deref_base( op, rs, matched, &matched, locker, &lock, + candidates, NULL ); + if ( e ) { + build_new_dn( &op->o_req_ndn, &e->e_nname, &stub, + op->o_tmpmemctx ); + bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, + e, &lock); + matched = NULL; + goto dn2entry_retry; + } + } else if ( e && is_entry_alias( e )) { + e = deref_base( op, rs, e, &matched, locker, &lock, + candidates, NULL ); + } } if ( e == NULL ) { @@ -411,7 +441,8 @@ dn2entry_retry: erefs = is_entry_referral( matched ) ? get_entry_referrals( op, matched ) : NULL; - rs->sr_err = LDAP_REFERRAL; + if ( rs->sr_err == DB_NOTFOUND ) + rs->sr_err = LDAP_REFERRAL; rs->sr_matched = matched_dn.bv_val; } @@ -434,7 +465,7 @@ dn2entry_retry: #endif rs->sr_ref = referral_rewrite( default_referral, NULL, &op->o_req_dn, op->oq_search.rs_scope ); - rs->sr_err = LDAP_REFERRAL; + rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT; } send_ldap_result( op, rs ); @@ -471,7 +502,7 @@ dn2entry_retry: bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock); } send_ldap_result( op, rs ); - return 1; + return rs->sr_err; } #endif /* SLAP_ACL_HONOR_DISCLOSE */ @@ -637,7 +668,7 @@ dn2entry_retry: for ( id = bdb_idl_first( candidates, &cursor ); id != NOID ; id = bdb_idl_next( candidates, &cursor ) ) { - int scopeok = 0; + int scopeok; loop_begin: @@ -695,28 +726,24 @@ fetch_entry_retry: rs->sr_entry = e; -#ifdef BDB_SUBENTRIES - { - 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 )) - { + 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_visibility( op )) { + } 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; } -#endif /* BDB_SUBENTRIES */ /* Does this candidate actually satisfy the search scope? * @@ -727,6 +754,7 @@ fetch_entry_retry: * scope while we are looking at it, and unless we're using * BDB_HIER, its parents cannot be moved either. */ + scopeok = 0; switch( op->ors_scope ) { case LDAP_SCOPE_BASE: /* This is always true, yes? */ @@ -826,23 +854,14 @@ fetch_entry_retry: if ( rs->sr_err == LDAP_COMPARE_TRUE ) { /* check size limit */ - if ( --op->ors_slimit == -1) { -#ifdef SLAP_ZONE_ALLOC - slap_zn_runlock(bdb->bi_cache.c_zctx, e); -#endif - bdb_cache_return_entry_r( bdb->bi_dbenv, - &bdb->bi_cache, e, &lock ); - e = NULL; - rs->sr_entry = NULL; - rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; - rs->sr_ref = rs->sr_v2ref; - send_ldap_result( op, rs ); - rs->sr_err = LDAP_SUCCESS; - goto done; - } - if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) { +#ifdef SLAP_ZONE_ALLOC + slap_zn_runlock(bdb->bi_cache.c_zctx, e); +#endif + bdb_cache_return_entry_r( bdb->bi_dbenv, + &bdb->bi_cache, e, &lock ); + e = NULL; send_paged_response( op, rs, &lastid, tentries ); goto done; } @@ -851,20 +870,20 @@ fetch_entry_retry: if (e) { /* safe default */ - int result = -1; rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_operational_attrs = NULL; rs->sr_ctrls = NULL; rs->sr_flags = 0; rs->sr_err = LDAP_SUCCESS; - result = send_search_entry( op, rs ); + rs->sr_err = send_search_entry( op, rs ); - switch (result) { - case 0: /* entry sent ok */ + switch ( rs->sr_err ) { + case LDAP_SUCCESS: /* entry sent ok */ break; - case 1: /* entry not sent */ + default: /* entry not sent */ break; - case -1: /* connection closed */ + case LDAP_UNAVAILABLE: + case LDAP_SIZELIMIT_EXCEEDED: #ifdef SLAP_ZONE_ALLOC slap_zn_runlock(bdb->bi_cache.c_zctx, e); #endif @@ -872,7 +891,14 @@ fetch_entry_retry: &bdb->bi_cache, e, &lock); e = NULL; rs->sr_entry = NULL; - rs->sr_err = LDAP_OTHER; + if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) { + rs->sr_ref = rs->sr_v2ref; + send_ldap_result( op, rs ); + rs->sr_err = LDAP_SUCCESS; + + } else { + rs->sr_err = LDAP_OTHER; + } goto done; } } @@ -895,8 +921,6 @@ loop_continue: e = NULL; rs->sr_entry = NULL; } - - ldap_pvt_thread_yield(); } nochange: @@ -949,7 +973,7 @@ static int oc_filter( { int rc = 0; - assert( f ); + assert( f != NULL ); if( cur > *max ) *max = cur; @@ -1016,10 +1040,16 @@ static int search_candidates( int rc, depth = 1; Filter f, rf, xf, nf; ID *stack; +#ifdef LDAP_COMP_MATCH AttributeAssertion aa_ref = { NULL, BER_BVNULL, NULL }; -#ifdef BDB_SUBENTRIES +#else + AttributeAssertion aa_ref = { NULL, BER_BVNULL }; +#endif Filter sf; +#ifdef LDAP_COMP_MATCH AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL }; +#else + AttributeAssertion aa_subentry = { NULL, BER_BVNULL }; #endif /* @@ -1066,7 +1096,6 @@ static int search_candidates( /* Filter depth increased again, adding dummy clause */ depth++; -#ifdef BDB_SUBENTRIES if( get_subentries_visibility( op ) ) { struct berval bv_subentry = BER_BVC( "subentry" ); sf.f_choice = LDAP_FILTER_EQUALITY; @@ -1076,7 +1105,6 @@ static int search_candidates( sf.f_next = nf.f_next; nf.f_next = &sf; } -#endif /* Allocate IDL stack, plus 1 more for former tmp */ if ( depth+1 > bdb->bi_search_stack_depth ) { @@ -1249,7 +1277,8 @@ send_paged_response( op->o_conn->c_pagedresults_state.ps_cookie = respcookie; op->o_conn->c_pagedresults_state.ps_count = - ((PagedResultsState *)op->o_pagedresults_state)->ps_count + rs->sr_nentries; + ((PagedResultsState *)op->o_pagedresults_state)->ps_count + + rs->sr_nentries; /* return size of 0 -- no estimate */ ber_printf( ber, "{iO}", 0, &cookie );