mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 17:19:43 -05:00
ITS#5734: Search limits by baseDN - limits dn.this="..."
This commit is contained in:
parent
4edb6c96e7
commit
34e8048136
5 changed files with 97 additions and 46 deletions
|
|
@ -1250,23 +1250,33 @@ createTimestamp attributes for entries. It also controls
|
|||
the entryCSN and entryUUID attributes, which are needed
|
||||
by the syncrepl provider. By default, olcLastMod is TRUE.
|
||||
.TP
|
||||
.B olcLimits: <who> <limit> [<limit> [...]]
|
||||
Specify time and size limits based on who initiated an operation.
|
||||
.B olcLimits: <selector> <limit> [<limit> [...]]
|
||||
Specify time and size limits based on the operation's initiator or
|
||||
base DN.
|
||||
The argument
|
||||
.B who
|
||||
.B <selector>
|
||||
can be any of
|
||||
.RS
|
||||
.RS
|
||||
.TP
|
||||
anonymous | users | [dn[.<style>]=]<pattern> | group[/oc[/at]]=<pattern>
|
||||
anonymous | users | [<dnspec>=]<pattern> | group[/oc[/at]]=<pattern>
|
||||
|
||||
.RE
|
||||
with
|
||||
.RS
|
||||
.TP
|
||||
<dnspec> ::= dn[.<type>][.<style>]
|
||||
.TP
|
||||
<type> ::= self | this
|
||||
.TP
|
||||
<style> ::= exact | base | onelevel | subtree | children | regex | anonymous
|
||||
|
||||
.RE
|
||||
DN type
|
||||
.B self
|
||||
is the default and means the bound user, while
|
||||
.B this
|
||||
means the base DN of the operation.
|
||||
The term
|
||||
.B anonymous
|
||||
matches all unauthenticated clients.
|
||||
|
|
@ -1300,7 +1310,7 @@ field is ignored.
|
|||
The same behavior is obtained by using the
|
||||
.B anonymous
|
||||
form of the
|
||||
.B who
|
||||
.B <selector>
|
||||
clause.
|
||||
The term
|
||||
.BR group ,
|
||||
|
|
@ -1414,7 +1424,7 @@ limit is set to
|
|||
to preserve the original behavior.
|
||||
|
||||
In case of no match, the global limits are used.
|
||||
The default values are the same as
|
||||
The default values are the same as for
|
||||
.B olcSizeLimit
|
||||
and
|
||||
.BR olcTimeLimit ;
|
||||
|
|
|
|||
|
|
@ -1172,23 +1172,33 @@ createTimestamp attributes for entries. It also controls
|
|||
the entryCSN and entryUUID attributes, which are needed
|
||||
by the syncrepl provider. By default, lastmod is on.
|
||||
.TP
|
||||
.B limits <who> <limit> [<limit> [...]]
|
||||
Specify time and size limits based on who initiated an operation.
|
||||
.B limits <selector> <limit> [<limit> [...]]
|
||||
Specify time and size limits based on the operation's initiator or
|
||||
base DN.
|
||||
The argument
|
||||
.B who
|
||||
.B <selector>
|
||||
can be any of
|
||||
.RS
|
||||
.RS
|
||||
.TP
|
||||
anonymous | users | [dn[.<style>]=]<pattern> | group[/oc[/at]]=<pattern>
|
||||
anonymous | users | [<dnspec>=]<pattern> | group[/oc[/at]]=<pattern>
|
||||
|
||||
.RE
|
||||
with
|
||||
.RS
|
||||
.TP
|
||||
<dnspec> ::= dn[.<type>][.<style>]
|
||||
.TP
|
||||
<type> ::= self | this
|
||||
.TP
|
||||
<style> ::= exact | base | onelevel | subtree | children | regex | anonymous
|
||||
|
||||
.RE
|
||||
DN type
|
||||
.B self
|
||||
is the default and means the bound user, while
|
||||
.B this
|
||||
means the base DN of the operation.
|
||||
The term
|
||||
.B anonymous
|
||||
matches all unauthenticated clients.
|
||||
|
|
@ -1222,7 +1232,7 @@ field is ignored.
|
|||
The same behavior is obtained by using the
|
||||
.B anonymous
|
||||
form of the
|
||||
.B who
|
||||
.B <selector>
|
||||
clause.
|
||||
The term
|
||||
.BR group ,
|
||||
|
|
@ -1336,7 +1346,7 @@ limit is set to
|
|||
to preserve the original behavior.
|
||||
|
||||
In case of no match, the global limits are used.
|
||||
The default values are the same of
|
||||
The default values are the same as for
|
||||
.B sizelimit
|
||||
and
|
||||
.BR timelimit ;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
/* define to get an error if requesting limit higher than hard */
|
||||
#undef ABOVE_HARD_LIMIT_IS_ERROR
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
static const char *const dn_source[2] = { "DN", "DN.THIS" };
|
||||
#endif
|
||||
|
||||
static char *
|
||||
limits2str( unsigned i )
|
||||
{
|
||||
|
|
@ -63,21 +67,25 @@ limits2str( unsigned i )
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
limits_get(
|
||||
Operation *op,
|
||||
struct berval *ndn,
|
||||
struct slap_limits_set **limit
|
||||
)
|
||||
{
|
||||
struct slap_limits **lm;
|
||||
struct berval *ndns[2];
|
||||
|
||||
assert( op != NULL );
|
||||
assert( limit != NULL );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "==> limits_get: %s dn=\"%s\"\n",
|
||||
ndns[0] = &op->o_ndn;
|
||||
ndns[1] = &op->o_req_ndn;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "==> limits_get: %s self=\"%s\" this=\"%s\"\n",
|
||||
op->o_log_prefix,
|
||||
BER_BVISNULL( ndn ) ? "[anonymous]" : ndn->bv_val, 0 );
|
||||
BER_BVISNULL( ndns[0] ) ? "[anonymous]" : ndns[0]->bv_val,
|
||||
BER_BVISNULL( ndns[1] ) ? "" : ndns[1]->bv_val );
|
||||
/*
|
||||
* default values
|
||||
*/
|
||||
|
|
@ -90,6 +98,8 @@ limits_get(
|
|||
for ( lm = op->o_bd->be_limits; lm[0] != NULL; lm++ ) {
|
||||
unsigned style = lm[0]->lm_flags & SLAP_LIMITS_MASK;
|
||||
unsigned type = lm[0]->lm_flags & SLAP_LIMITS_TYPE_MASK;
|
||||
unsigned isthis = type == SLAP_LIMITS_TYPE_THIS;
|
||||
struct berval *ndn = ndns[isthis];
|
||||
|
||||
switch ( style ) {
|
||||
case SLAP_LIMITS_EXACT:
|
||||
|
|
@ -118,8 +128,8 @@ limits_get(
|
|||
|
||||
if ( dn_match( &lm[0]->lm_pat, ndn ) ) {
|
||||
*limit = &lm[0]->lm_limits;
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=EXACT dn=\"%s\"\n",
|
||||
lm[0]->lm_pat.bv_val, 0, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=EXACT dn=\"%s\"\n",
|
||||
dn_source[isthis], lm[0]->lm_pat.bv_val, 0 );
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
|
@ -171,8 +181,8 @@ limits_get(
|
|||
}
|
||||
|
||||
*limit = &lm[0]->lm_limits;
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s dn=\"%s\"\n",
|
||||
limits2str( style ), lm[0]->lm_pat.bv_val, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=%s dn=\"%s\"\n",
|
||||
dn_source[isthis], limits2str( style ), lm[0]->lm_pat.bv_val );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
|
@ -187,16 +197,16 @@ limits_get(
|
|||
0, NULL, 0 ) == 0 )
|
||||
{
|
||||
*limit = &lm[0]->lm_limits;
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s dn=\"%s\"\n",
|
||||
limits2str( style ), lm[0]->lm_pat.bv_val, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=%s dn=\"%s\"\n",
|
||||
dn_source[isthis], limits2str( style ), lm[0]->lm_pat.bv_val );
|
||||
return( 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_LIMITS_ANONYMOUS:
|
||||
if ( BER_BVISEMPTY( ndn ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s\n",
|
||||
limits2str( style ), 0, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=%s\n",
|
||||
dn_source[isthis], limits2str( style ), 0 );
|
||||
*limit = &lm[0]->lm_limits;
|
||||
return( 0 );
|
||||
}
|
||||
|
|
@ -205,8 +215,8 @@ limits_get(
|
|||
case SLAP_LIMITS_USERS:
|
||||
if ( !BER_BVISEMPTY( ndn ) ) {
|
||||
*limit = &lm[0]->lm_limits;
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s\n",
|
||||
limits2str( style ), 0, 0 );
|
||||
Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=%s\n",
|
||||
dn_source[isthis], limits2str( style ), 0 );
|
||||
return( 0 );
|
||||
}
|
||||
break;
|
||||
|
|
@ -248,6 +258,7 @@ limits_add(
|
|||
case SLAP_LIMITS_ANONYMOUS:
|
||||
case SLAP_LIMITS_USERS:
|
||||
case SLAP_LIMITS_ANY:
|
||||
/* For these styles, type == 0 (SLAP_LIMITS_TYPE_SELF). */
|
||||
for ( i = 0; be->be_limits && be->be_limits[ i ]; i++ ) {
|
||||
if ( be->be_limits[ i ]->lm_flags == style ) {
|
||||
return( -1 );
|
||||
|
|
@ -363,10 +374,12 @@ limits_parse(
|
|||
*
|
||||
* "anonymous"
|
||||
* "users"
|
||||
* [ "dn" [ "." { "exact" | "base" | "onelevel" | "subtree" | children"
|
||||
* | "regex" | "anonymous" } ] "=" ] <dn pattern>
|
||||
* [ "dn" [ "." { "this" | "self" } ] [ "." { "exact" | "base" |
|
||||
* "onelevel" | "subtree" | "children" | "regex" | "anonymous" } ]
|
||||
* "=" ] <dn pattern>
|
||||
*
|
||||
* Note:
|
||||
* "this" is the baseobject, "self" (the default) is the bound DN
|
||||
* "exact" and "base" are the same (exact match);
|
||||
* "onelevel" means exactly one rdn below, NOT including pattern
|
||||
* "subtree" means any rdn below, including pattern
|
||||
|
|
@ -396,18 +409,31 @@ limits_parse(
|
|||
|
||||
} else if ( strncasecmp( pattern, "dn", STRLENOF( "dn" ) ) == 0 ) {
|
||||
pattern += STRLENOF( "dn" );
|
||||
flags = SLAP_LIMITS_TYPE_SELF;
|
||||
if ( pattern[0] == '.' ) {
|
||||
pattern++;
|
||||
if ( strncasecmp( pattern, "this", STRLENOF( "this" )) == 0 ) {
|
||||
flags = SLAP_LIMITS_TYPE_THIS;
|
||||
pattern += STRLENOF( "this" );
|
||||
} else if ( strncasecmp( pattern, "self", STRLENOF( "self" )) == 0 ) {
|
||||
pattern += STRLENOF( "self" );
|
||||
} else {
|
||||
goto got_dn_dot;
|
||||
}
|
||||
}
|
||||
if ( pattern[0] == '.' ) {
|
||||
pattern++;
|
||||
got_dn_dot:
|
||||
if ( strncasecmp( pattern, "exact", STRLENOF( "exact" )) == 0 ) {
|
||||
flags = SLAP_LIMITS_EXACT;
|
||||
flags |= SLAP_LIMITS_EXACT;
|
||||
pattern += STRLENOF( "exact" );
|
||||
|
||||
} else if ( strncasecmp( pattern, "base", STRLENOF( "base" ) ) == 0 ) {
|
||||
flags = SLAP_LIMITS_BASE;
|
||||
flags |= SLAP_LIMITS_BASE;
|
||||
pattern += STRLENOF( "base" );
|
||||
|
||||
} else if ( strncasecmp( pattern, "one", STRLENOF( "one" ) ) == 0 ) {
|
||||
flags = SLAP_LIMITS_ONE;
|
||||
flags |= SLAP_LIMITS_ONE;
|
||||
pattern += STRLENOF( "one" );
|
||||
if ( strncasecmp( pattern, "level", STRLENOF( "level" ) ) == 0 ) {
|
||||
pattern += STRLENOF( "level" );
|
||||
|
|
@ -420,7 +446,7 @@ limits_parse(
|
|||
}
|
||||
|
||||
} else if ( strncasecmp( pattern, "sub", STRLENOF( "sub" ) ) == 0 ) {
|
||||
flags = SLAP_LIMITS_SUBTREE;
|
||||
flags |= SLAP_LIMITS_SUBTREE;
|
||||
pattern += STRLENOF( "sub" );
|
||||
if ( strncasecmp( pattern, "tree", STRLENOF( "tree" ) ) == 0 ) {
|
||||
pattern += STRLENOF( "tree" );
|
||||
|
|
@ -433,18 +459,20 @@ limits_parse(
|
|||
}
|
||||
|
||||
} else if ( strncasecmp( pattern, "children", STRLENOF( "children" ) ) == 0 ) {
|
||||
flags = SLAP_LIMITS_CHILDREN;
|
||||
flags |= SLAP_LIMITS_CHILDREN;
|
||||
pattern += STRLENOF( "children" );
|
||||
|
||||
} else if ( strncasecmp( pattern, "regex", STRLENOF( "regex" ) ) == 0 ) {
|
||||
flags = SLAP_LIMITS_REGEX;
|
||||
flags |= SLAP_LIMITS_REGEX;
|
||||
pattern += STRLENOF( "regex" );
|
||||
|
||||
/*
|
||||
* this could be deprecated in favour
|
||||
* of the pattern = "anonymous" form
|
||||
*/
|
||||
} else if ( strncasecmp( pattern, "anonymous", STRLENOF( "anonymous" ) ) == 0 ) {
|
||||
} else if ( strncasecmp( pattern, "anonymous", STRLENOF( "anonymous" ) ) == 0
|
||||
&& flags == SLAP_LIMITS_TYPE_SELF )
|
||||
{
|
||||
flags = SLAP_LIMITS_ANONYMOUS;
|
||||
pattern = NULL;
|
||||
}
|
||||
|
|
@ -463,8 +491,8 @@ limits_parse(
|
|||
if ( pattern[0] != '=' ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s : line %d: missing '=' in "
|
||||
"\"dn[.{exact|base|onelevel|subtree"
|
||||
"|children|regex|anonymous}]"
|
||||
"\"dn[.{this|self}][.{exact|base"
|
||||
"|onelevel|subtree|children|regex}]"
|
||||
"=<pattern>\" in "
|
||||
"\"limits <pattern> <limits>\" "
|
||||
"line.\n%s",
|
||||
|
|
@ -879,13 +907,14 @@ limits_unparse( struct slap_limits *lim, struct berval *bv, ber_len_t buflen )
|
|||
{
|
||||
struct berval btmp;
|
||||
char *ptr;
|
||||
int lm;
|
||||
int type, lm, dntypelen;
|
||||
|
||||
if ( !bv || !bv->bv_val ) return -1;
|
||||
|
||||
ptr = bv->bv_val;
|
||||
type = lim->lm_flags & SLAP_LIMITS_TYPE_MASK;
|
||||
|
||||
if (( lim->lm_flags & SLAP_LIMITS_TYPE_MASK ) == SLAP_LIMITS_TYPE_GROUP ) {
|
||||
if ( type == SLAP_LIMITS_TYPE_GROUP ) {
|
||||
if ( WHATSLEFT <= STRLENOF( "group/" "/" "=\"" "\"" )
|
||||
+ lim->lm_group_oc->soc_cname.bv_len
|
||||
+ lim->lm_group_ad->ad_cname.bv_len
|
||||
|
|
@ -913,9 +942,11 @@ limits_unparse( struct slap_limits *lim, struct berval *bv, ber_len_t buflen )
|
|||
case SLAP_LIMITS_SUBTREE:
|
||||
case SLAP_LIMITS_CHILDREN:
|
||||
case SLAP_LIMITS_REGEX:
|
||||
if ( WHATSLEFT <= STRLENOF( "dn." "=" "\"" "\"" )
|
||||
dntypelen = type == SLAP_LIMITS_TYPE_SELF
|
||||
? STRLENOF( "dn." ) : STRLENOF( "dn.this." );
|
||||
if ( WHATSLEFT <= dntypelen + STRLENOF( "=" "\"" "\"" )
|
||||
+ strlen( lmpats[lm] ) + lim->lm_pat.bv_len ) return -1;
|
||||
ptr = lutil_strcopy( ptr, "dn." );
|
||||
ptr = lutil_strncopy( ptr, "dn.this.", dntypelen );
|
||||
ptr = lutil_strcopy( ptr, lmpats[lm] );
|
||||
*ptr++ = '=';
|
||||
*ptr++ = '"';
|
||||
|
|
@ -1132,7 +1163,7 @@ limits_check( Operation *op, SlapReply *rs )
|
|||
|
||||
/* if not root, get appropriate limits */
|
||||
} else {
|
||||
( void ) limits_get( op, &op->o_ndn, &op->ors_limit );
|
||||
( void ) limits_get( op, &op->ors_limit );
|
||||
|
||||
assert( op->ors_limit != NULL );
|
||||
|
||||
|
|
|
|||
|
|
@ -1115,9 +1115,6 @@ LDAP_SLAPD_F (int) slap_build_syncUUID_set LDAP_P((
|
|||
/*
|
||||
* limits.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) limits_get LDAP_P((
|
||||
Operation *op, struct berval *ndn,
|
||||
struct slap_limits_set **limit ));
|
||||
LDAP_SLAPD_F (int) limits_parse LDAP_P((
|
||||
Backend *be, const char *fname, int lineno,
|
||||
int argc, char **argv ));
|
||||
|
|
|
|||
|
|
@ -1641,6 +1641,7 @@ struct slap_limits_set {
|
|||
|
||||
struct slap_limits {
|
||||
unsigned lm_flags; /* type of pattern */
|
||||
/* Values must match lmpats[] in limits.c */
|
||||
#define SLAP_LIMITS_UNDEFINED 0x0000U
|
||||
#define SLAP_LIMITS_EXACT 0x0001U
|
||||
#define SLAP_LIMITS_BASE SLAP_LIMITS_EXACT
|
||||
|
|
@ -1653,8 +1654,10 @@ struct slap_limits {
|
|||
#define SLAP_LIMITS_ANY 0x0008U
|
||||
#define SLAP_LIMITS_MASK 0x000FU
|
||||
|
||||
#define SLAP_LIMITS_TYPE_DN 0x0000U
|
||||
#define SLAP_LIMITS_TYPE_SELF 0x0000U
|
||||
#define SLAP_LIMITS_TYPE_DN SLAP_LIMITS_TYPE_SELF
|
||||
#define SLAP_LIMITS_TYPE_GROUP 0x0010U
|
||||
#define SLAP_LIMITS_TYPE_THIS 0x0020U
|
||||
#define SLAP_LIMITS_TYPE_MASK 0x00F0U
|
||||
|
||||
regex_t lm_regex; /* regex data for REGEX */
|
||||
|
|
|
|||
Loading…
Reference in a new issue