/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2000-2005 The OpenLDAP Foundation.
+ * Copyright 2000-2007 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
ID *lastid,
int tentries );
-static int bdb_pfid_cmp( const void *v_id1, const void *v_id2 );
-static ID* bdb_id_dup( Operation *op, ID *id );
-
/* Dereference aliases for a single alias entry. Return the final
* dereferenced entry on success, NULL on any failure.
*/
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.
*/
/* Free the previous entry, continue to work with the
* one we just retrieved.
*/
- bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
- *matched, lock);
+ bdb_cache_return_entry_r( bdb, *matched, lock);
*lock = lockr;
/* We found a regular entry. Return this to the caller. The
Entry *matched, *a;
EntryInfo *ei;
struct berval bv_alias = BER_BVC( "alias" );
- AttributeAssertion aa_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;
/* Find all aliases in database */
BDB_IDL_ZERO( aliases );
- rs->sr_err = bdb_filter_candidates( op, &af, aliases,
+ rs->sr_err = bdb_filter_candidates( op, locker, &af, aliases,
curscop, visited );
if (rs->sr_err != LDAP_SUCCESS) {
return rs->sr_err;
* to the cumulative list of candidates.
*/
BDB_IDL_CPY( curscop, aliases );
- rs->sr_err = bdb_dn2idl( op, e, subscop,
+ rs->sr_err = bdb_dn2idl( op, locker, e, subscop,
subscop2+BDB_IDL_DB_SIZE );
if (first) {
first = 0;
} else {
- bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &locka);
+ bdb_cache_return_entry_r (bdb, e, &locka);
}
BDB_IDL_CPY(subscop2, subscop);
rs->sr_err = bdb_idl_intersection(curscop, subscop);
* turned into a range that spans IDs indiscriminately
*/
if (!is_entry_alias(a)) {
- bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
- a, &lockr);
+ bdb_cache_return_entry_r (bdb, a, &lockr);
continue;
}
bdb_idl_insert(newsubs, a->e_id);
bdb_idl_insert(scopes, a->e_id);
}
- bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
- a, &lockr);
+ bdb_cache_return_entry_r( bdb, a, &lockr);
} else if (matched) {
/* Alias could not be dereferenced, or it deref'd to
* an ID we've already seen. Ignore it.
*/
- bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache,
- matched, &lockr );
+ bdb_cache_return_entry_r( bdb, matched, &lockr );
rs->sr_text = NULL;
}
}
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,
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, 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 ) {
if ( matched != NULL ) {
BerVarray erefs = NULL;
-#ifdef SLAP_ACL_HONOR_DISCLOSE
/* return referral only if "disclose"
* is granted on the object */
if ( ! access_allowed( op, matched,
{
rs->sr_err = LDAP_NO_SUCH_OBJECT;
- } else
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
- {
+ } else {
ber_dupbv( &matched_dn, &matched->e_name );
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;
}
#ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, matched);
#endif
- bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache,
- matched, &lock);
+ bdb_cache_return_entry_r (bdb, matched, &lock);
matched = NULL;
if ( erefs ) {
#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 );
return rs->sr_err;
}
-#ifdef SLAP_ACL_HONOR_DISCLOSE
/* NOTE: __NEW__ "search" access is required
* on searchBase object */
if ( ! access_allowed_mask( op, e, slap_schema.si_ad_entry,
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
if ( e != &e_root ) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+ bdb_cache_return_entry_r(bdb, e, &lock);
}
send_ldap_result( op, rs );
- return 1;
+ return rs->sr_err;
}
-#endif /* SLAP_ACL_HONOR_DISCLOSE */
if ( !manageDSAit && e != &e_root && is_entry_referral( e ) ) {
/* entry is a referral, don't allow add */
#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 );
+ bdb_cache_return_entry_r( bdb, e, &lock );
e = NULL;
if ( erefs ) {
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
if ( e != &e_root ) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+ bdb_cache_return_entry_r(bdb, e, &lock);
}
send_ldap_result( op, rs );
return 1;
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
if ( e != &e_root ) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+ bdb_cache_return_entry_r(bdb, e, &lock);
}
e = NULL;
goto loop_begin;
}
-loop_start:
-
for ( id = bdb_idl_first( candidates, &cursor );
id != NOID ; id = bdb_idl_next( candidates, &cursor ) )
{
- int scopeok = 0;
- ID* idhole = NULL;
+ int scopeok;
loop_begin:
/* check for abandon */
if ( op->o_abandon ) {
- rs->sr_err = LDAP_SUCCESS;
+ rs->sr_err = SLAPD_ABANDON;
goto done;
}
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?
*
* 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? */
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, e, &lock );
+ e = NULL;
send_paged_response( op, rs, &lastid, tentries );
goto done;
}
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
- bdb_cache_return_entry_r(bdb->bi_dbenv,
- &bdb->bi_cache, e, &lock);
+ bdb_cache_return_entry_r(bdb, 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;
}
}
#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 );
+ bdb_cache_return_entry_r( bdb, e , &lock );
e = NULL;
rs->sr_entry = NULL;
}
-
- ldap_pvt_thread_yield();
}
nochange:
{
int rc = 0;
- assert( f );
+ assert( f != NULL );
if( cur > *max ) *max = cur;
int rc, depth = 1;
Filter f, rf, xf, nf;
ID *stack;
- AttributeAssertion aa_ref;
-#ifdef BDB_SUBENTRIES
+#ifdef LDAP_COMP_MATCH
+ AttributeAssertion aa_ref = { NULL, BER_BVNULL, NULL };
+#else
+ AttributeAssertion aa_ref = { NULL, BER_BVNULL };
+#endif
Filter sf;
- AttributeAssertion aa_subentry;
+#ifdef LDAP_COMP_MATCH
+ AttributeAssertion aa_subentry = { NULL, BER_BVNULL, NULL };
+#else
+ AttributeAssertion aa_subentry = { NULL, BER_BVNULL };
#endif
/*
/* 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;
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 ) {
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
rc = search_aliases( op, rs, e, locker, ids, scopes, stack );
} else {
- rc = bdb_dn2idl( op, e, ids, stack );
+ rc = bdb_dn2idl( op, locker, e, ids, stack );
}
if ( rc == LDAP_SUCCESS ) {
- rc = bdb_filter_candidates( op, &f, ids,
+ rc = bdb_filter_candidates( op, locker, &f, ids,
stack, stack+BDB_IDL_UM_SIZE );
}
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 );
(void) ber_free_buf( ber );
}
-static int
-bdb_pfid_cmp( const void *v_id1, const void *v_id2 )
-{
- const ID *p1 = v_id1, *p2 = v_id2;
- return *p1 - *p2;
-}
-
-static ID*
-bdb_id_dup( Operation *op, ID *id )
-{
- ID *new;
- new = ch_malloc( sizeof(ID) );
- *new = *id;
- return new;
-}