mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-23 14:09:39 +08:00
handle regex-based per op_ndn time/size limits
This commit is contained in:
parent
c842bf8b80
commit
4051547dfa
@ -19,6 +19,7 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \
|
||||
schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
|
||||
configinfo.c starttls.c index.c sets.c \
|
||||
root_dse.c sasl.c module.c suffixalias.c mra.c mods.c \
|
||||
limits.c \
|
||||
$(@PLAT@_SRCS)
|
||||
|
||||
OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
|
||||
@ -31,6 +32,7 @@ OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
|
||||
schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
|
||||
configinfo.o starttls.o index.o sets.o \
|
||||
root_dse.o sasl.o module.o suffixalias.o mra.o mods.o \
|
||||
limits.o \
|
||||
$(@PLAT@_OBJS)
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
|
@ -727,6 +727,25 @@ read_config( const char *fname )
|
||||
be->be_timelimit = atoi( cargv[1] );
|
||||
}
|
||||
|
||||
/* set regex-based limits */
|
||||
} else if ( strcasecmp( cargv[0], "limits" ) == 0 ) {
|
||||
if ( be == NULL ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "config", LDAP_LEVEL_WARNING,
|
||||
"%s: line %d \"limits\" allowed only in database environment.\n",
|
||||
fname, lineno ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d \"limits\" allowed only in database environment.\n%s",
|
||||
fname, lineno, "" );
|
||||
#endif
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if ( parse_limits( be, fname, lineno, cargc, cargv ) ) {
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* set database suffix */
|
||||
} else if ( strcasecmp( cargv[0], "suffix" ) == 0 ) {
|
||||
Backend *tmp_be;
|
||||
|
233
servers/slapd/limits.c
Normal file
233
servers/slapd/limits.c
Normal file
@ -0,0 +1,233 @@
|
||||
/* limits.c - routines to handle regex-based size and time limits */
|
||||
/*
|
||||
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
|
||||
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ac/regex.h>
|
||||
#include <ac/string.h>
|
||||
|
||||
#include "slap.h"
|
||||
|
||||
int
|
||||
get_limits(
|
||||
Backend *be,
|
||||
const char *ndn,
|
||||
int *timelimit,
|
||||
int *sizelimit
|
||||
)
|
||||
{
|
||||
struct slap_limits **lm;
|
||||
|
||||
/*
|
||||
* default values
|
||||
*/
|
||||
*timelimit = be->be_timelimit;
|
||||
*sizelimit = be->be_sizelimit;
|
||||
|
||||
/*
|
||||
* anonymous or no regex-based limits?
|
||||
*/
|
||||
if ( be->be_limits == NULL || ndn == NULL || ndn[0] == '\0' ) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
for ( lm = be->be_limits; lm[0] != NULL; lm++ ) {
|
||||
switch ( lm[0]->lm_type) {
|
||||
case SLAP_LIMITS_EXACT:
|
||||
if ( strcmp( lm[0]->lm_dn_pat, ndn ) == 0 ) {
|
||||
*timelimit = lm[0]->lm_timelimit;
|
||||
*sizelimit = lm[0]->lm_sizelimit;
|
||||
return( 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_LIMITS_REGEX:
|
||||
if ( regexec( &lm[0]->lm_dn_regex, ndn, 0, NULL, 0) == 0 ) {
|
||||
*timelimit = lm[0]->lm_timelimit;
|
||||
*sizelimit = lm[0]->lm_sizelimit;
|
||||
return( 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 ); /* unreachable */
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
add_limits(
|
||||
Backend *be,
|
||||
int type,
|
||||
const char *pattern,
|
||||
int timelimit,
|
||||
int sizelimit
|
||||
)
|
||||
{
|
||||
int i;
|
||||
struct slap_limits *lm;
|
||||
|
||||
assert( be );
|
||||
assert( pattern);
|
||||
|
||||
lm = ( struct slap_limits * )ch_calloc( sizeof( struct slap_limits ), 1 );
|
||||
|
||||
switch ( type ) {
|
||||
case SLAP_LIMITS_EXACT:
|
||||
lm->lm_type = SLAP_LIMITS_EXACT;
|
||||
lm->lm_dn_pat = ch_strdup( pattern );
|
||||
if ( dn_normalize( lm->lm_dn_pat ) == NULL ) {
|
||||
ch_free( lm->lm_dn_pat );
|
||||
ch_free( lm );
|
||||
return( -1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SLAP_LIMITS_REGEX:
|
||||
case SLAP_LIMITS_UNDEFINED:
|
||||
lm->lm_type = SLAP_LIMITS_REGEX;
|
||||
lm->lm_dn_pat = ch_strdup( pattern );
|
||||
if ( regcomp( &lm->lm_dn_regex, lm->lm_dn_pat, REG_EXTENDED | REG_ICASE ) ) {
|
||||
ch_free( lm->lm_dn_pat );
|
||||
ch_free( lm );
|
||||
return( -1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lm->lm_timelimit = timelimit;
|
||||
lm->lm_sizelimit = sizelimit;
|
||||
|
||||
if ( be->be_limits == NULL ) {
|
||||
i = 1;
|
||||
be->be_limits = ( struct slap_limits ** )ch_calloc( sizeof( struct slap_limits * ), 2 );
|
||||
} else {
|
||||
for ( i = 0; be->be_limits[i]; i++ );
|
||||
|
||||
be->be_limits = ( struct slap_limits ** )ch_realloc( be->be_limits,
|
||||
sizeof( struct slap_limits * ) * ( i + 1 ) );
|
||||
}
|
||||
be->be_limits[i] = lm;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
parse_limits(
|
||||
Backend *be,
|
||||
const char *fname,
|
||||
int lineno,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
int type = SLAP_LIMITS_UNDEFINED;
|
||||
char *pattern;
|
||||
int timelimit;
|
||||
int sizelimit;
|
||||
int i;
|
||||
|
||||
assert( be );
|
||||
|
||||
if ( argc < 3 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
|
||||
"%s : line %d: missing arg(s) in "
|
||||
"\"limits <pattern> <limits>\" line.\n",
|
||||
fname, lineno ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s : line %d: missing arg(s) in "
|
||||
"\"limits <pattern> <limits>\" line.\n%s",
|
||||
fname, lineno, "" );
|
||||
#endif
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
timelimit = be->be_timelimit;
|
||||
sizelimit = be->be_sizelimit;
|
||||
|
||||
/*
|
||||
* syntax:
|
||||
*
|
||||
* "limits" <pattern> <limit> [ <limit> [ ... ] ]
|
||||
*
|
||||
*
|
||||
* <pattern>:
|
||||
*
|
||||
* [ "dn" [ "." { "exact" | "regex" } ] "=" ] <dn pattern>
|
||||
*
|
||||
*
|
||||
* <limit>:
|
||||
*
|
||||
* { "time" | "size" } "=" <value>
|
||||
*/
|
||||
|
||||
pattern = argv[1];
|
||||
if ( strncasecmp( pattern, "dn", 2 ) == 0 ) {
|
||||
pattern += 2;
|
||||
if ( pattern[0] == '.' ) {
|
||||
pattern++;
|
||||
if ( strncasecmp( pattern, "exact", 5 ) == 0 ) {
|
||||
type = SLAP_LIMITS_EXACT;
|
||||
pattern += 5;
|
||||
} else if ( strncasecmp( pattern, "regex", 5 ) == 0 ) {
|
||||
type = SLAP_LIMITS_REGEX;
|
||||
pattern += 5;
|
||||
}
|
||||
}
|
||||
|
||||
if ( pattern[0] != '=' ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
|
||||
"%s : line %d: missing '=' in "
|
||||
"\"dn[.{exact|regex}]=<pattern>\" in "
|
||||
"\"limits <pattern> <limits>\" line.\n",
|
||||
fname, lineno ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s : line %d: missing '=' in "
|
||||
"\"dn[.{exact|regex}]=<pattern>\" in "
|
||||
"\"limits <pattern> <limits>\" line.\n%s",
|
||||
fname, lineno, "" );
|
||||
#endif
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* skip '=' (required) */
|
||||
pattern++;
|
||||
}
|
||||
|
||||
for ( i = 2; i < argc; i++ ) {
|
||||
if ( strncasecmp( argv[i], "time=", 5) == 0 ) {
|
||||
timelimit = atoi( argv[i]+5 );
|
||||
} else if ( strncasecmp( argv[i], "size=", 5) == 0 ) {
|
||||
sizelimit = atoi( argv[i]+5 );
|
||||
} else {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
|
||||
"%s : line %d: unknown limit type \"%s\" in "
|
||||
"\"limits <pattern> <limits>\" line "
|
||||
"(ignored).\n",
|
||||
fname, lineno, argv[i] ));
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s : line %d: unknown limit type \"%s\" in "
|
||||
"\"limits <pattern> <limits>\" line "
|
||||
"(ignored).\n",
|
||||
fname, lineno, argv[i] );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return( add_limits( be, type, pattern, timelimit, sizelimit ) );
|
||||
}
|
||||
|
@ -396,6 +396,17 @@ LDAP_SLAPD_F (void) filter_print LDAP_P(( Filter *f ));
|
||||
LDAP_SLAPD_F (int) test_filter LDAP_P((
|
||||
Backend *be, Connection *conn, Operation *op, Entry *e, Filter *f ));
|
||||
|
||||
/*
|
||||
* limits.c
|
||||
*/
|
||||
LDAP_SLAPD_F (int) get_limits LDAP_P((
|
||||
Backend *be, const char *ndn, int *timelimit, int *sizelimit ));
|
||||
LDAP_SLAPD_F (int) add_limits LDAP_P((
|
||||
Backend *be, int type, const char *pattern,
|
||||
int timelimit, int sizelimit ));
|
||||
LDAP_SLAPD_F (int) parse_limits LDAP_P((
|
||||
Backend *be, const char *fname, int lineno, int argc, char **argv ));
|
||||
|
||||
/*
|
||||
* lock.c
|
||||
*/
|
||||
|
@ -814,6 +814,17 @@ struct slap_replica_info {
|
||||
char **ri_nsuffix; /* array of suffixes this replica accepts */
|
||||
};
|
||||
|
||||
struct slap_limits {
|
||||
int lm_type; /* type of pattern */
|
||||
#define SLAP_LIMITS_UNDEFINED 0x0000
|
||||
#define SLAP_LIMITS_EXACT 0x0001
|
||||
#define SLAP_LIMITS_REGEX 0x0002
|
||||
regex_t lm_dn_regex; /* regex-based size and time limits */
|
||||
char *lm_dn_pat; /* ndn for EXACT; pattern for REGEX */
|
||||
int lm_timelimit;
|
||||
int lm_sizelimit;
|
||||
};
|
||||
|
||||
/* temporary aliases */
|
||||
typedef BackendDB Backend;
|
||||
#define nbackends nBackendDB
|
||||
@ -911,6 +922,7 @@ struct slap_backend_db {
|
||||
unsigned int be_max_deref_depth; /* limit for depth of an alias deref */
|
||||
int be_sizelimit; /* size limit for this backend */
|
||||
int be_timelimit; /* time limit for this backend */
|
||||
struct slap_limits **be_limits; /* regex-based size and time limits */
|
||||
AccessControl *be_acl; /* access control list for this backend */
|
||||
slap_access_t be_dfltaccess; /* access given if no acl matches */
|
||||
struct slap_replica_info **be_replica; /* replicas of this backend (in master) */
|
||||
|
@ -203,4 +203,14 @@ int add_replica_info( Backend *be, const char *host )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int parse_limits( Backend *be, const char *fname, int lineno, int argc, char **argv )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_limits( Backend *be, const char *ndn, int *timelimit, int *sizelimit )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user