]> git.sur5r.net Git - openldap/commitdiff
completion of limits w/ paged results control
authorPierangelo Masarati <ando@openldap.org>
Fri, 9 Apr 2004 15:54:46 +0000 (15:54 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 9 Apr 2004 15:54:46 +0000 (15:54 +0000)
doc/man/man5/slapd.conf.5
servers/slapd/back-bdb/search.c
servers/slapd/config.c
servers/slapd/limits.c

index f3b652c7609ee287984c802c24f246bc538396ea..5e9d5b17f90547bb4eadf3d3470b1fdb6defd6e6 100644 (file)
@@ -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={<integer>|noEstimate} ,
+.BR size.pr={<integer>|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={<integer>|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
index 048364065b4b24fcdf61da041c1bca75c82aa67a..170059eaed002f14ff25caba70e1fc4be3458e68 100644 (file)
@@ -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 );
index d157227a8136e5e486fefeb77537730b6c22726f..a126e7e5c669cbb2044187358a14a34c5ceb9d92 100644 (file)
@@ -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;
index 870bf632245cffc625fbb7f82d0d6dd04c694175..d30f887f61c1289c17f96f61a8dea63476d994f7 100644 (file)
@@ -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;
                }
        }