From 59aea479632ec3fe94bd09a76a04532663528ec6 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 21 Nov 2002 12:58:59 +0000 Subject: [PATCH] improve limits handling and consistency; return "Admin limit exceeded" instead of "Unwilling to perform" --- doc/man/man5/slapd.conf.5 | 4 +- servers/slapd/back-bdb/search.c | 12 ++-- servers/slapd/back-ldap/search.c | 12 ++-- servers/slapd/back-ldbm/search.c | 12 ++-- servers/slapd/back-meta/search.c | 12 ++-- servers/slapd/back-sql/search.c | 12 ++-- servers/slapd/limits.c | 100 +++++++++++++++++++++++-------- 7 files changed, 118 insertions(+), 46 deletions(-) diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 21997427a7..ab3a6fb4b4 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -290,7 +290,7 @@ If no time limit is explicitly requested by the client, the .BR soft limit is used; if the requested time limit exceedes the .BR hard -limit, an "Unwilling to perform" is returned. +limit, an "Administrative limit exceeded" is returned. If the .BR hard limit is set to 0 or to the keyword "soft", the soft limit is used @@ -315,7 +315,7 @@ If no size limit is explicitly requested by the client, the .BR soft limit is used; if the requested size limit exceedes the .BR hard -limit, an "Unwilling to perform" is returned. +limit, an "Administrative limit exceeded" is returned. If the .BR hard limit is set to 0 or to the keyword "soft", the soft limit is used diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index dddadbf45a..1f558f1fb5 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -262,13 +262,15 @@ dn2entry_retry: /* if requested limit higher than hard limit, abort */ } else if ( tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) { + if ( limit->lms_t_hard == 0 + && limit->lms_t_soft > -1 + && tlimit > limit->lms_t_soft ) { tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); rc = 0; goto done; @@ -284,13 +286,15 @@ dn2entry_retry: /* if requested limit higher than hard limit, abort */ } else if ( slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) { + if ( limit->lms_s_hard == 0 + && limit->lms_s_soft > -1 + && slimit > limit->lms_s_soft ) { slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); rc = 0; goto done; diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index e2990e81d8..fe25fdc8dc 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -110,12 +110,14 @@ ldap_back_search( /* if requested limit higher than hard limit, abort */ if ( !isroot && tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) { + if ( limit->lms_t_hard == 0 + && limit->lms_t_soft > -1 + && tlimit > limit->lms_t_soft ) { tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { - send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, + send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL ); rc = 0; goto finish; @@ -128,12 +130,14 @@ ldap_back_search( /* if requested limit higher than hard limit, abort */ if ( !isroot && slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) { + if ( limit->lms_s_hard == 0 + && limit->lms_s_soft > -1 + && slimit > limit->lms_s_soft ) { slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { - send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, + send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL ); rc = 0; goto finish; diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c index 875b6e99f6..765e79a543 100644 --- a/servers/slapd/back-ldbm/search.c +++ b/servers/slapd/back-ldbm/search.c @@ -247,13 +247,15 @@ searchit: /* if requested limit higher than hard limit, abort */ } else if ( tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) { + if ( limit->lms_t_hard == 0 + && limit->lms_t_soft > -1 + && tlimit > limit->lms_t_soft ) { tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); rc = 0; goto done; @@ -269,13 +271,15 @@ searchit: /* if requested limit higher than hard limit, abort */ } else if ( slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) { + if ( limit->lms_s_hard == 0 + && limit->lms_s_soft > -1 + && slimit > limit->lms_s_soft ) { slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); rc = 0; goto done; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 35b0aae92d..0a2e04a07f 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -167,12 +167,14 @@ meta_back_search( /* if requested limit higher than hard limit, abort */ if ( !isroot && tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) { + if ( limit->lms_t_hard == 0 + && limit->lms_t_soft > -1 + && tlimit > limit->lms_t_soft ) { tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { - send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, + send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL ); rc = 0; goto finish; @@ -185,12 +187,14 @@ meta_back_search( /* if requested limit higher than hard limit, abort */ if ( !isroot && slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) { + if ( limit->lms_s_hard == 0 + && limit->lms_s_soft > -1 + && slimit > limit->lms_s_soft ) { slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { - send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, + send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL ); rc = 0; goto finish; diff --git a/servers/slapd/back-sql/search.c b/servers/slapd/back-sql/search.c index 411468e6af..b5fefff7ff 100644 --- a/servers/slapd/back-sql/search.c +++ b/servers/slapd/back-sql/search.c @@ -1074,13 +1074,15 @@ backsql_search( /* if requested limit higher than hard limit, abort */ } else if ( tlimit > limit->lms_t_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) { + if ( limit->lms_t_hard == 0 + && limit->lms_t_soft > -1 + && tlimit > limit->lms_t_soft ) { tlimit = limit->lms_t_soft; /* positive hard limit means abort */ } else if ( limit->lms_t_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); return 0; } @@ -1095,13 +1097,15 @@ backsql_search( /* if requested limit higher than hard limit, abort */ } else if ( slimit > limit->lms_s_hard ) { /* no hard limit means use soft instead */ - if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) { + if ( limit->lms_s_hard == 0 + && limit->lms_s_soft > -1 + && slimit > limit->lms_s_soft ) { slimit = limit->lms_s_soft; /* positive hard limit means abort */ } else if ( limit->lms_s_hard > 0 ) { send_search_result( conn, op, - LDAP_UNWILLING_TO_PERFORM, + LDAP_ADMINLIMIT_EXCEEDED, NULL, NULL, NULL, NULL, 0 ); return 0; } diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c index e9e436f68d..19cc9e5528 100644 --- a/servers/slapd/limits.c +++ b/servers/slapd/limits.c @@ -277,31 +277,31 @@ parse_limits( } else if ( strcasecmp( pattern, "users" ) == 0 ) { type = SLAP_LIMITS_USERS; - } else if ( strncasecmp( pattern, "dn", 2 ) == 0 ) { + } else if ( strncasecmp( pattern, "dn", sizeof( "dn") - 1 ) == 0 ) { pattern += 2; if ( pattern[0] == '.' ) { pattern++; - if ( strncasecmp( pattern, "exact", 5 ) == 0 ) { + if ( strncasecmp( pattern, "exact", sizeof( "exact" ) - 1 ) == 0 ) { type = SLAP_LIMITS_EXACT; pattern += 5; - } else if ( strncasecmp( pattern, "base", 4 ) == 0 ) { + } else if ( strncasecmp( pattern, "base", sizeof( "base " ) - 1 ) == 0 ) { type = SLAP_LIMITS_BASE; pattern += 4; - } else if ( strncasecmp( pattern, "one", 3 ) == 0 ) { + } else if ( strncasecmp( pattern, "one", sizeof( "one" ) - 1 ) == 0 ) { type = SLAP_LIMITS_ONE; pattern += 3; - } else if ( strncasecmp( pattern, "subtree", 7 ) == 0 ) { + } else if ( strncasecmp( pattern, "subtree", sizeof( "subtree" ) - 1 ) == 0 ) { type = SLAP_LIMITS_SUBTREE; pattern += 7; - } else if ( strncasecmp( pattern, "children", 8 ) == 0 ) { + } else if ( strncasecmp( pattern, "children", sizeof( "children" ) - 1 ) == 0 ) { type = SLAP_LIMITS_CHILDREN; pattern += 8; - } else if ( strncasecmp( pattern, "regex", 5 ) == 0 ) { + } else if ( strncasecmp( pattern, "regex", sizeof( "regex" ) - 1 ) == 0 ) { type = SLAP_LIMITS_REGEX; pattern += 5; @@ -309,7 +309,7 @@ parse_limits( * this could be deprecated in favour * of the pattern = "anonymous" form */ - } else if ( strncasecmp( pattern, "anonymous", 9 ) == 0 ) { + } else if ( strncasecmp( pattern, "anonymous", sizeof( "anonymous" ) - 1 ) == 0 ) { type = SLAP_LIMITS_ANONYMOUS; pattern = NULL; } @@ -384,11 +384,15 @@ parse_limits( /* * sanity checks ... */ - if ( limit.lms_t_hard > 0 && limit.lms_t_hard < limit.lms_t_soft ) { + if ( limit.lms_t_hard > 0 && + ( limit.lms_t_hard < limit.lms_t_soft + || limit.lms_t_soft == -1 ) ) { limit.lms_t_hard = limit.lms_t_soft; } - if ( limit.lms_s_hard > 0 && limit.lms_s_hard < limit.lms_s_soft ) { + if ( limit.lms_s_hard > 0 && + ( limit.lms_s_hard < limit.lms_s_soft + || limit.lms_s_soft == -1 ) ) { limit.lms_s_hard = limit.lms_s_soft; } @@ -404,20 +408,30 @@ parse_limit( assert( arg ); assert( limit ); - if ( strncasecmp( arg, "time", 4 ) == 0 ) { + if ( strncasecmp( arg, "time", sizeof( "time" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] == '.' ) { arg++; - if ( strncasecmp( arg, "soft", 4 ) == 0 ) { + if ( strncasecmp( arg, "soft", sizeof( "soft" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] != '=' ) { return( 1 ); } arg++; - limit->lms_t_soft = atoi( arg ); + if ( strcasecmp( arg, "none" ) == 0 ) { + limit->lms_t_soft = -1; + } else { + char *next = NULL; + + limit->lms_t_soft = + strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_t_soft < -1 ) { + return( 1 ); + } + } - } else if ( strncasecmp( arg, "hard", 4 ) == 0 ) { + } else if ( strncasecmp( arg, "hard", sizeof( "hard" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] != '=' ) { return( 1 ); @@ -428,7 +442,13 @@ parse_limit( } else if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_t_hard = -1; } else { - limit->lms_t_hard = atoi( arg ); + char *next = NULL; + + limit->lms_t_hard = + strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_t_hard < -1 ) { + return( 1 ); + } } } else { @@ -436,28 +456,43 @@ parse_limit( } } else if ( arg[0] == '=' ) { + char *next = NULL; + arg++; - limit->lms_t_soft = atoi( arg ); + limit->lms_t_soft = strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_t_soft < -1 ) { + return( 1 ); + } limit->lms_t_hard = 0; } else { return( 1 ); } - } else if ( strncasecmp( arg, "size", 4 ) == 0 ) { + } else if ( strncasecmp( arg, "size", sizeof( "size" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] == '.' ) { arg++; - if ( strncasecmp( arg, "soft", 4 ) == 0 ) { + if ( strncasecmp( arg, "soft", sizeof( "soft" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] != '=' ) { return( 1 ); } arg++; - limit->lms_s_soft = atoi( arg ); + if ( strcasecmp( arg, "none" ) == 0 ) { + limit->lms_s_soft = -1; + } else { + char *next = NULL; + + limit->lms_s_soft = + strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_s_soft < -1 ) { + return( 1 ); + } + } - } else if ( strncasecmp( arg, "hard", 4 ) == 0 ) { + } else if ( strncasecmp( arg, "hard", sizeof( "hard" ) - 1 ) == 0 ) { arg += 4; if ( arg[0] != '=' ) { return( 1 ); @@ -468,10 +503,16 @@ parse_limit( } else if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_s_hard = -1; } else { - limit->lms_s_hard = atoi( arg ); + char *next = NULL; + + limit->lms_s_hard = + strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_s_hard < -1 ) { + return( 1 ); + } } - } else if ( strncasecmp( arg, "unchecked", 9 ) == 0 ) { + } else if ( strncasecmp( arg, "unchecked", sizeof( "unchecked" ) - 1 ) == 0 ) { arg += 9; if ( arg[0] != '=' ) { return( 1 ); @@ -480,7 +521,13 @@ parse_limit( if ( strcasecmp( arg, "none" ) == 0 ) { limit->lms_s_unchecked = -1; } else { - limit->lms_s_unchecked = atoi( arg ); + char *next = NULL; + + limit->lms_s_unchecked = + strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_s_unchecked < -1 ) { + return( 1 ); + } } } else { @@ -488,8 +535,13 @@ parse_limit( } } else if ( arg[0] == '=' ) { + char *next = NULL; + arg++; - limit->lms_s_soft = atoi( arg ); + limit->lms_s_soft = strtol( arg, &next, 10 ); + if ( next == arg || limit->lms_s_soft < -1 ) { + return( 1 ); + } limit->lms_s_hard = 0; } else { -- 2.39.5