X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fsearch.c;h=59f81ff9207b5035d1d8cdebfd2edad00309a651;hb=0af1940f3fb59fe57b2281ef253fe1341c505c2c;hp=a7525be1d813774c8ad10c7c6ad86b5d199f3a04;hpb=e93c8f18d4a4240a3f22265a1475fd09178589a2;p=openldap diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index a7525be1d8..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. */ @@ -360,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, @@ -388,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 ) { @@ -417,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; } @@ -440,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 ); @@ -477,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 */ @@ -701,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? * @@ -833,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; } @@ -858,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 @@ -879,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; } } @@ -902,8 +921,6 @@ loop_continue: e = NULL; rs->sr_entry = NULL; } - - ldap_pvt_thread_yield(); } nochange: @@ -1028,13 +1045,11 @@ static int search_candidates( #else AttributeAssertion aa_ref = { NULL, BER_BVNULL }; #endif -#ifdef BDB_SUBENTRIES Filter sf; #ifdef LDAP_COMP_MATCH AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL }; #else AttributeAssertion aa_subentry = { NULL, BER_BVNULL }; -#endif #endif /* @@ -1081,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; @@ -1091,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 ) {