]> git.sur5r.net Git - openldap/commitdiff
use hard limit instead of returning adminLimitExceeded when requested limit exceeds...
authorPierangelo Masarati <ando@openldap.org>
Tue, 22 Jun 2004 09:43:41 +0000 (09:43 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 22 Jun 2004 09:43:41 +0000 (09:43 +0000)
doc/man/man5/slapd.conf.5
servers/slapd/limits.c
tests/data/slapd-limits.conf
tests/scripts/test025-limits

index 5a26bcf9076463f846b2344388f9e29ef1a0fc91..d495e94000f2bf477cf9e2f97d9f2046e5d24490 100644 (file)
@@ -807,8 +807,6 @@ e.g. ldapi:// (and eventually IPSEC).  It is not normally used.
 Specify the maximum number of entries to return from a search operation.
 The default size limit is 500.
 Use
-.B -1
-or 
 .B unlimited
 to specify no limits.
 The second format allows a fine grain setting of the size limits.
@@ -841,8 +839,6 @@ Specify the maximum number of seconds (in real time)
 .B slapd
 will spend answering a search request.  The default time limit is 3600.
 Use
-.B -1
-or 
 .B unlimited
 to specify no limits.
 The second format allows a fine grain setting of the time limits.
@@ -1070,21 +1066,22 @@ and
 The syntax for time limits is 
 .BR time[.{soft|hard}]=<integer> ,
 where 
-.BR integer
+.I integer
 is the number of seconds slapd will spend answering a search request.
 If no time limit is explicitly requested by the client, the 
 .BR soft
 limit is used; if the requested time limit exceeds the
 .BR hard
-limit, an
-.I "Administrative limit exceeded"
-error is returned.
+.\"limit, an
+.\".I "Administrative limit exceeded"
+.\"error is returned.
+limit, the value of the limit is used instead.
 If the
 .BR hard
 limit is set to the keyword 
 .IR soft ,
 the soft limit is used in either case; if it is set to the keyword 
-.IR none , 
+.IR unlimited , 
 no hard limit is enforced.
 Explicit requests for time limits smaller or equal to the
 .BR hard 
@@ -1093,27 +1090,30 @@ If no limit specifier is set, the value is assigned to the
 .BR soft 
 limit, and the
 .BR hard
-limit is set to soft, to preserve the original behavior.
+limit is set to
+.IR soft ,
+to preserve the original behavior.
 
 The syntax for size limits is
 .BR size[.{soft|hard|unchecked}]=<integer> ,
 where
-.BR integer
+.I integer
 is the maximum number of entries slapd will return answering a search 
 request.
 If no size limit is explicitly requested by the client, the
 .BR soft
 limit is used; if the requested size limit exceeds the
 .BR hard
-limit, an 
-.I "Administrative limit exceeded"
-error is returned.
+.\"limit, an 
+.\".I "Administrative limit exceeded"
+.\"error is returned.
+limit, the value of the limit is used instead.
 If the 
 .BR hard
 limit is set to the keyword 
 .IR soft , 
 the soft limit is used in either case; if it is set to the keyword
-.IR none , 
+.IR unlimited , 
 no hard limit is enforced.
 Explicit requests for size limits smaller or equal to the
 .BR hard
@@ -1122,12 +1122,21 @@ The
 .BR unchecked
 specifier sets a limit on the number of candidates a search request is allowed
 to examine.
+The rationale behind it is that searches for non-properly indicized
+attributes may result in large sets of candidates, which must be 
+examined by
+.BR slapd (8)
+to determine whether they match the search filter or not.
+The
+.B unckeched
+limit provides a means to drop such operations before they are even 
+started.
 If the selected candidates exceed the 
 .BR unchecked
 limit, the search will abort with 
 .IR "Unwilling to perform" .
 If it is set to the keyword 
-.IR none , 
+.IR unlimited , 
 no limit is applied (the default).
 If it is set to
 .IR disable ,
@@ -1137,7 +1146,9 @@ If no limit specifier is set, the value is assigned to the
 .BR soft 
 limit, and the
 .BR hard
-limit is set to soft, to preserve the original behavior.
+limit is set to
+.IR soft ,
+to preserve the original behavior.
 
 In case of no match, the global limits are used.
 The default values are the same of
@@ -1157,31 +1168,33 @@ of entries to be returned.
 However, the size limit applies to the total count of entries returned within
 the search, and not to a single page.
 Additional size limits may be enforced; the syntax is
-.BR size.pr={<integer>|noEstimate|none} ,
+.BR size.pr={<integer>|noEstimate|unlimited} ,
 where
-.B integer
+.I integer
 is the max page size if no explicit limit is set; the keyword
 .I noEstimate
 inhibits the server from returning an estimate of the total number
-of entries that might be returned; the keyword
-.I none
+of entries that might be returned
+(note: the current implementation does not return any estimate).
+The keyword
+.I unlimited
 indicates that no limit is applied to the pagedResults control page size.
 The syntax
-.B size.prtotal={<integer>|none|disabled}
+.B size.prtotal={<integer>|unlimited|disabled}
 allows to set a limit on the total number of entries that a pagedResults
 control allows to return.
 By default it is set to the 
 .B hard
 limit.
 When set, 
-.B integer
+.I integer
 is the max number of entries that the whole search with pagedResults control
 can return.
 Use 
-.B none
-to allow unlimited number of entries to be returned, i.e. to use 
-pagedResults as a means to allow clients to circumvent size limitations 
-on regular searches; the keyword
+.I unlimited
+to allow unlimited number of entries to be returned, e.g. to allow
+the use of the pagedResults control as a means to circumvent size 
+limitations on regular searches; the keyword
 .I disabled
 disables the control, i.e. no paged results can be returned.
 Note that the total number of entries returned when the pagedResults control 
index ff4479ce034c3751f42b539967ed845309f5cfc7..c60e734068c3ff6eac2004c133f76448b56b6bd3 100644 (file)
@@ -23,6 +23,9 @@
 
 #include "slap.h"
 
+/* define to get an error if requesting limit higher than hard */
+#undef ABOVE_HARD_LIMIT_IS_ERROR
+
 static char *
 limits2str( unsigned i )
 {
@@ -734,7 +737,7 @@ limits_parse_one(
                        arg++;
                        if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
                                arg += STRLENOF( "soft=" );
-                               if ( strcasecmp( arg, "none" ) == 0 ) {
+                               if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_t_soft = -1;
 
                                } else {
@@ -750,7 +753,7 @@ limits_parse_one(
                                        }
 
                                        if ( soft == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead; issue warning? */
                                        }
 
                                        limit->lms_t_soft = soft;
@@ -761,7 +764,7 @@ limits_parse_one(
                                if ( strcasecmp( arg, "soft" ) == 0 ) {
                                        limit->lms_t_hard = 0;
 
-                               } else if ( strcasecmp( arg, "none" ) == 0 ) {
+                               } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_t_hard = -1;
 
                                } else {
@@ -777,7 +780,7 @@ limits_parse_one(
                                        }
 
                                        if ( hard == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( hard == 0 ) {
@@ -793,7 +796,7 @@ limits_parse_one(
                        
                } else if ( arg[0] == '=' ) {
                        arg++;
-                       if ( strcasecmp( arg, "none" ) == 0 ) {
+                       if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                limit->lms_t_soft = -1;
 
                        } else {
@@ -817,7 +820,7 @@ limits_parse_one(
                        arg++;
                        if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
                                arg += STRLENOF( "soft=" );
-                               if ( strcasecmp( arg, "none" ) == 0 ) {
+                               if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_s_soft = -1;
 
                                } else {
@@ -833,7 +836,7 @@ limits_parse_one(
                                        }
 
                                        if ( soft == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_soft = soft;
@@ -844,7 +847,7 @@ limits_parse_one(
                                if ( strcasecmp( arg, "soft" ) == 0 ) {
                                        limit->lms_s_hard = 0;
 
-                               } else if ( strcasecmp( arg, "none" ) == 0 ) {
+                               } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_s_hard = -1;
 
                                } else {
@@ -860,7 +863,7 @@ limits_parse_one(
                                        }
 
                                        if ( hard == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( hard == 0 ) {
@@ -872,7 +875,7 @@ limits_parse_one(
                                
                        } else if ( strncasecmp( arg, "unchecked=", STRLENOF( "unchecked=" ) ) == 0 ) {
                                arg += STRLENOF( "unchecked=" );
-                               if ( strcasecmp( arg, "none" ) == 0 ) {
+                               if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_s_unchecked = -1;
 
                                } else if ( strcasecmp( arg, "disabled" ) == 0 ) {
@@ -891,7 +894,7 @@ limits_parse_one(
                                        }
 
                                        if ( unchecked == -1 ) {
-                                               /*  FIXME: use "none" instead */
+                                               /*  FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_unchecked = unchecked;
@@ -902,7 +905,7 @@ limits_parse_one(
                                if ( strcasecmp( arg, "noEstimate" ) == 0 ) {
                                        limit->lms_s_pr_hide = 1;
 
-                               } else if ( strcasecmp( arg, "none" ) == 0 ) {
+                               } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_s_pr = -1;
 
                                } else {
@@ -918,7 +921,7 @@ limits_parse_one(
                                        }
 
                                        if ( pr == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        limit->lms_s_pr = pr;
@@ -927,7 +930,7 @@ limits_parse_one(
                        } else if ( strncasecmp( arg, "prtotal=", STRLENOF( "prtotal=" ) ) == 0 ) {
                                arg += STRLENOF( "prtotal=" );
 
-                               if ( strcasecmp( arg, "none" ) == 0 ) {
+                               if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                        limit->lms_s_pr_total = -1;
 
                                } else if ( strcasecmp( arg, "disabled" ) == 0 ) {
@@ -950,7 +953,7 @@ limits_parse_one(
                                        }
 
                                        if ( total == -1 ) {
-                                               /* FIXME: use "none" instead */
+                                               /* FIXME: use "unlimited" instead */
                                        }
 
                                        if ( total == 0 ) {
@@ -966,7 +969,7 @@ limits_parse_one(
                        
                } else if ( arg[0] == '=' ) {
                        arg++;
-                       if ( strcasecmp( arg, "none" ) == 0 ) {
+                       if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
                                limit->lms_s_soft = -1;
 
                        } else {
@@ -1040,6 +1043,7 @@ limits_check( Operation *op, SlapReply *rs )
                                }
 
                        } else if ( op->ors_limit->lms_t_hard > 0 ) {
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
                                if ( op->ors_tlimit == SLAP_MAX_LIMIT ) {
                                        op->ors_tlimit = op->ors_limit->lms_t_hard;
 
@@ -1050,6 +1054,11 @@ limits_check( Operation *op, SlapReply *rs )
                                        rs->sr_err = LDAP_SUCCESS;
                                        return -1;
                                }
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+                               if ( op->ors_tlimit > op->ors_limit->lms_t_hard ) {
+                                       op->ors_tlimit = op->ors_limit->lms_t_hard;
+                               }
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
                        }
                }
 
@@ -1105,6 +1114,7 @@ limits_check( Operation *op, SlapReply *rs )
                                        slimit = op->ors_slimit - op->o_pagedresults_state.ps_count;
                                }
 
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
                        } else if ( pr_total > 0 && op->ors_slimit != SLAP_MAX_LIMIT
                                        && ( op->ors_slimit == SLAP_NO_LIMIT || op->ors_slimit > pr_total ) )
                        {
@@ -1112,6 +1122,7 @@ limits_check( Operation *op, SlapReply *rs )
                                send_ldap_result( op, rs );
                                rs->sr_err = LDAP_SUCCESS;
                                return -1;
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
        
                        } else {
                                /* if no limit is required, use soft limit */
@@ -1121,8 +1132,13 @@ limits_check( Operation *op, SlapReply *rs )
                                /* first round of pagedResults: set count to any appropriate limit */
 
                                /* if the limit is set, check that it does not violate any server-side limit */
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
                                if ( op->ors_slimit == SLAP_MAX_LIMIT ) {
                                        slimit2 = op->ors_slimit = pr_total;
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+                               if ( op->ors_slimit == SLAP_MAX_LIMIT || op->ors_slimit > pr_total ) {
+                                       slimit2 = op->ors_slimit = pr_total;
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
 
                                } else if ( op->ors_slimit == 0 ) {
                                        slimit2 = pr_total;
@@ -1196,6 +1212,7 @@ limits_check( Operation *op, SlapReply *rs )
 
                        /* explicit hard limit: error if violated */
                        } else if ( op->ors_limit->lms_s_hard > 0 ) {
+#ifdef ABOVE_HARD_LIMIT_IS_ERROR
                                if ( op->ors_slimit == SLAP_MAX_LIMIT ) {
                                        op->ors_slimit = op->ors_limit->lms_s_hard;
 
@@ -1206,6 +1223,11 @@ limits_check( Operation *op, SlapReply *rs )
                                        rs->sr_err = LDAP_SUCCESS;
                                        return -1;
                                }
+#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
+                               if ( op->ors_slimit > op->ors_limit->lms_s_hard ) {
+                                       op->ors_slimit = op->ors_limit->lms_s_hard;
+                               }
+#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
                        }
                }
 
index cf5894aabf13f8fc8c9b40fd2f47b63ee44f855e..e284f54942250ec98c197a0d85e787201c518d91 100644 (file)
@@ -43,18 +43,18 @@ rootpw              secret
 #hdb#index             uid eq
 
 # Need extra limits for pagedResults on backends that support it...
-#bdb#limits    dn.exact="cn=Unlimited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=none
+#bdb#limits    dn.exact="cn=Unlimited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=unlimited
 #bdb#limits    dn.exact="cn=Page Size Limited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=4
 #bdb#limits    dn.exact="cn=Paged Results Disabled User,ou=Paged Results Users,dc=example,dc=com" size=4 size.prtotal=disabled
 #bdb#limits    dn.exact="cn=Paged Results Limited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.prtotal=10
 
-#hdb#limits    dn.exact="cn=Unlimited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=none
+#hdb#limits    dn.exact="cn=Unlimited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=unlimited
 #hdb#limits    dn.exact="cn=Page Size Limited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.pr=4
 #hdb#limits    dn.exact="cn=Paged Results Disabled User,ou=Paged Results Users,dc=example,dc=com" size=4 size.prtotal=disabled
 #hdb#limits    dn.exact="cn=Paged Results Limited User,ou=Paged Results Users,dc=example,dc=com" size=4 size.prtotal=10
 
-limits dn.exact="cn=Unlimited User,ou=People,dc=example,dc=com" size=none time=none
-limits dn.exact="cn=Soft Limited User,ou=People,dc=example,dc=com" size.soft=4 size.hard=none
+limits dn.exact="cn=Unlimited User,ou=People,dc=example,dc=com" size=unlimited time=unlimited
+limits dn.exact="cn=Soft Limited User,ou=People,dc=example,dc=com" size.soft=4 size.hard=unlimited
 limits dn.exact="cn=Hard Limited User,ou=People,dc=example,dc=com" size.soft=4 size.hard=8
 limits dn.exact="cn=Unchecked Limited User,ou=People,dc=example,dc=com" size.unchecked=4
 limits group="cn=Unchecked Limited Users,ou=Groups,dc=example,dc=com" size.unchecked=4
index 7bcc4fcda384e86e5742e2a064d732e5190dcab5..812419d663c0ec24370cf92fe0b3b8896e7947f1 100755 (executable)
@@ -406,13 +406,23 @@ case $RC in
                fi
        ;;
        4)
-               echo "...error: bumped into server-side size limit instead of hard size administrative limit"
-               test $KILLSERVERS != no && kill -HUP $KILLPIDS
-               exit $RC
-       ;;
-       11)
-               echo "...bumped into server-side hard size administrative limit"
+               if test x"$COUNT" != x ; then
+                       if test "$COUNT" = "$SIZELIMIT" ; then
+                               echo "...error: bumped into requested ($SIZELIMIT) size limit"
+                               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+                               exit $RC
+                       else
+                               echo "...got size limit $COUNT instead of requested $SIZELIMIT entries"
+                       fi
+               else
+                       echo "...error: bumped into server-side size limit, but got no entries!"
+                       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+                       exit $RC
+               fi
        ;;
+#      11)
+#              echo "...bumped into server-side hard size administrative limit"
+#      ;;
        *)
                echo "ldapsearch failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
@@ -446,9 +456,9 @@ case $RC in
                         exit $RC
                fi
        ;;
-       11)
-               echo "...bumped into server-side hard size administrative limit"
-       ;;
+#      11)
+#              echo "...bumped into server-side hard size administrative limit"
+#      ;;
        *)
                echo "ldapsearch failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
@@ -1037,18 +1047,20 @@ case $RC in
                if test x"$COUNT" != x ; then
                        if test "$COUNT" = "$SIZELIMIT" ; then
                                echo "...error: bumped into requested ($SIZELIMIT) size limit"
+                               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+                               exit $RC
                        else
-                               echo "...error: got size limit $SIZELIMIT but $COUNT entries"
+                               echo "...got size limit $COUNT instead of requested $SIZELIMIT entries"
                        fi
                else
                        echo "...error: bumped into server-side size limit, but got no entries!"
+                       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+                       exit $RC
                fi
-                test $KILLSERVERS != no && kill -HUP $KILLPIDS
-                exit $RC
-       ;;
-       11)
-               echo "...bumped into hard size administrative limit"
        ;;
+#      11)
+#              echo "...bumped into hard size administrative limit"
+#      ;;
        *)
                echo "ldapsearch failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
@@ -1074,11 +1086,17 @@ case $RC in
                 fi
        ;;
        4)
-               echo "...bumped into requested ($SIZELIMIT=$COUNT) size limit"
-       ;;
-       11)
-               echo "...bumped into hard size administrative limit"
+               if test x"$COUNT" != x ; then
+                       echo "...bumped into requested ($SIZELIMIT=$COUNT) size limit"
+               else
+                       echo "...error: bumped into size limit but got no entries!"
+                       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+                       exit $RC
+               fi
        ;;
+#      11)
+#              echo "...bumped into hard size administrative limit"
+#      ;;
        *)
                echo "ldapsearch failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
@@ -1102,9 +1120,9 @@ case $RC in
                         exit $RC
                 fi
        ;;
-       11)
-               echo "...bumped into unchecked administrative limit"
-       ;;
+#      11)
+#              echo "...bumped into unchecked administrative limit"
+#      ;;
        *)
                echo "ldapsearch failed ($RC)!"
                test $KILLSERVERS != no && kill -HUP $KILLPIDS