From 2e13fbeea13ccc75dc58e59c627c4644326d7783 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Fri, 9 Apr 2004 15:54:46 +0000 Subject: [PATCH] completion of limits w/ paged results control --- doc/man/man5/slapd.conf.5 | 22 +++++- servers/slapd/back-bdb/search.c | 16 ---- servers/slapd/config.c | 3 +- servers/slapd/limits.c | 135 ++++++++++++++++++++++---------- 4 files changed, 113 insertions(+), 63 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index f3b652c760..5e9d5b17f9 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -447,13 +447,27 @@ no limit is set on If .B pagedResults control is defined, additional size limits may be enforced; the syntax is -.BR size.pr={|noEstimate} , +.BR size.pr={|noEstimate|disabled|none} , where -.BR integer +.B integer is the max page size if no explicit limit is set; the keyword -.IR noEstimate +.I noEstimate inhibits the server to return an estimate of the total number -of entries that will be returned. +of entries that will be returned; the keyword +.I disabled +disables the control; the keyword +.I none +indicates that no limit is applied to the pagedResults control page size. +The syntax +.B size.prtotal={|none} +allows to set a limit on the total number of entries that a pagedResults +control allows to return. +By default it is unlimited, which is indicated by the keyword +.IR none . +When set, +.B integer +is the max number of entries that the whole search with pagedResults control +can return. .RE .\"-- NEW_LOGGING option -- .\".TP diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 048364065b..170059eaed 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -1121,22 +1121,6 @@ id2entry_retry: } if ( get_pagedresults(sop) ) { - if ( sop->ors_limit /* isroot == TRUE */ - && sop->ors_limit->lms_s_pr_total > 0 - && sop->ors_limit->lms_s_pr_total <= rs->sr_nentries + 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 ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index d157227a81..a126e7e5c6 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -54,7 +54,8 @@ struct slap_limits_set deflimit = { 0, -1, /* no limit on unchecked size */ 0, /* page limit */ - 0 /* hide number of entries left */ + 0, /* hide number of entries left */ + -1 /* unlimited number of total entries returned by paged results */ }; AccessControl *global_acl = NULL; diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c index 870bf63224..d30f887f61 100644 --- a/servers/slapd/limits.c +++ b/servers/slapd/limits.c @@ -601,18 +601,15 @@ limits_parse_one( assert( limit ); if ( strncasecmp( arg, "time", STRLENOF( "time" ) ) == 0 ) { - arg += 4; + arg += STRLENOF( "time" ); if ( arg[0] == '.' ) { arg++; - if ( strncasecmp( arg, "soft", STRLENOF( "soft" ) ) == 0 ) { - arg += 4; - if ( arg[0] != '=' ) { - return( 1 ); - } - arg++; + if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) { + arg += STRLENOF( "soft=" ); if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_t_soft = -1; + } else { char *next = NULL; @@ -623,16 +620,14 @@ limits_parse_one( } } - } else if ( strncasecmp( arg, "hard", STRLENOF( "hard" ) ) == 0 ) { - arg += 4; - if ( arg[0] != '=' ) { - return( 1 ); - } - arg++; + } else if ( strncasecmp( arg, "hard=", STRLENOF( "hard=" ) ) == 0 ) { + arg += STRLENOF( "hard=" ); if ( strcasecmp( arg, "soft" ) == 0 ) { limit->lms_t_hard = 0; + } else if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_t_hard = -1; + } else { char *next = NULL; @@ -666,16 +661,12 @@ limits_parse_one( } } else if ( strncasecmp( arg, "size", STRLENOF( "size" ) ) == 0 ) { - arg += 4; + arg += STRLENOF( "size" ); if ( arg[0] == '.' ) { arg++; - if ( strncasecmp( arg, "soft", STRLENOF( "soft" ) ) == 0 ) { - arg += 4; - if ( arg[0] != '=' ) { - return( 1 ); - } - arg++; + if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) { + arg += STRLENOF( "soft=" ); if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_s_soft = -1; } else { @@ -688,16 +679,14 @@ limits_parse_one( } } - } else if ( strncasecmp( arg, "hard", STRLENOF( "hard" ) ) == 0 ) { - arg += 4; - if ( arg[0] != '=' ) { - return( 1 ); - } - arg++; + } else if ( strncasecmp( arg, "hard=", STRLENOF( "hard=" ) ) == 0 ) { + arg += STRLENOF( "hard=" ); if ( strcasecmp( arg, "soft" ) == 0 ) { limit->lms_s_hard = 0; + } else if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_s_hard = -1; + } else { char *next = NULL; @@ -708,12 +697,8 @@ limits_parse_one( } } - } else if ( strncasecmp( arg, "unchecked", STRLENOF( "unchecked" ) ) == 0 ) { - arg += 9; - if ( arg[0] != '=' ) { - return( 1 ); - } - arg++; + } else if ( strncasecmp( arg, "unchecked=", STRLENOF( "unchecked=" ) ) == 0 ) { + arg += STRLENOF( "unchecked=" ); if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_s_unchecked = -1; } else { @@ -731,6 +716,12 @@ limits_parse_one( if ( strcasecmp( arg, "noEstimate" ) == 0 ) { limit->lms_s_pr_hide = 1; + } else if ( strcasecmp( arg, "none" ) == 0 ) { + limit->lms_s_pr = -1; + + } else if ( strcasecmp( arg, "disabled" ) == 0 ) { + limit->lms_s_pr_total = 0; + } else { char *next = NULL; @@ -742,13 +733,18 @@ limits_parse_one( } } else if ( strncasecmp( arg, "prtotal=", STRLENOF( "prtotal=" ) ) == 0 ) { - char *next = NULL; - arg += STRLENOF( "prtotal=" ); - limit->lms_s_pr_total = strtol( arg, &next, 10 ); - if ( next == arg || limit->lms_s_pr_total < -1 ) { - return( 1 ); + if ( strcasecmp( arg, "none" ) == 0 ) { + limit->lms_s_pr_total = -1; + + } else { + char *next = NULL; + + limit->lms_s_pr_total = strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_s_pr_total < -1 ) { + return( 1 ); + } } } else { @@ -826,13 +822,65 @@ limits_check( Operation *op, SlapReply *rs ) /* negative hard limit means no limit */ } + + /* if paged results is requested */ + if ( get_pagedresults( op ) ) { + int slimit = -2; + + /* paged results is not allowed */ + if ( op->ors_limit->lms_s_pr_total == 0 ) { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + rs->sr_text = "pagedResults control not allowed"; + send_ldap_result( op, rs ); + rs->sr_err = LDAP_SUCCESS; + rs->sr_text = NULL; + return -1; - /* 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 no limit is required, use soft limit */ + int total = op->ors_limit->lms_s_pr_total - op->o_pagedresults_state.ps_count; + + if ( total >= 0 && op->ors_limit->lms_s_pr > 0 ) { + /* use the smallest limit set by total/per page */ + if ( total < op->ors_limit->lms_s_pr ) { + slimit = total; + + } else { + /* use the perpage limit if any + * NOTE: + 1 because the given value must be legal */ + slimit = op->ors_limit->lms_s_pr + 1; + } + + } else if ( total >= 0 ) { + /* use the total limit if any */ + slimit = total; + + } else if ( op->ors_limit->lms_s_pr != 0 ) { + /* use the perpage limit if any + * NOTE: + 1 because the given value must be legal */ + slimit = op->ors_limit->lms_s_pr + 1; + + } else { + /* use the standard hard/soft limit if any */ + slimit = ( op->ors_limit->lms_s_hard == 0 ? op->ors_limit->lms_s_soft : op->ors_limit->lms_s_hard ); + } + } + + /* if got any limit, use it */ + if ( slimit != -2 ) { + if ( op->ors_slimit <= 0 ) { + op->ors_slimit = slimit; + + } else if ( op->ors_slimit > slimit ) { + rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED; + send_ldap_result( op, rs ); + rs->sr_err = LDAP_SUCCESS; + return -1; + } + + } else { + /* use the standard hard/soft limit if any */ + op->ors_slimit = ( op->ors_limit->lms_s_hard == 0 ? op->ors_limit->lms_s_soft : op->ors_limit->lms_s_hard ); } /* if requested limit higher than hard limit, abort */ @@ -852,6 +900,9 @@ limits_check( Operation *op, SlapReply *rs ) } /* negative hard limit means no limit */ + + } else if ( op->ors_slimit == 0 ) { + op->ors_slimit = op->ors_limit->lms_s_soft; } } -- 2.39.5