diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index d61446a3b4..086b1ddc92 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -374,7 +374,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, ID candidates[BDB_IDL_UM_SIZE]; ID scopes[BDB_IDL_DB_SIZE]; Entry *e = NULL, base, e_root = {0}; - Entry *matched = NULL; + Entry *matched = NULL; EntryInfo *ei, ei_root = {0}; struct berval realbase = BER_BVNULL; int manageDSAit; @@ -382,11 +382,10 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, ID lastid = NOID; AttributeName *attrs; - Filter contextcsnand, contextcsnle, cookief, csnfnot, - csnfeq, csnfand, csnfge; + Filter contextcsnand, contextcsnle, cookief, csnfnot, + csnfeq, csnfand, csnfge; AttributeAssertion aa_ge, aa_eq, aa_le; - int entry_count = 0; - struct berval *search_context_csn = NULL; + struct berval *search_context_csn = NULL; DB_LOCK ctxcsn_lock; LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; int num_ctrls = 0; @@ -755,6 +754,7 @@ dn2entry_retry: if ( get_pagedresults(sop) ) { if ( sop->o_pagedresults_state.ps_cookie == 0 ) { id = 0; + } else { if ( sop->o_pagedresults_size == 0 ) { rs->sr_err = LDAP_SUCCESS; @@ -1104,8 +1104,8 @@ id2entry_retry: if ( rs->sr_err == LDAP_COMPARE_TRUE ) { /* check size limit */ - if ( --sop->ors_slimit == -1 && - sop->o_sync_slog_size == -1 ) + if ( --sop->ors_slimit == -1 && + sop->o_sync_slog_size == -1 ) { if (!IS_PSEARCH) { bdb_cache_return_entry_r( bdb->bi_dbenv, @@ -1121,6 +1121,21 @@ id2entry_retry: } if ( get_pagedresults(sop) ) { + if ( sop->ors_limit /* isroot == TRUE */ + && sop->ors_slimit < sop->o_pagedresults_state.ps_count ) { + if (!IS_PSEARCH) { + 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( sop, rs ); + rs->sr_err = LDAP_SUCCESS; + goto done; + } + if ( rs->sr_nentries >= sop->o_pagedresults_size ) { send_pagerequest_response( sop, rs, lastid, tentries ); @@ -1700,6 +1715,7 @@ send_pagerequest_response( respcookie = ( PagedResultsCookie )lastid; op->o_conn->c_pagedresults_state.ps_cookie = respcookie; + op->o_conn->c_pagedresults_state.ps_count = op->o_pagedresults_state.ps_count + rs->sr_nentries; cookie.bv_len = sizeof( respcookie ); cookie.bv_val = (char *)&respcookie; @@ -1722,4 +1738,5 @@ send_pagerequest_response( done: (void) ber_free_buf( ber ); -} +} + diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index ab5ee35546..6ad3dc8c95 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -889,19 +889,21 @@ static int parsePagedResults ( AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie )); - if( reqcookie > op->o_pagedresults_state.ps_cookie ) { + if ( reqcookie > op->o_pagedresults_state.ps_cookie ) { /* bad cookie */ rs->sr_text = "paged results cookie is invalid"; return LDAP_PROTOCOL_ERROR; - } else if( reqcookie < op->o_pagedresults_state.ps_cookie ) { + } else if ( reqcookie < op->o_pagedresults_state.ps_cookie ) { rs->sr_text = "paged results cookie is invalid or old"; return LDAP_UNWILLING_TO_PERFORM; } + } else { /* Initial request. Initialize state. */ op->o_pagedresults_state.ps_cookie = 0; op->o_pagedresults_state.ps_id = NOID; + op->o_pagedresults_state.ps_count = 0; } op->o_pagedresults_size = size; diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index b38a2884d5..0b753fb1fd 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1889,6 +1889,7 @@ typedef struct slap_paged_state { Backend *ps_be; PagedResultsCookie ps_cookie; ID ps_id; + unsigned long ps_count; } PagedResultsState; #define LDAP_PSEARCH_BY_ADD 0x01