]> git.sur5r.net Git - openldap/blob - servers/slapd/limits.c
2b4829a31962a8b5df88215b6bfdec823ef21655
[openldap] / servers / slapd / limits.c
1 /* limits.c - routines to handle regex-based size and time limits */
2 /*
3  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <stdio.h>
10
11 #include <ac/regex.h>
12 #include <ac/string.h>
13
14 #include "slap.h"
15
16 int
17 get_limits( 
18         Backend         *be, 
19         const char      *ndn, 
20         int             *timelimit, 
21         int             *sizelimit 
22 )
23 {
24         struct slap_limits **lm;
25
26         /*
27          * default values
28          */
29         *timelimit = be->be_timelimit;
30         *sizelimit = be->be_sizelimit;
31
32         /*
33          * anonymous or no regex-based limits? 
34          */
35         if ( be->be_limits == NULL || ndn == NULL || ndn[0] == '\0' ) {
36                 return( 0 );
37         }
38
39         for ( lm = be->be_limits; lm[0] != NULL; lm++ ) {
40                 switch ( lm[0]->lm_type) {
41                 case SLAP_LIMITS_EXACT:
42                         if ( strcmp( lm[0]->lm_dn_pat, ndn ) == 0 ) {
43                                 *timelimit = lm[0]->lm_timelimit;
44                                 *sizelimit = lm[0]->lm_sizelimit;
45                                 return( 0 );
46                         }
47                         break;
48
49                 case SLAP_LIMITS_REGEX:
50                         if ( regexec( &lm[0]->lm_dn_regex, ndn, 0, NULL, 0) == 0 ) {
51                                 *timelimit = lm[0]->lm_timelimit;
52                                 *sizelimit = lm[0]->lm_sizelimit;
53                                 return( 0 );
54                         }
55                         break;
56                         
57                 default:
58                         assert( 0 );    /* unreachable */
59                         return( -1 );
60                 }
61         }
62
63         return( 0 );
64 }
65
66 int
67 add_limits(
68         Backend         *be,
69         int             type,
70         const char      *pattern,
71         int             timelimit,
72         int             sizelimit
73 )
74 {
75         int                     i;
76         struct slap_limits      *lm;
77         
78         assert( be );
79         assert( pattern);
80
81         lm = ( struct slap_limits * )ch_calloc( sizeof( struct slap_limits ), 1 );
82
83         switch ( type ) {
84         case SLAP_LIMITS_EXACT:
85                 lm->lm_type = SLAP_LIMITS_EXACT;
86                 lm->lm_dn_pat = ch_strdup( pattern );
87                 if ( dn_normalize( lm->lm_dn_pat ) == NULL ) {
88                         ch_free( lm->lm_dn_pat );
89                         ch_free( lm );
90                         return( -1 );
91                 }
92                 break;
93                 
94         case SLAP_LIMITS_REGEX:
95         case SLAP_LIMITS_UNDEFINED:
96                 lm->lm_type = SLAP_LIMITS_REGEX;
97                 lm->lm_dn_pat = ch_strdup( pattern );
98                 if ( regcomp( &lm->lm_dn_regex, lm->lm_dn_pat, REG_EXTENDED | REG_ICASE ) ) {
99                         ch_free( lm->lm_dn_pat );
100                         ch_free( lm );
101                         return( -1 );
102                 }
103                 break;
104         }
105
106         lm->lm_timelimit = timelimit;
107         lm->lm_sizelimit = sizelimit;
108
109         if ( be->be_limits == NULL ) {
110                 i = 1;
111                 be->be_limits = ( struct slap_limits ** )ch_calloc( sizeof( struct slap_limits * ), 2 );
112         } else {
113                 for ( i = 0; be->be_limits[i]; i++ );
114                 
115                 be->be_limits = ( struct slap_limits ** )ch_realloc( be->be_limits,
116                         sizeof( struct slap_limits * ) * ( i + 1 ) );
117         }
118         be->be_limits[i] = lm;
119         
120         return( 0 );
121 }
122
123 int
124 parse_limits(
125         Backend     *be,
126         const char  *fname,
127         int         lineno,
128         int         argc,
129         char        **argv
130 )
131 {
132         int     type = SLAP_LIMITS_UNDEFINED;
133         char    *pattern;
134         int     timelimit;
135         int     sizelimit;
136         int     i;
137
138         assert( be );
139
140         if ( argc < 3 ) {
141 #ifdef NEW_LOGGING
142                 LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
143                         "%s : line %d: missing arg(s) in "
144                         "\"limits <pattern> <limits>\" line.\n",
145                         fname, lineno ));
146 #else
147                 Debug( LDAP_DEBUG_ANY,
148                         "%s : line %d: missing arg(s) in "
149                         "\"limits <pattern> <limits>\" line.\n%s",
150                         fname, lineno, "" );
151 #endif
152                 return( -1 );
153         }
154
155         timelimit = be->be_timelimit;
156         sizelimit = be->be_sizelimit;
157
158         /*
159          * syntax:
160          *
161          * "limits" <pattern> <limit> [ <limit> [ ... ] ]
162          * 
163          * 
164          * <pattern>:
165          * 
166          * [ "dn" [ "." { "exact" | "regex" } ] "=" ] <dn pattern>
167          *
168          * 
169          * <limit>:
170          *
171          * { "time" | "size" } "=" <value>
172          */
173         
174         pattern = argv[1];
175         if ( strncasecmp( pattern, "dn", 2 ) == 0 ) {
176                 pattern += 2;
177                 if ( pattern[0] == '.' ) {
178                         pattern++;
179                         if ( strncasecmp( pattern, "exact", 5 ) == 0 ) {
180                                 type = SLAP_LIMITS_EXACT;
181                                 pattern += 5;
182                         } else if ( strncasecmp( pattern, "regex", 5 ) == 0 ) {
183                                 type = SLAP_LIMITS_REGEX;
184                                 pattern += 5;
185                         }
186                 }
187
188                 if ( pattern[0] != '=' ) {
189 #ifdef NEW_LOGGING
190                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
191                                 "%s : line %d: missing '=' in "
192                                 "\"dn[.{exact|regex}]=<pattern>\" in "
193                                 "\"limits <pattern> <limits>\" line.\n",
194                         fname, lineno ));
195 #else
196                         Debug( LDAP_DEBUG_ANY,
197                                 "%s : line %d: missing '=' in "
198                                 "\"dn[.{exact|regex}]=<pattern>\" in "
199                                 "\"limits <pattern> <limits>\" line.\n%s",
200                         fname, lineno, "" );
201 #endif
202                         return( -1 );
203                 }
204
205                 /* skip '=' (required) */
206                 pattern++;
207         }
208
209         for ( i = 2; i < argc; i++ ) {
210                 if ( strncasecmp( argv[i], "time=", 5) == 0 ) {
211                         timelimit = atoi( argv[i]+5 );
212                 } else if ( strncasecmp( argv[i], "size=", 5) == 0 ) {
213                         sizelimit = atoi( argv[i]+5 );
214                 } else {
215 #ifdef NEW_LOGGING
216                         LDAP_LOG(( "config", LDAP_LEVEL_CRIT,
217                                 "%s : line %d: unknown limit type \"%s\" in "
218                                 "\"limits <pattern> <limits>\" line "
219                                 "(ignored).\n",
220                         fname, lineno, argv[i] ));
221 #else
222                         Debug( LDAP_DEBUG_ANY,
223                                 "%s : line %d: unknown limit type \"%s\" in "
224                                 "\"limits <pattern> <limits>\" line "
225                                 "(ignored).\n",
226                         fname, lineno, argv[i] );
227 #endif
228                 }
229         }
230         
231         return( add_limits( be, type, pattern, timelimit, sizelimit ) );
232 }
233