X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-bdb%2Fsearch.c;h=20e44d0ebddcf4317ee203a8e3d55066e1cf8518;hb=60c4893b9379627eb3da95558e65c162f6805d3a;hp=a4687be4018f90cacbca8e3f4b0d8329a683aeac;hpb=fdeffe84e1b87a7c98bec356e658ffab379dcde5;p=openldap diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index a4687be401..20e44d0ebd 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -11,39 +11,37 @@ #include #include "back-bdb.h" +#include "idl.h" #include "external.h" static int base_candidate( - BackendDB *be, + BackendDB *be, Entry *e, ID *ids ); static int search_candidates( BackendDB *be, Entry *e, Filter *filter, - int scope, + int scope, int deref, int manageDSAit, ID *ids ); -static ID idl_first( ID *ids, ID *cursor ); -static ID idl_next( ID *ids, ID *cursor ); - int bdb_search( - BackendDB *be, - Connection *conn, - Operation *op, - const char *base, - const char *nbase, - int scope, - int deref, - int slimit, - int tlimit, - Filter *filter, - const char *filterstr, - char **attrs, - int attrsonly ) + BackendDB *be, + Connection *conn, + Operation *op, + const char *base, + const char *nbase, + int scope, + int deref, + int slimit, + int tlimit, + Filter *filter, + const char *filterstr, + char **attrs, + int attrsonly ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; int abandon; @@ -72,8 +70,7 @@ bdb_search( } else #endif { - /* obtain entry */ - rc = dn2entry_r( be, NULL, nbase, &e, &matched ); + rc = bdb_dn2entry( be, NULL, nbase, &e, &matched, 0 ); } switch(rc) { @@ -82,7 +79,7 @@ bdb_search( break; default: send_ldap_result( conn, op, rc=LDAP_OTHER, - NULL, "internal error", NULL, NULL ); + NULL, "internal error", NULL, NULL ); return rc; } @@ -108,6 +105,7 @@ bdb_search( ber_bvecfree( refs ); free( matched_dn ); bdb_entry_return( be, matched ); + matched = NULL; } return rc; @@ -120,12 +118,13 @@ bdb_search( conn, op, e ); bdb_entry_return( be, e ); + e = NULL; Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n", 0, 0, 0 ); send_ldap_result( conn, op, LDAP_REFERRAL, - matched_dn, NULL, refs, NULL ); + matched_dn, NULL, refs, NULL ); ber_bvecfree( refs ); free( matched_dn ); @@ -137,7 +136,7 @@ bdb_search( tlimit = -1; /* allow root to set no limit */ } else { tlimit = (tlimit > be->be_timelimit || tlimit < 1) ? - be->be_timelimit : tlimit; + be->be_timelimit : tlimit; stoptime = op->o_time + tlimit; } @@ -145,7 +144,7 @@ bdb_search( slimit = -1; /* allow root to set no limit */ } else { slimit = (slimit > be->be_sizelimit || slimit < 1) ? - be->be_sizelimit : slimit; + be->be_sizelimit : slimit; } if ( scope == LDAP_SCOPE_BASE ) { @@ -153,7 +152,7 @@ bdb_search( } else { rc = search_candidates( be, e, filter, - scope, deref, manageDSAit, candidates ); + scope, deref, manageDSAit, candidates ); } /* need normalized dn below */ @@ -163,6 +162,7 @@ bdb_search( cursor = e->e_id; bdb_entry_return( be, e ); + e = NULL; if ( candidates[0] == 0 ) { Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n", @@ -176,9 +176,9 @@ bdb_search( goto done; } - for ( id = idl_first( candidates, &cursor ); + for ( id = bdb_idl_first( candidates, &cursor ); id != NOID; - id = idl_next( candidates, &cursor ) ) + id = bdb_idl_next( candidates, &cursor ) ) { int scopeok = 0; @@ -203,9 +203,12 @@ bdb_search( rc = bdb_id2entry( be, NULL, id, &e ); if ( e == NULL ) { - Debug( LDAP_DEBUG_TRACE, - "bdb_search: candidate %ld not found\n", - id, 0, 0 ); + if( !BDB_IDL_IS_RANGE(candidates) ) { + /* only complain for non-range IDLs */ + Debug( LDAP_DEBUG_TRACE, + "bdb_search: candidate %ld not found\n", + id, 0, 0 ); + } goto loop_continue; } @@ -301,6 +304,7 @@ bdb_search( /* check size limit */ if ( --slimit == -1 ) { bdb_entry_return( be, e ); + e = NULL; send_search_result( conn, op, rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, v2refs, NULL, nentries ); @@ -319,6 +323,7 @@ bdb_search( break; case -1: /* connection closed */ bdb_entry_return( be, e ); + e = NULL; rc = LDAP_OTHER; goto done; } @@ -357,7 +362,7 @@ done: static int base_candidate( - BackendDB *be, + BackendDB *be, Entry *e, ID *ids ) { @@ -373,56 +378,77 @@ static int search_candidates( BackendDB *be, Entry *e, Filter *filter, - int scope, + int scope, int deref, int manageDSAit, ID *ids ) { - Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: \"%s\" (0x%08lx)\n", - e->e_dn, (long) e->e_id, 0); - - ids[0] = NOID; - return 0; -} - -static ID idl_first( ID *ids, ID *cursor ) -{ - ID pos; + int rc; + Filter f, fand, rf, xf; + AttributeAssertion aa_ref; + struct bdb_info *bdb = (struct bdb_info *) be->be_private; +#ifdef BDB_ALIASES + Filter af; + AttributeAssertion aa_alias; +#endif - if ( ids[0] == 0 ) { - *cursor = NOID; - return NOID; + Debug(LDAP_DEBUG_TRACE, + "search_candidates: base=\"%s\" (0x%08lx) scope=%d\n", + e->e_dn, (long) e->e_id, scope ); + + xf.f_or = filter; + xf.f_choice = LDAP_FILTER_OR; + xf.f_next = NULL; + + if( !manageDSAit ) { + /* match referrals */ + static struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" }; + rf.f_choice = LDAP_FILTER_EQUALITY; + rf.f_ava = &aa_ref; + rf.f_av_desc = slap_schema.si_ad_objectClass; + rf.f_av_value = &bv_ref; + rf.f_next = xf.f_or; + xf.f_or = &rf; } - if ( BDB_IS_ALLIDS( ids ) ) { - /* XXYYZ: quick hack for testing */ - ids[1] = 100; - return *cursor; +#ifdef BDB_ALIASES + if( deref & LDAP_DEREF_SEARCHING ) { + /* match aliases */ + static struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" }; + af.f_choice = LDAP_FILTER_EQUALITY; + af.f_ava = &aa_alias; + af.f_av_desc = slap_schema.si_ad_objectClass; + af.f_av_value = &bv_alias; + af.f_next = xf.f_or; + xf.f_or = ⁡ } +#endif - pos = bdb_idl_search( ids, *cursor ); + f.f_next = NULL; + f.f_choice = LDAP_FILTER_AND; + f.f_and = &fand; + fand.f_choice = scope == LDAP_SCOPE_SUBTREE + ? SLAPD_FILTER_DN_SUBTREE + : SLAPD_FILTER_DN_ONE; + fand.f_dn = e->e_ndn; + fand.f_next = xf.f_or == filter ? filter : &xf ; - if( pos > ids[0] ) { - return NOID; - } - *cursor = pos; - return ids[pos]; -} - -static ID idl_next( ID *ids, ID *cursor ) -{ - if ( BDB_IS_ALLIDS( ids ) ) { - if( ++(*cursor) <= ids[1] ) { - return *cursor; - } - return NOID; +#ifdef BDB_FILTER_INDICES + { + ID range[3]; + BDB_IDL_ID( bdb, range, e->e_id ); + rc = bdb_filter_candidates( be, range, &f, ids ); } +#else + BDB_IDL_ID( bdb, ids, e->e_id ); + rc = 0; +#endif - if ( *cursor < ids[0] ) { - return ids[(*cursor)++]; - } + Debug(LDAP_DEBUG_TRACE, + "search_candidates: id=%ld first=%ld last=%ld\n", + ids[0], ids[1], + BDB_IDL_IS_RANGE( ids ) ? ids[2] : ids[ids[0]] ); - return NOID; + return rc; } -