From 091246c6fd1f0b45281a0adeb213a214c18214a3 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 8 Mar 2004 18:12:45 +0000 Subject: [PATCH] move limits evaluation to frontend --- servers/slapd/back-bdb/search.c | 100 +++----------------- servers/slapd/back-ldap/search.c | 69 +++----------- servers/slapd/back-ldbm/search.c | 141 +++++++---------------------- servers/slapd/back-meta/search.c | 82 ++++------------- servers/slapd/back-passwd/search.c | 30 +++--- servers/slapd/back-sql/search.c | 124 ++++++------------------- servers/slapd/search.c | 67 ++++++++++++++ servers/slapd/slap.h | 3 + 8 files changed, 187 insertions(+), 429 deletions(-) diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index e9ceab27de..c4b1a9185e 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -395,8 +395,6 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, int entry_sync_state = -1; AttributeName null_attr; int no_sync_state_change = 0; - struct slap_limits_set *limit = NULL; - int isroot = 0; u_int32_t locker = 0; DB_LOCK lock; @@ -647,82 +645,8 @@ dn2entry_retry: return 1; } - /* if not root, get appropriate limits */ - if ( be_isroot( op->o_bd, &sop->o_ndn ) ) { - isroot = 1; - } else { - ( void ) get_limits( op, &sop->o_ndn, &limit ); - } - - /* The time/size limits come first because they require very little - * effort, so there's no chance the candidates are selected and then - * the request is not honored only because of time/size constraints - */ - - /* if no time limit requested, use soft limit (unless root!) */ - if ( isroot ) { - if ( sop->oq_search.rs_tlimit == 0 ) { - sop->oq_search.rs_tlimit = -1; /* allow root to set no limit */ - } - - if ( sop->oq_search.rs_slimit == 0 ) { - sop->oq_search.rs_slimit = -1; - } - - } else { - /* if no limit is required, use soft limit */ - if ( sop->oq_search.rs_tlimit <= 0 ) { - sop->oq_search.rs_tlimit = limit->lms_t_soft; - - /* if requested limit higher than hard limit, abort */ - } else if ( sop->oq_search.rs_tlimit > limit->lms_t_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 - && limit->lms_t_soft > -1 - && sop->oq_search.rs_tlimit > limit->lms_t_soft ) { - sop->oq_search.rs_tlimit = limit->lms_t_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_t_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( sop, rs ); - rs->sr_err = LDAP_SUCCESS; - goto done; - } - - /* negative hard limit means no limit */ - } - - /* if no limit is required, use soft limit */ - if ( sop->oq_search.rs_slimit <= 0 ) { - if ( get_pagedresults(sop) && limit->lms_s_pr != 0 ) { - sop->oq_search.rs_slimit = limit->lms_s_pr; - } else { - sop->oq_search.rs_slimit = limit->lms_s_soft; - } - - /* if requested limit higher than hard limit, abort */ - } else if ( sop->oq_search.rs_slimit > limit->lms_s_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 - && limit->lms_s_soft > -1 - && sop->oq_search.rs_slimit > limit->lms_s_soft ) { - sop->oq_search.rs_slimit = limit->lms_s_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_s_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( sop, rs ); - rs->sr_err = LDAP_SUCCESS; - goto done; - } - - /* negative hard limit means no limit */ - } - } - /* compute it anyway; root does not use it */ - stoptime = op->o_time + sop->oq_search.rs_tlimit; + stoptime = op->o_time + sop->ors_tlimit; /* need normalized dn below */ ber_dupbv( &realbase, &e->e_nname ); @@ -809,16 +733,18 @@ dn2entry_retry: } /* if not root and candidates exceed to-be-checked entries, abort */ - if ( !isroot && limit->lms_s_unchecked != -1 ) { - if ( BDB_IDL_N(candidates) > (unsigned) limit->lms_s_unchecked ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( sop, rs ); - rs->sr_err = LDAP_SUCCESS; - goto done; - } + if ( sop->ors_limit /* isroot == TRUE */ + && sop->ors_limit->lms_s_unchecked != -1 + && BDB_IDL_N(candidates) > (unsigned) sop->ors_limit->lms_s_unchecked ) + { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( sop, rs ); + rs->sr_err = LDAP_SUCCESS; + goto done; } - if ( isroot || !limit->lms_s_pr_hide ) { + if ( sop->ors_limit == NULL /* isroot == FALSE */ + || !sop->ors_limit->lms_s_pr_hide ) { tentries = BDB_IDL_N(candidates); } @@ -943,7 +869,7 @@ loop_begin: } /* check time limit */ - if ( sop->oq_search.rs_tlimit != -1 && slap_get_time() > stoptime ) { + if ( sop->ors_tlimit != -1 && slap_get_time() > stoptime ) { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; rs->sr_ref = rs->sr_v2ref; send_ldap_result( sop, rs ); @@ -1172,7 +1098,7 @@ id2entry_retry: if ( rs->sr_err == LDAP_COMPARE_TRUE ) { /* check size limit */ - if ( --sop->oq_search.rs_slimit == -1 && + if ( --sop->ors_slimit == -1 && sop->o_sync_slog_size == -1 ) { if (!IS_PSEARCH) { diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index a3aa7a2cc3..d3b45d6532 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -58,8 +58,6 @@ ldap_back_search( char **mapped_attrs = NULL; struct berval mbase; struct berval mfilter = { 0, NULL }; - struct slap_limits_set *limit = NULL; - int isroot = 0; int dontfreetext = 0; dncookie dc; #ifdef LDAP_BACK_PROXY_AUTHZ @@ -79,56 +77,11 @@ ldap_back_search( return( -1 ); } - /* if not root, get appropriate limits */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) { - isroot = 1; - } else { - ( void ) get_limits( op, &op->o_ndn, &limit ); - } - - /* if no time limit requested, rely on remote server limits */ - /* if requested limit higher than hard limit, abort */ - if ( !isroot && op->oq_search.rs_tlimit > limit->lms_t_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 - && limit->lms_t_soft > -1 - && op->oq_search.rs_tlimit > limit->lms_t_soft ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_t_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - rc = 0; - goto finish; - } - - /* negative hard limit means no limit */ - } - - /* if no size limit requested, rely on remote server limits */ - /* if requested limit higher than hard limit, abort */ - if ( !isroot && op->oq_search.rs_slimit > limit->lms_s_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 - && limit->lms_s_soft > -1 - && op->oq_search.rs_slimit > limit->lms_s_soft ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_s_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - rc = 0; - goto finish; - } - - /* negative hard limit means no limit */ - } - /* should we check return values? */ - if (op->oq_search.rs_deref != -1) - ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->oq_search.rs_deref); - if (op->oq_search.rs_tlimit != -1) { - tv.tv_sec = op->oq_search.rs_tlimit; + if (op->ors_deref != -1) + ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref); + if (op->ors_tlimit != -1) { + tv.tv_sec = op->ors_tlimit; tv.tv_usec = 0; } else { tv.tv_sec = 0; @@ -151,7 +104,7 @@ ldap_back_search( return -1; } - rc = ldap_back_filter_map_rewrite( &dc, op->oq_search.rs_filter, + rc = ldap_back_filter_map_rewrite( &dc, op->ors_filter, &mfilter, BACKLDAP_MAP ); switch ( rc ) { @@ -173,7 +126,7 @@ ldap_back_search( } rs->sr_err = ldap_back_map_attrs( &li->rwmap.rwm_at, - op->oq_search.rs_attrs, + op->ors_attrs, BACKLDAP_MAP, &mapped_attrs ); if ( rs->sr_err ) { rc = -1; @@ -189,15 +142,15 @@ ldap_back_search( #endif /* LDAP_BACK_PROXY_AUTHZ */ rs->sr_err = ldap_search_ext(lc->ld, mbase.bv_val, - op->oq_search.rs_scope, mfilter.bv_val, - mapped_attrs, op->oq_search.rs_attrsonly, + op->ors_scope, mfilter.bv_val, + mapped_attrs, op->ors_attrsonly, #ifdef LDAP_BACK_PROXY_AUTHZ ctrls, #else /* ! LDAP_BACK_PROXY_AUTHZ */ op->o_ctrls, #endif /* ! LDAP_BACK_PROXY_AUTHZ */ NULL, - tv.tv_sec ? &tv : NULL, op->oq_search.rs_slimit, + tv.tv_sec ? &tv : NULL, op->ors_slimit, &msgid ); if ( rs->sr_err != LDAP_SUCCESS ) { @@ -233,7 +186,7 @@ fail:; if ( ( rc = ldap_build_entry(op, e, &ent, &bdn, LDAP_BUILD_ENTRY_PRIVATE)) == LDAP_SUCCESS ) { rs->sr_entry = &ent; - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; abort = send_search_entry( op, rs ); while (ent.e_attrs) { Attribute *a; @@ -361,7 +314,7 @@ finish:; if ( mapped_attrs ) { ch_free( mapped_attrs ); } - if ( mfilter.bv_val != op->oq_search.rs_filterstr.bv_val ) { + if ( mfilter.bv_val != op->ors_filterstr.bv_val ) { ch_free( mfilter.bv_val ); } if ( mbase.bv_val != op->o_req_ndn.bv_val ) { diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 7ae88c475b..2ff93defff 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -49,9 +49,6 @@ ldbm_back_search( struct berval realbase = { 0, NULL }; int manageDSAit = get_manageDSAit( op ); - struct slap_limits_set *limit = NULL; - int isroot = 0; - #ifdef NEW_LOGGING LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_search: enter\n", 0, 0, 0 ); #else @@ -68,13 +65,13 @@ ldbm_back_search( /* need normalized dn below */ ber_dupbv( &realbase, &e->e_nname ); - candidates = search_candidates( op, e, op->oq_search.rs_filter, - op->oq_search.rs_scope, op->oq_search.rs_deref, + candidates = search_candidates( op, e, op->ors_filter, + op->ors_scope, op->ors_deref, manageDSAit || get_domainScope(op) ); goto searchit; - } else if ( op->oq_search.rs_deref & LDAP_DEREF_FINDING ) { + } else if ( op->ors_deref & LDAP_DEREF_FINDING ) { /* deref dn and get entry with reader lock */ e = deref_dn_r( op->o_bd, &op->o_req_ndn, &rs->sr_err, &matched, &rs->sr_text ); @@ -103,14 +100,14 @@ ldbm_back_search( if( erefs ) { rs->sr_ref = referral_rewrite( erefs, &matched_dn, - &op->o_req_dn, op->oq_search.rs_scope ); + &op->o_req_dn, op->ors_scope ); ber_bvarray_free( erefs ); } } else { rs->sr_ref = referral_rewrite( default_referral, - NULL, &op->o_req_dn, op->oq_search.rs_scope ); + NULL, &op->o_req_dn, op->ors_scope ); } ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock); @@ -149,7 +146,7 @@ ldbm_back_search( if( erefs ) { rs->sr_ref = referral_rewrite( erefs, &matched_dn, - &op->o_req_dn, op->oq_search.rs_scope ); + &op->o_req_dn, op->ors_scope ); ber_bvarray_free( erefs ); } @@ -173,15 +170,15 @@ ldbm_back_search( if ( is_entry_alias( e ) ) { /* don't deref */ - op->oq_search.rs_deref = LDAP_DEREF_NEVER; + op->ors_deref = LDAP_DEREF_NEVER; } - if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE ) { + if ( op->ors_scope == LDAP_SCOPE_BASE ) { candidates = base_candidate( op->o_bd, e ); } else { - candidates = search_candidates( op, e, op->oq_search.rs_filter, - op->oq_search.rs_scope, op->oq_search.rs_deref, manageDSAit ); + candidates = search_candidates( op, e, op->ors_filter, + op->ors_scope, op->ors_deref, manageDSAit ); } /* need normalized dn below */ @@ -207,91 +204,19 @@ searchit: goto done; } - /* if not root, get appropriate limits */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) - { - /* - * FIXME: I'd consider this dangerous if someone - * uses isroot for anything but handling limits - */ - isroot = 1; - } else { - ( void ) get_limits( op, &op->o_ndn, &limit ); - } - /* if candidates exceed to-be-checked entries, abort */ - if ( !isroot && limit->lms_s_unchecked != -1 ) { - if ( ID_BLOCK_NIDS( candidates ) > (unsigned) limit->lms_s_unchecked ) { - send_ldap_error( op, rs, LDAP_ADMINLIMIT_EXCEEDED, - NULL ); - rc = LDAP_SUCCESS; - goto done; - } + if ( op->ors_limit /* isroot == TRUE */ + && op->ors_limit->lms_s_unchecked != -1 + && ID_BLOCK_NIDS( candidates ) > (unsigned) op->ors_limit->lms_s_unchecked ) + { + send_ldap_error( op, rs, LDAP_ADMINLIMIT_EXCEEDED, NULL ); + rc = LDAP_SUCCESS; + goto done; } - /* if root an no specific limit is required, allow unlimited search */ - if ( isroot ) { - if ( op->oq_search.rs_tlimit == 0 ) { - op->oq_search.rs_tlimit = -1; - } - - if ( op->oq_search.rs_slimit == 0 ) { - op->oq_search.rs_slimit = -1; - } - - } else { - /* if no limit is required, use soft limit */ - if ( op->oq_search.rs_tlimit <= 0 ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* if requested limit higher than hard limit, abort */ - } else if ( op->oq_search.rs_tlimit > limit->lms_t_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 - && limit->lms_t_soft > -1 - && op->oq_search.rs_tlimit > limit->lms_t_soft ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_t_hard > 0 ) { - send_ldap_error( op, rs, - LDAP_ADMINLIMIT_EXCEEDED, - NULL ); - rc = LDAP_SUCCESS; - goto done; - } - - /* negative hard limit means no limit */ - } - - /* if no limit is required, use soft limit */ - if ( op->oq_search.rs_slimit <= 0 ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* if requested limit higher than hard limit, abort */ - } else if ( op->oq_search.rs_slimit > limit->lms_s_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 - && limit->lms_s_soft > -1 - && op->oq_search.rs_slimit > limit->lms_s_soft ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_s_hard > 0 ) { - send_ldap_error( op, rs, - LDAP_ADMINLIMIT_EXCEEDED, - NULL ); - rc = LDAP_SUCCESS; - goto done; - } - - /* negative hard limit means no limit */ - } - } - /* compute it anyway; root does not use it */ - stoptime = op->o_time + op->oq_search.rs_tlimit; - rs->sr_attrs = op->oq_search.rs_attrs; + stoptime = op->o_time + op->ors_tlimit; + rs->sr_attrs = op->ors_attrs; for ( id = idl_firstid( candidates, &cursor ); id != NOID; id = idl_nextid( candidates, &cursor ) ) @@ -306,7 +231,7 @@ searchit: } /* check time limit */ - if ( op->oq_search.rs_tlimit != -1 && slap_get_time() > stoptime ) { + if ( op->ors_tlimit != -1 && slap_get_time() > stoptime ) { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; send_ldap_result( op, rs ); rc = LDAP_SUCCESS; @@ -333,7 +258,7 @@ searchit: #ifdef LDBM_SUBENTRIES if ( is_entry_subentry( e ) ) { - if( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { + if( op->ors_scope != LDAP_SCOPE_BASE ) { if(!get_subentries_visibility( op )) { /* only subentries are visible */ goto loop_continue; @@ -350,7 +275,7 @@ searchit: } #endif - if ( op->oq_search.rs_deref & LDAP_DEREF_SEARCHING && + if ( op->ors_deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) { Entry *matched; @@ -370,7 +295,7 @@ searchit: } /* need to skip alias which deref into scope */ - if( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { + if( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { struct berval pdn; dnParent( &e->e_nname, &pdn ); if ( ber_bvcmp( &pdn, &realbase ) ) { @@ -403,13 +328,13 @@ searchit: * the filter explicitly here since it's only a candidate * anyway. */ - if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE && + if ( !manageDSAit && op->ors_scope != LDAP_SCOPE_BASE && is_entry_referral( e ) ) { struct berval dn; /* check scope */ - if ( !scopeok && op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { + if ( !scopeok && op->ors_scope == LDAP_SCOPE_ONELEVEL ) { if ( !be_issuffix( op->o_bd, &e->e_nname ) ) { dnParent( &e->e_nname, &dn ); scopeok = dn_match( &dn, &realbase ); @@ -418,12 +343,12 @@ searchit: } } else if ( !scopeok - && op->oq_search.rs_scope == LDAP_SCOPE_SUBTREE ) + && op->ors_scope == LDAP_SCOPE_SUBTREE ) { scopeok = dnIsSuffix( &e->e_nname, &realbase ); } else if ( !scopeok - && op->oq_search.rs_scope == LDAP_SCOPE_SUBORDINATE ) + && op->ors_scope == LDAP_SCOPE_SUBORDINATE ) { scopeok = !dn_match( &e->e_nname, &realbase ) && dnIsSuffix( &e->e_nname, &realbase ); @@ -436,7 +361,7 @@ searchit: BerVarray erefs = get_entry_referrals( op, e ); rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL, - op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL + op->ors_scope == LDAP_SCOPE_ONELEVEL ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE ); @@ -465,13 +390,13 @@ searchit: } /* if it matches the filter and scope, send it */ - result = test_filter( op, e, op->oq_search.rs_filter ); + result = test_filter( op, e, op->ors_filter ); if ( result == LDAP_COMPARE_TRUE ) { struct berval dn; /* check scope */ - if ( !scopeok && op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { + if ( !scopeok && op->ors_scope == LDAP_SCOPE_ONELEVEL ) { if ( !be_issuffix( op->o_bd, &e->e_nname ) ) { dnParent( &e->e_nname, &dn ); scopeok = dn_match( &dn, &realbase ); @@ -480,12 +405,12 @@ searchit: } } else if ( !scopeok && - op->oq_search.rs_scope == LDAP_SCOPE_SUBTREE ) + op->ors_scope == LDAP_SCOPE_SUBTREE ) { scopeok = dnIsSuffix( &e->e_nname, &realbase ); } else if ( !scopeok && - op->oq_search.rs_scope == LDAP_SCOPE_SUBORDINATE ) + op->ors_scope == LDAP_SCOPE_SUBORDINATE ) { scopeok = !dn_match( &e->e_nname, &realbase ) && dnIsSuffix( &e->e_nname, &realbase ); @@ -496,7 +421,7 @@ searchit: if ( scopeok ) { /* check size limit */ - if ( --op->oq_search.rs_slimit == -1 ) { + if ( --op->ors_slimit == -1 ) { cache_return_entry_r( &li->li_cache, e ); rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; send_ldap_result( op, rs ); diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index bc3e3e6ec3..d6c2798dc5 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -66,8 +66,6 @@ meta_back_search( Operation *op, SlapReply *rs ) int i, last = 0, candidates = 0, initial_candidates = 0, candidate_match = 0; - struct slap_limits_set *limit = NULL; - int isroot = 0; dncookie dc; int is_scope = 0, @@ -102,54 +100,6 @@ meta_back_search( Operation *op, SlapReply *rs ) return -1; } - /* if not root, get appropriate limits */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) { - isroot = 1; - } else { - ( void ) get_limits( op, &op->o_ndn, &limit ); - } - - /* if no time limit requested, rely on remote server limits */ - /* if requested limit higher than hard limit, abort */ - if ( !isroot && op->oq_search.rs_tlimit > limit->lms_t_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 - && limit->lms_t_soft > -1 - && op->oq_search.rs_tlimit > limit->lms_t_soft ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_t_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( op, rs ); - rc = 0; - goto finish; - } - - /* negative hard limit means no limit */ - } - - /* if no size limit requested, rely on remote server limits */ - /* if requested limit higher than hard limit, abort */ - if ( !isroot && op->oq_search.rs_slimit > limit->lms_s_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 - && limit->lms_s_soft > -1 - && op->oq_search.rs_slimit > limit->lms_s_soft ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_s_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( op, rs ); - rc = 0; - goto finish; - } - - /* negative hard limit means no limit */ - } - - dc.conn = op->o_conn; dc.rs = rs; @@ -158,7 +108,7 @@ meta_back_search( Operation *op, SlapReply *rs ) */ for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) { struct berval realbase = op->o_req_dn; - int realscope = op->oq_search.rs_scope; + int realscope = op->ors_scope; ber_len_t suffixlen = 0; struct berval mbase = { 0, NULL }; struct berval mfilter = { 0, NULL }; @@ -170,17 +120,17 @@ meta_back_search( Operation *op, SlapReply *rs ) } /* should we check return values? */ - if ( op->oq_search.rs_deref != -1 ) { + if ( op->ors_deref != -1 ) { ldap_set_option( lsc->ld, LDAP_OPT_DEREF, - ( void * )&op->oq_search.rs_deref); + ( void * )&op->ors_deref); } - if ( op->oq_search.rs_tlimit != -1 ) { + if ( op->ors_tlimit != -1 ) { ldap_set_option( lsc->ld, LDAP_OPT_TIMELIMIT, - ( void * )&op->oq_search.rs_tlimit); + ( void * )&op->ors_tlimit); } - if ( op->oq_search.rs_slimit != -1 ) { + if ( op->ors_slimit != -1 ) { ldap_set_option( lsc->ld, LDAP_OPT_SIZELIMIT, - ( void * )&op->oq_search.rs_slimit); + ( void * )&op->ors_slimit); } dc.rwmap = &li->targets[ i ]->rwmap; @@ -190,7 +140,7 @@ meta_back_search( Operation *op, SlapReply *rs ) */ suffixlen = li->targets[ i ]->suffix.bv_len; if ( suffixlen > op->o_req_ndn.bv_len ) { - switch ( op->oq_search.rs_scope ) { + switch ( op->ors_scope ) { case LDAP_SCOPE_SUBTREE: /* * make the target suffix the new base @@ -272,7 +222,7 @@ meta_back_search( Operation *op, SlapReply *rs ) * Maps filter */ rc = ldap_back_filter_map_rewrite( &dc, - op->oq_search.rs_filter, + op->ors_filter, &mfilter, BACKLDAP_MAP ); switch ( rc ) { case LDAP_SUCCESS: @@ -294,7 +244,7 @@ meta_back_search( Operation *op, SlapReply *rs ) * Maps required attributes */ rc = ldap_back_map_attrs( &li->targets[ i ]->rwmap.rwm_at, - op->oq_search.rs_attrs, BACKLDAP_MAP, + op->ors_attrs, BACKLDAP_MAP, &mapped_attrs ); if ( rc != LDAP_SUCCESS ) { /* @@ -309,12 +259,12 @@ meta_back_search( Operation *op, SlapReply *rs ) */ msgid[ i ] = ldap_search( lsc->ld, mbase.bv_val, realscope, mfilter.bv_val, mapped_attrs, - op->oq_search.rs_attrsonly ); + op->ors_attrsonly ); if ( mapped_attrs ) { free( mapped_attrs ); mapped_attrs = NULL; } - if ( mfilter.bv_val != op->oq_search.rs_filterstr.bv_val ) { + if ( mfilter.bv_val != op->ors_filterstr.bv_val ) { free( mfilter.bv_val ); mfilter.bv_val = NULL; } @@ -363,8 +313,8 @@ new_candidate:; break; } - if ( op->oq_search.rs_slimit > 0 - && rs->sr_nentries == op->oq_search.rs_slimit ) { + if ( op->ors_slimit > 0 + && rs->sr_nentries == op->ors_slimit ) { rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; rs->sr_v2ref = v2refs; send_ldap_result( op, rs ); @@ -418,7 +368,7 @@ new_candidate:; * this should correspond to the sole * entry that has the base DN */ - if ( op->oq_search.rs_scope == LDAP_SCOPE_BASE + if ( op->ors_scope == LDAP_SCOPE_BASE && rs->sr_nentries > 0 ) { candidates = 0; sres = LDAP_SUCCESS; @@ -768,7 +718,7 @@ meta_send_entry( attrp = &attr->a_next; } rs->sr_entry = &ent; - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_attrs = NULL; diff --git a/servers/slapd/back-passwd/search.c b/servers/slapd/back-passwd/search.c index 3e02efd510..1932583d17 100644 --- a/servers/slapd/back-passwd/search.c +++ b/servers/slapd/back-passwd/search.c @@ -69,11 +69,11 @@ passwd_back_search( AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; - op->oq_search.rs_tlimit = (op->oq_search.rs_tlimit > op->o_bd->be_timelimit || op->oq_search.rs_tlimit < 1) ? op->o_bd->be_timelimit - : op->oq_search.rs_tlimit; - stoptime = op->o_time + op->oq_search.rs_tlimit; - op->oq_search.rs_slimit = (op->oq_search.rs_slimit > op->o_bd->be_sizelimit || op->oq_search.rs_slimit < 1) ? op->o_bd->be_sizelimit - : op->oq_search.rs_slimit; + op->ors_tlimit = (op->ors_tlimit > op->o_bd->be_timelimit || op->ors_tlimit < 1) ? op->o_bd->be_timelimit + : op->ors_tlimit; + stoptime = op->o_time + op->ors_tlimit; + op->ors_slimit = (op->ors_slimit > op->o_bd->be_sizelimit || op->ors_slimit < 1) ? op->o_bd->be_sizelimit + : op->ors_slimit; /* Handle a query for the base of this backend */ if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) { @@ -83,7 +83,7 @@ passwd_back_search( rs->sr_matched = op->o_req_dn.bv_val; - if( op->oq_search.rs_scope != LDAP_SCOPE_ONELEVEL ) { + if( op->ors_scope != LDAP_SCOPE_ONELEVEL ) { AttributeDescription *desc = NULL; /* Create an entry corresponding to the base DN */ @@ -128,14 +128,14 @@ passwd_back_search( vals[0].bv_len = sizeof("organizationalUnit")-1; attr_mergeit( e, ad_objectClass, vals ); - if ( test_filter( op, e, op->oq_search.rs_filter ) == LDAP_COMPARE_TRUE ) { + if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { rs->sr_entry = e; - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; send_search_entry( op, rs ); } } - if ( op->oq_search.rs_scope != LDAP_SCOPE_BASE ) { + if ( op->ors_scope != LDAP_SCOPE_BASE ) { /* check all our "children" */ ldap_pvt_thread_mutex_lock( &passwd_mutex ); @@ -163,9 +163,9 @@ passwd_back_search( goto done; } - if ( test_filter( op, e, op->oq_search.rs_filter ) == LDAP_COMPARE_TRUE ) { + if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { /* check size limit */ - if ( --op->oq_search.rs_slimit == -1 ) { + if ( --op->ors_slimit == -1 ) { send_ldap_error( op, rs, LDAP_SIZELIMIT_EXCEEDED, NULL ); endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); @@ -173,7 +173,7 @@ passwd_back_search( } rs->sr_entry = e; - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; send_search_entry( op, rs ); } @@ -203,7 +203,7 @@ passwd_back_search( goto done; } - if( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { + if( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { goto done; } @@ -230,9 +230,9 @@ passwd_back_search( goto done; } - if ( test_filter( op, e, op->oq_search.rs_filter ) == LDAP_COMPARE_TRUE ) { + if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { rs->sr_entry = e; - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; send_search_entry( op, rs ); } diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 65257d0e0f..efbdcd9877 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -1146,21 +1146,19 @@ backsql_search( Operation *op, SlapReply *rs ) time_t stoptime = 0; backsql_srch_info srch_info; backsql_entryID *eid = NULL; - struct slap_limits_set *limit = NULL; - int isroot = 0; manageDSAit = get_manageDSAit( op ); Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): " "base='%s', filter='%s', scope=%d,", op->o_req_ndn.bv_val, - op->oq_search.rs_filterstr.bv_val, - op->oq_search.rs_scope ); + op->ors_filterstr.bv_val, + op->ors_scope ); Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, " "attributes to load: %s\n", - op->oq_search.rs_deref, - op->oq_search.rs_attrsonly, - op->oq_search.rs_attrs == NULL ? "all" : "custom list" ); + op->ors_deref, + op->ors_attrsonly, + op->ors_attrs == NULL ? "all" : "custom list" ); if ( op->o_req_ndn.bv_len > BACKSQL_MAX_DN_LEN ) { Debug( LDAP_DEBUG_TRACE, "backsql_search(): " @@ -1187,97 +1185,33 @@ backsql_search( Operation *op, SlapReply *rs ) return 1; } - /* if not root, get appropriate limits */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) { - isroot = 1; - } else { - ( void ) get_limits( op, &op->o_ndn, &limit ); - } - - /* The time/size limits come first because they require very little - * effort, so there's no chance the candidates are selected and then - * the request is not honored only because of time/size constraints */ - - /* if no time limit requested, use soft limit (unless root!) */ - if ( isroot ) { - if ( op->oq_search.rs_tlimit == 0 ) { - op->oq_search.rs_tlimit = -1; /* allow root to set no limit */ - } - - if ( op->oq_search.rs_slimit == 0 ) { - op->oq_search.rs_slimit = -1; - } - - } else { - /* if no limit is required, use soft limit */ - if ( op->oq_search.rs_tlimit <= 0 ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* if requested limit higher than hard limit, abort */ - } else if ( op->oq_search.rs_tlimit > limit->lms_t_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 - && limit->lms_t_soft > -1 - && op->oq_search.rs_tlimit > limit->lms_t_soft ) { - op->oq_search.rs_tlimit = limit->lms_t_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_t_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( op, rs ); - return 0; - } - - /* negative hard limit means no limit */ - } - - /* if no limit is required, use soft limit */ - if ( op->oq_search.rs_slimit <= 0 ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* if requested limit higher than hard limit, abort */ - } else if ( op->oq_search.rs_slimit > limit->lms_s_hard ) { - /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 - && limit->lms_s_soft > -1 - && op->oq_search.rs_slimit > limit->lms_s_soft ) { - op->oq_search.rs_slimit = limit->lms_s_soft; - - /* positive hard limit means abort */ - } else if ( limit->lms_s_hard > 0 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( op, rs ); - return 0; - } - - /* negative hard limit means no limit */ - } - } - /* compute it anyway; root does not use it */ - stoptime = op->o_time + op->oq_search.rs_tlimit; + stoptime = op->o_time + op->ors_tlimit; backsql_init_search( &srch_info, &op->o_req_dn, - op->oq_search.rs_scope, - op->oq_search.rs_slimit, op->oq_search.rs_tlimit, - stoptime, op->oq_search.rs_filter, - dbh, op, op->oq_search.rs_attrs ); + op->ors_scope, + op->ors_slimit, op->ors_tlimit, + stoptime, op->ors_filter, + dbh, op, op->ors_attrs ); /* * for each objectclass we try to construct query which gets IDs * of entries matching LDAP query filter and scope (or at least * candidates), and get the IDs */ - srch_info.bsi_n_candidates = ( isroot ? -2 : limit->lms_s_unchecked == -1 - ? -2 : limit->lms_s_unchecked ); + srch_info.bsi_n_candidates = + ( op->ors_limit == NULL /* isroot == FALSE */ ? -2 : + ( op->ors_limit->lms_s_unchecked == -1 ? -2 : + ( op->ors_limit->lms_s_unchecked ) ) ); avl_apply( bi->oc_by_oc, backsql_oc_get_candidates, &srch_info, BACKSQL_STOP, AVL_INORDER ); - if ( !isroot && limit->lms_s_unchecked != -1 ) { - if ( srch_info.bsi_n_candidates == -1 ) { - rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; - send_ldap_result( op, rs ); - goto done; - } + if ( op->ors_limit != NULL /* isroot == TRUE */ + && op->ors_limit->lms_s_unchecked != -1 + && srch_info.bsi_n_candidates == -1 ) + { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); + goto done; } /* @@ -1296,7 +1230,7 @@ backsql_search( Operation *op, SlapReply *rs ) } /* check time limit */ - if ( op->oq_search.rs_tlimit != -1 && slap_get_time() > stoptime ) { + if ( op->ors_tlimit != -1 && slap_get_time() > stoptime ) { rs->sr_err = LDAP_TIMELIMIT_EXCEEDED; rs->sr_ctrls = NULL; rs->sr_ref = rs->sr_v2ref; @@ -1320,7 +1254,7 @@ backsql_search( Operation *op, SlapReply *rs ) } if ( !manageDSAit && - op->oq_search.rs_scope != LDAP_SCOPE_BASE && + op->ors_scope != LDAP_SCOPE_BASE && is_entry_referral( entry ) ) { BerVarray refs; struct berval matched_dn; @@ -1330,7 +1264,7 @@ backsql_search( Operation *op, SlapReply *rs ) if ( refs ) { rs->sr_ref = referral_rewrite( refs, &matched_dn, &op->o_req_dn, - op->oq_search.rs_scope ); + op->ors_scope ); ber_bvarray_free( refs ); } @@ -1388,10 +1322,10 @@ backsql_search( Operation *op, SlapReply *rs ) } } - if ( test_filter( op, entry, op->oq_search.rs_filter ) + if ( test_filter( op, entry, op->ors_filter ) == LDAP_COMPARE_TRUE ) { if ( hasSubordinate && !( srch_info.bsi_flags & BSQL_SF_ALL_OPER ) - && !ad_inlist( slap_schema.si_ad_hasSubordinates, op->oq_search.rs_attrs ) ) { + && !ad_inlist( slap_schema.si_ad_hasSubordinates, op->ors_attrs ) ) { a->a_next = NULL; attr_free( hasSubordinate ); hasSubordinate = NULL; @@ -1403,7 +1337,7 @@ backsql_search( Operation *op, SlapReply *rs ) } else #endif { - rs->sr_attrs = op->oq_search.rs_attrs; + rs->sr_attrs = op->ors_attrs; rs->sr_entry = entry; sres = send_search_entry( op, rs ); rs->sr_entry = NULL; @@ -1429,8 +1363,8 @@ backsql_search( Operation *op, SlapReply *rs ) } entry_free( entry ); - if ( op->oq_search.rs_slimit != -1 - && rs->sr_nentries >= op->oq_search.rs_slimit ) { + if ( op->ors_slimit != -1 + && rs->sr_nentries >= op->ors_slimit ) { rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; send_ldap_result( op, rs ); goto end_of_search; diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 981223cf51..d1aa9eca6a 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -397,6 +397,73 @@ do_search( } #endif /* LDAP_SLAPI */ + /* allow root to set no limit */ + if ( be_isroot( op->o_bd, &op->o_ndn ) ) { + op->ors_limit = NULL; + + if ( op->ors_tlimit == 0 ) { + op->ors_tlimit = -1; + } + + if ( op->ors_slimit == 0 ) { + op->ors_slimit = -1; + } + + /* if not root, get appropriate limits */ + } else { + ( void ) get_limits( op, &op->o_ndn, &op->ors_limit ); + + /* if no limit is required, use soft limit */ + if ( op->ors_tlimit <= 0 ) { + op->ors_tlimit = op->ors_limit->lms_t_soft; + + /* if requested limit higher than hard limit, abort */ + } else if ( op->ors_tlimit > op->ors_limit->lms_t_hard ) { + /* no hard limit means use soft instead */ + if ( op->ors_limit->lms_t_hard == 0 + && op->ors_limit->lms_t_soft > -1 + && op->ors_tlimit > op->ors_limit->lms_t_soft ) { + op->ors_tlimit = op->ors_limit->lms_t_soft; + + /* positive hard limit means abort */ + } else if ( op->ors_limit->lms_t_hard > 0 ) { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); + rs->sr_err = LDAP_SUCCESS; + goto return_results; + } + + /* negative hard limit means no limit */ + } + + /* if no limit is required, use soft limit */ + if ( op->ors_slimit <= 0 ) { + if ( get_pagedresults( op ) && op->ors_limit->lms_s_pr != 0 ) { + op->ors_slimit = op->ors_limit->lms_s_pr; + } else { + op->ors_slimit = op->ors_limit->lms_s_soft; + } + + /* if requested limit higher than hard limit, abort */ + } else if ( op->ors_slimit > op->ors_limit->lms_s_hard ) { + /* no hard limit means use soft instead */ + if ( op->ors_limit->lms_s_hard == 0 + && op->ors_limit->lms_s_soft > -1 + && op->ors_slimit > op->ors_limit->lms_s_soft ) { + op->ors_slimit = op->ors_limit->lms_s_soft; + + /* positive hard limit means abort */ + } else if ( op->ors_limit->lms_s_hard > 0 ) { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); + rs->sr_err = LDAP_SUCCESS; + goto return_results; + } + + /* negative hard limit means no limit */ + } + } + /* actually do the search and send the result(s) */ if ( op->o_bd->be_search ) { (op->o_bd->be_search)( op, rs ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index d4efbc2d31..2132253e5a 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1570,6 +1570,8 @@ typedef struct req_search_s { int rs_deref; int rs_slimit; int rs_tlimit; + /* NULL means be_isroot evaluated to TRUE */ + struct slap_limits_set *rs_limit; int rs_attrsonly; AttributeName *rs_attrs; Filter *rs_filter; @@ -1965,6 +1967,7 @@ typedef struct slap_op { #define ors_deref oq_search.rs_deref #define ors_slimit oq_search.rs_slimit #define ors_tlimit oq_search.rs_tlimit +#define ors_limit oq_search.rs_limit #define ors_attrsonly oq_search.rs_attrsonly #define ors_attrs oq_search.rs_attrs #define ors_filter oq_search.rs_filter -- 2.39.5