~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to servers/slapd/limits.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug, Steve Langasek, Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (1.1.2 upstream) (0.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20090218184400-zw4mjse9eywt5566
Tags: 2.4.14-0ubuntu1
[ Steve Langasek ]
* New upstream version
  - Fixes a bug with the pcache overlay not returning cached entries
    (closes: #497697)
  - Update evolution-ntlm patch to apply to current Makefiles.
  - (tentatively) drop gnutls-ciphers, since this bug was reported to be
    fixed upstream in 2.4.8.  The fix applied in 2.4.8 didn't match the
    patch from the bug report, so this should be watched for regressions.
* Build against db4.7 instead of db4.2 at last!  Closes: #421946.
* Build with --disable-ndb, to avoid a misbuild when libmysqlclient is
  installed in the build environment.
* New patch, no-crlcheck-for-gnutls, to fix a build failure when using
  --with-tls=gnutls.

[ Mathias Gug ]
* Merge from debian unstable, remaining changes:
  - debian/apparmor-profile: add AppArmor profile
  - debian/slapd.postinst: Reload AA profile on configuration
  - updated debian/slapd.README.Debian for note on AppArmor
  - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6
  - debian/control: Conflicts with apparmor-profiles << 2.1+1075-0ubuntu4
    to make sure that if earlier version of apparmour-profiles gets
    installed it won't overwrite our profile.
  - Modify Maintainer value to match the DebianMaintainerField
    speficication.
  - follow ApparmorProfileMigration and force apparmor compalin mode on 
    some upgrades (LP: #203529)
  - debian/slapd.dirs: add etc/apparmor.d/force-complain
  - debian/slapd.preinst: create symlink for force-complain on pre-feisty
    upgrades, upgrades where apparmor-profiles profile is unchanged (ie
    non-enforcing) and upgrades where apparmor profile does not exist.
  - debian/slapd.postrm: remove symlink in force-complain/ on purge
  - debian/patches/fix-ucred-libc due to changes how newer glibc handle
    the ucred struct now.
  - debian/control:
    - Build-depend on libltdl7-dev rather then libltdl3-dev.
  - debian/patches/autogen.sh:
    - Call libtoolize with the --install option to install config.{guess,sub}
      files.
  - Don't use local statement in config script as it fails if /bin/sh
    points to bash (LP: #286063).
  - Disable the testsuite on hppa. Allows building of packages on this
    architecture again, once this package is in the archive.
    LP: #288908.
  - debian/slapd.postinst, debian/slapd.script-common: set correct ownership
    and permissions on /var/lib/ldap, /etc/ldap/slapd.d (group readable) and
    /var/run/slapd (world readable). (LP: #257667).
  - debian/patches/nssov-build, debian/rules: 
    Build and package the nss overlay.
    debian/schema/misc.ldif: add ldif file for the misc schema, which defines
    rfc822MailMember (required by the nss overlay).
  - debian/{control,rules}: enable PIE hardening
  - Use cn=config as the default configuration backend instead of 
    slapd.conf. Migrate slapd.conf  file to /etc/ldap/slapd.d/ on upgrade
    asking the end user to enter a new password to control the access to the
    cn=config tree.
* debian/patches/corrupt-contextCSN: The contextCSN can get corrupted at
  times. (ITS: #5947)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* limits.c - routines to handle regex-based size and time limits */
2
 
/* $OpenLDAP: pkg/ldap/servers/slapd/limits.c,v 1.73.2.6 2008/02/11 23:26:44 kurt Exp $ */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/limits.c,v 1.73.2.10 2009/01/22 00:01:01 kurt Exp $ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
 
 * Copyright 1998-2008 The OpenLDAP Foundation.
 
5
 * Copyright 1998-2009 The OpenLDAP Foundation.
6
6
 * All rights reserved.
7
7
 *
8
8
 * Redistribution and use in source and binary forms, with or without
18
18
 
19
19
#include <stdio.h>
20
20
 
 
21
#include <ac/ctype.h>
21
22
#include <ac/regex.h>
22
23
#include <ac/string.h>
23
24
 
27
28
/* define to get an error if requesting limit higher than hard */
28
29
#undef ABOVE_HARD_LIMIT_IS_ERROR
29
30
 
30
 
static char *
 
31
static const struct berval lmpats[] = {
 
32
        BER_BVC( "base" ),
 
33
        BER_BVC( "base" ),
 
34
        BER_BVC( "onelevel" ),
 
35
        BER_BVC( "subtree" ),
 
36
        BER_BVC( "children" ),
 
37
        BER_BVC( "regex" ),
 
38
        BER_BVC( "anonymous" ),
 
39
        BER_BVC( "users" ),
 
40
        BER_BVC( "*" )
 
41
};
 
42
 
 
43
#ifdef LDAP_DEBUG
 
44
static const char *const dn_source[2] = { "DN", "DN.THIS" };
 
45
static const char *const lmpats_out[] = {
 
46
        "UNDEFINED",
 
47
        "EXACT",
 
48
        "ONELEVEL",
 
49
        "SUBTREE",
 
50
        "CHILDREN",
 
51
        "REGEX",
 
52
        "ANONYMOUS",
 
53
        "USERS",
 
54
        "ANY"
 
55
};
 
56
 
 
57
static const char *
31
58
limits2str( unsigned i )
32
59
{
33
 
        switch ( i ) {
34
 
        case SLAP_LIMITS_UNDEFINED:
35
 
                return "UNDEFINED";
36
 
 
37
 
        case SLAP_LIMITS_EXACT:
38
 
                return "EXACT";
39
 
                        
40
 
        case SLAP_LIMITS_ONE:
41
 
                return "ONELEVEL";      
42
 
 
43
 
        case SLAP_LIMITS_SUBTREE:
44
 
                return "SUBTREE";
45
 
 
46
 
        case SLAP_LIMITS_CHILDREN:
47
 
                return "CHILDREN";
48
 
 
49
 
        case SLAP_LIMITS_REGEX:
50
 
                return "REGEX";
51
 
 
52
 
        case SLAP_LIMITS_ANONYMOUS:
53
 
                return "ANONYMOUS";
54
 
                
55
 
        case SLAP_LIMITS_USERS:
56
 
                return "USERS";
57
 
                
58
 
        case SLAP_LIMITS_ANY:
59
 
                return "ANY";
60
 
 
61
 
        default:
62
 
                return "UNKNOWN";
63
 
        }
 
60
        return i < (sizeof( lmpats_out ) / sizeof( lmpats_out[0] ))
 
61
                ? lmpats_out[i] : "UNKNOWN";
64
62
}
 
63
#endif /* LDAP_DEBUG */
65
64
 
66
 
int
 
65
static int
67
66
limits_get( 
68
67
        Operation               *op,
69
 
        struct berval           *ndn, 
70
68
        struct slap_limits_set  **limit
71
69
)
72
70
{
 
71
        static struct berval empty_dn = BER_BVC( "" );
73
72
        struct slap_limits **lm;
 
73
        struct berval           *ndns[2];
74
74
 
75
75
        assert( op != NULL );
76
76
        assert( limit != NULL );
77
77
 
78
 
        Debug( LDAP_DEBUG_TRACE, "==> limits_get: %s dn=\"%s\"\n",
 
78
        ndns[0] = &op->o_ndn;
 
79
        ndns[1] = &op->o_req_ndn;
 
80
 
 
81
        Debug( LDAP_DEBUG_TRACE, "==> limits_get: %s self=\"%s\" this=\"%s\"\n",
79
82
                        op->o_log_prefix,
80
 
                        BER_BVISNULL( ndn ) ? "[anonymous]" : ndn->bv_val, 0 );
 
83
                        BER_BVISNULL( ndns[0] ) ? "[anonymous]" : ndns[0]->bv_val,
 
84
                        BER_BVISNULL( ndns[1] ) ? "" : ndns[1]->bv_val );
81
85
        /*
82
86
         * default values
83
87
         */
90
94
        for ( lm = op->o_bd->be_limits; lm[0] != NULL; lm++ ) {
91
95
                unsigned        style = lm[0]->lm_flags & SLAP_LIMITS_MASK;
92
96
                unsigned        type = lm[0]->lm_flags & SLAP_LIMITS_TYPE_MASK;
 
97
                unsigned        isthis = type == SLAP_LIMITS_TYPE_THIS;
 
98
                struct berval *ndn = ndns[isthis];
 
99
 
 
100
                if ( style == SLAP_LIMITS_ANY )
 
101
                        goto found_any;
 
102
 
 
103
                if ( BER_BVISEMPTY( ndn ) ) {
 
104
                        if ( style == SLAP_LIMITS_ANONYMOUS )
 
105
                                goto found_nodn;
 
106
                        if ( !isthis )
 
107
                                continue;
 
108
                        ndn = &empty_dn;
 
109
                }
93
110
 
94
111
                switch ( style ) {
95
112
                case SLAP_LIMITS_EXACT:
96
 
                        if ( BER_BVISEMPTY( ndn ) ) {
97
 
                                break;
98
 
                        }
99
 
 
100
113
                        if ( type == SLAP_LIMITS_TYPE_GROUP ) {
101
 
                                int     rc;
102
 
 
103
 
                                rc = backend_group( op, NULL,
 
114
                                int     rc = backend_group( op, NULL,
104
115
                                                &lm[0]->lm_pat, ndn,
105
116
                                                lm[0]->lm_group_oc,
106
117
                                                lm[0]->lm_group_ad );
107
118
                                if ( rc == 0 ) {
108
 
                                        *limit = &lm[0]->lm_limits;
109
 
                                        Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=GROUP match=EXACT "
110
 
                                                        "dn=\"%s\" oc=\"%s\" ad=\"%s\"\n",
111
 
                                                        lm[0]->lm_pat.bv_val,
112
 
                                                        lm[0]->lm_group_oc->soc_cname.bv_val,
113
 
                                                        lm[0]->lm_group_ad->ad_cname.bv_val );
114
 
 
115
 
                                        return( 0 );
 
119
                                        goto found_group;
116
120
                                }
117
121
                        } else {
118
 
                        
119
122
                                if ( dn_match( &lm[0]->lm_pat, ndn ) ) {
120
 
                                        *limit = &lm[0]->lm_limits;
121
 
                                        Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=EXACT dn=\"%s\"\n",
122
 
                                                        lm[0]->lm_pat.bv_val, 0, 0 );
123
 
                                        return( 0 );
 
123
                                        goto found_dn;
124
124
                                }
125
125
                        }
126
126
                        break;
128
128
                case SLAP_LIMITS_ONE:
129
129
                case SLAP_LIMITS_SUBTREE:
130
130
                case SLAP_LIMITS_CHILDREN: {
131
 
                        size_t d;
 
131
                        ber_len_t d;
132
132
                        
133
 
                        if ( BER_BVISEMPTY( ndn ) ) {
134
 
                                break;
135
 
                        }
136
 
 
137
 
                        /* ndn shorter than dn_pat */
 
133
                        /* ndn shorter than lm_pat */
138
134
                        if ( ndn->bv_len < lm[0]->lm_pat.bv_len ) {
139
135
                                break;
140
136
                        }
141
137
                        d = ndn->bv_len - lm[0]->lm_pat.bv_len;
142
138
 
143
 
                        /* allow exact match for SUBTREE only */
144
139
                        if ( d == 0 ) {
 
140
                                /* allow exact match for SUBTREE only */
145
141
                                if ( style != SLAP_LIMITS_SUBTREE ) {
146
142
                                        break;
147
143
                                }
152
148
                                }
153
149
                        }
154
150
 
155
 
                        /* in case of (sub)match ... */
156
 
                        if ( lm[0]->lm_pat.bv_len == ( ndn->bv_len - d )
157
 
                                        && strcmp( lm[0]->lm_pat.bv_val,
158
 
                                                &ndn->bv_val[d] ) == 0 )
159
 
                        {
160
 
                                /* check for exactly one rdn in case of ONE */
161
 
                                if ( style == SLAP_LIMITS_ONE ) {
162
 
                                        /*
163
 
                                         * if ndn is more that one rdn
164
 
                                         * below dn_pat, continue
165
 
                                         */
166
 
                                        if ( (size_t) dn_rdnlen( NULL, ndn )
167
 
                                                        != d - 1 )
168
 
                                        {
169
 
                                                break;
170
 
                                        }
 
151
                        /* check that ndn ends with lm_pat */
 
152
                        if ( strcmp( lm[0]->lm_pat.bv_val, &ndn->bv_val[d] ) != 0 ) {
 
153
                                break;
 
154
                        }
 
155
 
 
156
                        /* in case of ONE, require exactly one rdn below lm_pat */
 
157
                        if ( style == SLAP_LIMITS_ONE ) {
 
158
                                if ( dn_rdnlen( NULL, ndn ) != d - 1 ) {
 
159
                                        break;
171
160
                                }
172
 
 
173
 
                                *limit = &lm[0]->lm_limits;
174
 
                                Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s dn=\"%s\"\n",
175
 
                                                limits2str( style ), lm[0]->lm_pat.bv_val, 0 );
176
 
                                return( 0 );
177
161
                        }
178
162
 
179
 
                        break;
 
163
                        goto found_dn;
180
164
                }
181
165
 
182
166
                case SLAP_LIMITS_REGEX:
183
 
                        if ( BER_BVISEMPTY( ndn ) ) {
184
 
                                break;
185
 
                        }
186
 
                        if ( regexec( &lm[0]->lm_regex, ndn->bv_val,
187
 
                                                0, NULL, 0 ) == 0 )
188
 
                        {
189
 
                                *limit = &lm[0]->lm_limits;
190
 
                                Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s dn=\"%s\"\n",
191
 
                                                limits2str( style ), lm[0]->lm_pat.bv_val, 0 );
192
 
                                return( 0 );
 
167
                        if ( regexec( &lm[0]->lm_regex, ndn->bv_val, 0, NULL, 0 ) == 0 ) {
 
168
                                goto found_dn;
193
169
                        }
194
170
                        break;
195
171
 
196
172
                case SLAP_LIMITS_ANONYMOUS:
197
 
                        if ( BER_BVISEMPTY( ndn ) ) {
198
 
                                Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s\n",
199
 
                                                limits2str( style ), 0, 0 );
200
 
                                *limit = &lm[0]->lm_limits;
201
 
                                return( 0 );
202
 
                        }
203
173
                        break;
204
174
 
205
175
                case SLAP_LIMITS_USERS:
206
 
                        if ( !BER_BVISEMPTY( ndn ) ) {
207
 
                                *limit = &lm[0]->lm_limits;
208
 
                                Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=DN match=%s\n",
209
 
                                                limits2str( style ), 0, 0 );
210
 
                                return( 0 );
211
 
                        }
212
 
                        break;
213
 
 
214
 
                case SLAP_LIMITS_ANY:
 
176
                found_nodn:
 
177
                        Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=%s match=%s\n",
 
178
                                dn_source[isthis], limits2str( style ), 0 );
 
179
                found_any:
 
180
                        *limit = &lm[0]->lm_limits;
 
181
                        return( 0 );
 
182
 
 
183
                found_dn:
 
184
                        Debug( LDAP_DEBUG_TRACE,
 
185
                                "<== limits_get: type=%s match=%s dn=\"%s\"\n",
 
186
                                dn_source[isthis], limits2str( style ), lm[0]->lm_pat.bv_val );
 
187
                        *limit = &lm[0]->lm_limits;
 
188
                        return( 0 );
 
189
 
 
190
                found_group:
 
191
                        Debug( LDAP_DEBUG_TRACE, "<== limits_get: type=GROUP match=EXACT "
 
192
                                "dn=\"%s\" oc=\"%s\" ad=\"%s\"\n",
 
193
                                lm[0]->lm_pat.bv_val,
 
194
                                lm[0]->lm_group_oc->soc_cname.bv_val,
 
195
                                lm[0]->lm_group_ad->ad_cname.bv_val );
215
196
                        *limit = &lm[0]->lm_limits;
216
197
                        return( 0 );
217
198
 
248
229
        case SLAP_LIMITS_ANONYMOUS:
249
230
        case SLAP_LIMITS_USERS:
250
231
        case SLAP_LIMITS_ANY:
 
232
                /* For these styles, type == 0 (SLAP_LIMITS_TYPE_SELF). */
251
233
                for ( i = 0; be->be_limits && be->be_limits[ i ]; i++ ) {
252
234
                        if ( be->be_limits[ i ]->lm_flags == style ) {
253
235
                                return( -1 );
267
249
        case SLAP_LIMITS_ONE:
268
250
        case SLAP_LIMITS_SUBTREE:
269
251
        case SLAP_LIMITS_CHILDREN:
270
 
                lm->lm_flags = style | type;
271
252
                {
272
253
                        int rc;
273
254
                        struct berval bv;
283
264
                break;
284
265
                
285
266
        case SLAP_LIMITS_REGEX:
286
 
                lm->lm_flags = style | type;
287
267
                ber_str2bv( pattern, 0, 1, &lm->lm_pat );
288
268
                if ( regcomp( &lm->lm_regex, lm->lm_pat.bv_val, 
289
269
                                        REG_EXTENDED | REG_ICASE ) ) {
296
276
        case SLAP_LIMITS_ANONYMOUS:
297
277
        case SLAP_LIMITS_USERS:
298
278
        case SLAP_LIMITS_ANY:
299
 
                lm->lm_flags = style | type;
300
279
                BER_BVZERO( &lm->lm_pat );
301
280
                break;
302
281
        }
310
289
                break;
311
290
        }
312
291
 
 
292
        lm->lm_flags = style | type;
313
293
        lm->lm_limits = *limit;
314
294
 
315
295
        i = 0;
325
305
        return( 0 );
326
306
}
327
307
 
 
308
#define STRSTART( s, m ) (strncasecmp( s, m, STRLENOF( "" m "" )) == 0)
 
309
 
328
310
int
329
311
limits_parse(
330
312
        Backend     *be,
363
345
         * 
364
346
         * "anonymous"
365
347
         * "users"
366
 
         * [ "dn" [ "." { "exact" | "base" | "onelevel" | "subtree" | children"
367
 
         *      | "regex" | "anonymous" } ] "=" ] <dn pattern>
 
348
         * [ "dn" [ "." { "this" | "self" } ] [ "." { "exact" | "base" |
 
349
         *      "onelevel" | "subtree" | "children" | "regex" | "anonymous" } ]
 
350
         *      "=" ] <dn pattern>
368
351
         *
369
352
         * Note:
 
353
         *      "this" is the baseobject, "self" (the default) is the bound DN
370
354
         *      "exact" and "base" are the same (exact match);
371
355
         *      "onelevel" means exactly one rdn below, NOT including pattern
372
356
         *      "subtree" means any rdn below, including pattern
394
378
        } else if ( strcasecmp( pattern, "users" ) == 0 ) {
395
379
                flags = SLAP_LIMITS_USERS;
396
380
                
397
 
        } else if ( strncasecmp( pattern, "dn", STRLENOF( "dn" ) ) == 0 ) {
 
381
        } else if ( STRSTART( pattern, "dn" ) ) {
398
382
                pattern += STRLENOF( "dn" );
399
 
                if ( pattern[0] == '.' ) {
400
 
                        pattern++;
401
 
                        if ( strncasecmp( pattern, "exact", STRLENOF( "exact" )) == 0 ) {
402
 
                                flags = SLAP_LIMITS_EXACT;
 
383
                flags = SLAP_LIMITS_TYPE_SELF;
 
384
                if ( pattern[0] == '.' ) {
 
385
                        pattern++;
 
386
                        if ( STRSTART( pattern, "this" ) ) {
 
387
                                flags = SLAP_LIMITS_TYPE_THIS;
 
388
                                pattern += STRLENOF( "this" );
 
389
                        } else if ( STRSTART( pattern, "self" ) ) {
 
390
                                pattern += STRLENOF( "self" );
 
391
                        } else {
 
392
                                goto got_dn_dot;
 
393
                        }
 
394
                }
 
395
                if ( pattern[0] == '.' ) {
 
396
                        pattern++;
 
397
                got_dn_dot:
 
398
                        if ( STRSTART( pattern, "exact" ) ) {
 
399
                                flags |= SLAP_LIMITS_EXACT;
403
400
                                pattern += STRLENOF( "exact" );
404
401
 
405
 
                        } else if ( strncasecmp( pattern, "base", STRLENOF( "base" ) ) == 0 ) {
406
 
                                flags = SLAP_LIMITS_BASE;
 
402
                        } else if ( STRSTART( pattern, "base" ) ) {
 
403
                                flags |= SLAP_LIMITS_BASE;
407
404
                                pattern += STRLENOF( "base" );
408
405
 
409
 
                        } else if ( strncasecmp( pattern, "one", STRLENOF( "one" ) ) == 0 ) {
410
 
                                flags = SLAP_LIMITS_ONE;
 
406
                        } else if ( STRSTART( pattern, "one" ) ) {
 
407
                                flags |= SLAP_LIMITS_ONE;
411
408
                                pattern += STRLENOF( "one" );
412
 
                                if ( strncasecmp( pattern, "level", STRLENOF( "level" ) ) == 0 ) {
 
409
                                if ( STRSTART( pattern, "level" ) ) {
413
410
                                        pattern += STRLENOF( "level" );
414
411
 
415
412
                                } else {
419
416
                                                "use \"onelevel\" instead.\n", fname, lineno, 0 );
420
417
                                }
421
418
 
422
 
                        } else if ( strncasecmp( pattern, "sub", STRLENOF( "sub" ) ) == 0 ) {
423
 
                                flags = SLAP_LIMITS_SUBTREE;
 
419
                        } else if ( STRSTART( pattern, "sub" ) ) {
 
420
                                flags |= SLAP_LIMITS_SUBTREE;
424
421
                                pattern += STRLENOF( "sub" );
425
 
                                if ( strncasecmp( pattern, "tree", STRLENOF( "tree" ) ) == 0 ) {
 
422
                                if ( STRSTART( pattern, "tree" ) ) {
426
423
                                        pattern += STRLENOF( "tree" );
427
424
 
428
425
                                } else {
432
429
                                                "use \"subtree\" instead.\n", fname, lineno, 0 );
433
430
                                }
434
431
 
435
 
                        } else if ( strncasecmp( pattern, "children", STRLENOF( "children" ) ) == 0 ) {
436
 
                                flags = SLAP_LIMITS_CHILDREN;
 
432
                        } else if ( STRSTART( pattern, "children" ) ) {
 
433
                                flags |= SLAP_LIMITS_CHILDREN;
437
434
                                pattern += STRLENOF( "children" );
438
435
 
439
 
                        } else if ( strncasecmp( pattern, "regex", STRLENOF( "regex" ) ) == 0 ) {
440
 
                                flags = SLAP_LIMITS_REGEX;
 
436
                        } else if ( STRSTART( pattern, "regex" ) ) {
 
437
                                flags |= SLAP_LIMITS_REGEX;
441
438
                                pattern += STRLENOF( "regex" );
442
439
 
443
440
                        /* 
444
441
                         * this could be deprecated in favour
445
442
                         * of the pattern = "anonymous" form
446
443
                         */
447
 
                        } else if ( strncasecmp( pattern, "anonymous", STRLENOF( "anonymous" ) ) == 0 ) {
 
444
                        } else if ( STRSTART( pattern, "anonymous" )
 
445
                                        && flags == SLAP_LIMITS_TYPE_SELF )
 
446
                        {
448
447
                                flags = SLAP_LIMITS_ANONYMOUS;
449
448
                                pattern = NULL;
 
449
 
 
450
                        } else {
 
451
                                /* force error below */
 
452
                                if ( *pattern == '=' )
 
453
                                        --pattern;
450
454
                        }
451
455
                }
452
456
 
453
457
                /* pre-check the data */
454
 
                switch ( flags ) {
455
 
                case SLAP_LIMITS_ANONYMOUS:
456
 
                case SLAP_LIMITS_USERS:
457
 
 
458
 
                        /* no need for pattern */
459
 
                        pattern = NULL;
460
 
                        break;
461
 
 
462
 
                default:
 
458
                if ( pattern != NULL ) {
463
459
                        if ( pattern[0] != '=' ) {
464
460
                                Debug( LDAP_DEBUG_ANY,
465
 
                                        "%s : line %d: missing '=' in "
466
 
                                        "\"dn[.{exact|base|onelevel|subtree"
467
 
                                        "|children|regex|anonymous}]"
468
 
                                        "=<pattern>\" in "
469
 
                                        "\"limits <pattern> <limits>\" "
470
 
                                        "line.\n%s",
471
 
                                        fname, lineno, "" );
 
461
                                        "%s : line %d: %s in "
 
462
                                        "\"dn[.{this|self}][.{exact|base"
 
463
                                        "|onelevel|subtree|children|regex"
 
464
                                        "|anonymous}]=<pattern>\" in "
 
465
                                        "\"limits <pattern> <limits>\" line.\n",
 
466
                                        fname, lineno,
 
467
                                        isalnum( (unsigned char)pattern[0] )
 
468
                                        ? "unknown DN modifier" : "missing '='" );
472
469
                                return( -1 );
473
470
                        }
474
471
 
480
477
                                flags = SLAP_LIMITS_ANY;
481
478
                                pattern = NULL;
482
479
 
483
 
                        } else if ( flags == SLAP_LIMITS_REGEX
 
480
                        } else if ( (flags & SLAP_LIMITS_MASK) == SLAP_LIMITS_REGEX
484
481
                                        && strcmp( pattern, ".*" ) == 0 ) {
485
482
                                flags = SLAP_LIMITS_ANY;
486
483
                                pattern = NULL;
487
484
                        }
488
485
                }
489
486
 
490
 
        } else if (strncasecmp( pattern, "group", STRLENOF( "group" ) ) == 0 ) {
 
487
        } else if (STRSTART( pattern, "group" ) ) {
491
488
                pattern += STRLENOF( "group" );
492
489
 
493
490
                if ( pattern[0] == '/' ) {
637
634
        assert( arg != NULL );
638
635
        assert( limit != NULL );
639
636
 
640
 
        if ( strncasecmp( arg, "time", STRLENOF( "time" ) ) == 0 ) {
 
637
        if ( STRSTART( arg, "time" ) ) {
641
638
                arg += STRLENOF( "time" );
642
639
 
643
640
                if ( arg[0] == '.' ) {
644
641
                        arg++;
645
 
                        if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
 
642
                        if ( STRSTART( arg, "soft=" ) ) {
646
643
                                arg += STRLENOF( "soft=" );
647
 
                                if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
644
                                if ( strcasecmp( arg, "unlimited" ) == 0
 
645
                                        || strcasecmp( arg, "none" ) == 0 )
 
646
                                {
648
647
                                        limit->lms_t_soft = -1;
649
648
 
650
649
                                } else {
661
660
                                        limit->lms_t_soft = soft;
662
661
                                }
663
662
                                
664
 
                        } else if ( strncasecmp( arg, "hard=", STRLENOF( "hard=" ) ) == 0 ) {
 
663
                        } else if ( STRSTART( arg, "hard=" ) ) {
665
664
                                arg += STRLENOF( "hard=" );
666
665
                                if ( strcasecmp( arg, "soft" ) == 0 ) {
667
666
                                        limit->lms_t_hard = 0;
668
667
 
669
 
                                } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
668
                                } else if ( strcasecmp( arg, "unlimited" ) == 0
 
669
                                                || strcasecmp( arg, "none" ) == 0 )
 
670
                                {
670
671
                                        limit->lms_t_hard = -1;
671
672
 
672
673
                                } else {
693
694
                        
694
695
                } else if ( arg[0] == '=' ) {
695
696
                        arg++;
696
 
                        if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
697
                        if ( strcasecmp( arg, "unlimited" ) == 0
 
698
                                || strcasecmp( arg, "none" ) == 0 )
 
699
                        {
697
700
                                limit->lms_t_soft = -1;
698
701
 
699
702
                        } else {
709
712
                        return( 1 );
710
713
                }
711
714
 
712
 
        } else if ( strncasecmp( arg, "size", STRLENOF( "size" ) ) == 0 ) {
 
715
        } else if ( STRSTART( arg, "size" ) ) {
713
716
                arg += STRLENOF( "size" );
714
717
                
715
718
                if ( arg[0] == '.' ) {
716
719
                        arg++;
717
 
                        if ( strncasecmp( arg, "soft=", STRLENOF( "soft=" ) ) == 0 ) {
 
720
                        if ( STRSTART( arg, "soft=" ) ) {
718
721
                                arg += STRLENOF( "soft=" );
719
 
                                if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
722
                                if ( strcasecmp( arg, "unlimited" ) == 0
 
723
                                        || strcasecmp( arg, "none" ) == 0 )
 
724
                                {
720
725
                                        limit->lms_s_soft = -1;
721
726
 
722
727
                                } else {
733
738
                                        limit->lms_s_soft = soft;
734
739
                                }
735
740
                                
736
 
                        } else if ( strncasecmp( arg, "hard=", STRLENOF( "hard=" ) ) == 0 ) {
 
741
                        } else if ( STRSTART( arg, "hard=" ) ) {
737
742
                                arg += STRLENOF( "hard=" );
738
743
                                if ( strcasecmp( arg, "soft" ) == 0 ) {
739
744
                                        limit->lms_s_hard = 0;
740
745
 
741
 
                                } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
746
                                } else if ( strcasecmp( arg, "unlimited" ) == 0
 
747
                                                || strcasecmp( arg, "none" ) == 0 )
 
748
                                {
742
749
                                        limit->lms_s_hard = -1;
743
750
 
744
751
                                } else {
759
766
                                        limit->lms_s_hard = hard;
760
767
                                }
761
768
                                
762
 
                        } else if ( strncasecmp( arg, "unchecked=", STRLENOF( "unchecked=" ) ) == 0 ) {
 
769
                        } else if ( STRSTART( arg, "unchecked=" ) ) {
763
770
                                arg += STRLENOF( "unchecked=" );
764
 
                                if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
771
                                if ( strcasecmp( arg, "unlimited" ) == 0
 
772
                                        || strcasecmp( arg, "none" ) == 0 )
 
773
                                {
765
774
                                        limit->lms_s_unchecked = -1;
766
775
 
767
776
                                } else if ( strcasecmp( arg, "disabled" ) == 0 ) {
781
790
                                        limit->lms_s_unchecked = unchecked;
782
791
                                }
783
792
 
784
 
                        } else if ( strncasecmp( arg, "pr=", STRLENOF( "pr=" ) ) == 0 ) {
 
793
                        } else if ( STRSTART( arg, "pr=" ) ) {
785
794
                                arg += STRLENOF( "pr=" );
786
795
                                if ( strcasecmp( arg, "noEstimate" ) == 0 ) {
787
796
                                        limit->lms_s_pr_hide = 1;
788
797
 
789
 
                                } else if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
798
                                } else if ( strcasecmp( arg, "unlimited" ) == 0
 
799
                                                || strcasecmp( arg, "none" ) == 0 )
 
800
                                {
790
801
                                        limit->lms_s_pr = -1;
791
802
 
792
803
                                } else {
803
814
                                        limit->lms_s_pr = pr;
804
815
                                }
805
816
 
806
 
                        } else if ( strncasecmp( arg, "prtotal=", STRLENOF( "prtotal=" ) ) == 0 ) {
 
817
                        } else if ( STRSTART( arg, "prtotal=" ) ) {
807
818
                                arg += STRLENOF( "prtotal=" );
808
819
 
809
 
                                if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
820
                                if ( strcasecmp( arg, "unlimited" ) == 0
 
821
                                        || strcasecmp( arg, "none" ) == 0 )
 
822
                                {
810
823
                                        limit->lms_s_pr_total = -1;
811
824
 
812
825
                                } else if ( strcasecmp( arg, "disabled" ) == 0 ) {
839
852
                        
840
853
                } else if ( arg[0] == '=' ) {
841
854
                        arg++;
842
 
                        if ( strcasecmp( arg, "unlimited" ) == 0 || strcasecmp( arg, "none" ) == 0 ) {
 
855
                        if ( strcasecmp( arg, "unlimited" ) == 0
 
856
                                || strcasecmp( arg, "none" ) == 0 )
 
857
                        {
843
858
                                limit->lms_s_soft = -1;
844
859
 
845
860
                        } else {
859
874
        return 0;
860
875
}
861
876
 
862
 
static const char *lmpats[] = {
863
 
        "base",
864
 
        "base",
865
 
        "onelevel",
866
 
        "subtree",
867
 
        "children",
868
 
        "regex",
869
 
        "anonymous",
870
 
        "users",
871
 
        "*"
872
 
};
873
 
 
874
 
#define WHATSLEFT       ( buflen - ( ptr - bv->bv_val ) )
 
877
/* Helper macros for limits_unparse() and limits_unparse_one():
 
878
 * Write to ptr, but not past bufEnd.  Move ptr past the new text.
 
879
 * Return (success && enough room ? 0 : -1).
 
880
 */
 
881
#define ptr_APPEND_BV(bv) /* Append a \0-terminated berval */ \
 
882
        (WHATSLEFT <= (bv).bv_len ? -1 : \
 
883
         ((void) (ptr = lutil_strcopy( ptr, (bv).bv_val )), 0))
 
884
#define ptr_APPEND_LIT(str) /* Append a string literal */ \
 
885
        (WHATSLEFT <= STRLENOF( "" str "" ) ? -1 : \
 
886
         ((void) (ptr = lutil_strcopy( ptr, str )), 0))
 
887
#define ptr_APPEND_FMT(args) /* Append formatted text */ \
 
888
        (WHATSLEFT <= (tmpLen = snprintf args) ? -1 : ((void) (ptr += tmpLen), 0))
 
889
#define ptr_APPEND_FMT1(fmt, arg) ptr_APPEND_FMT(( ptr, WHATSLEFT, fmt, arg ))
 
890
#define WHATSLEFT ((ber_len_t) (bufEnd - ptr))
875
891
 
876
892
/* Caller must provide an adequately sized buffer in bv */
877
893
int
878
894
limits_unparse( struct slap_limits *lim, struct berval *bv, ber_len_t buflen )
879
895
{
880
896
        struct berval btmp;
881
 
        char *ptr;
882
 
        int lm;
 
897
        char *ptr, *bufEnd;                     /* Updated/used by ptr_APPEND_*()/WHATSLEFT */
 
898
        ber_len_t tmpLen;                       /* Used by ptr_APPEND_FMT*() */
 
899
        unsigned type, style;
 
900
        int rc = 0;
883
901
 
884
902
        if ( !bv || !bv->bv_val ) return -1;
885
903
 
886
904
        ptr = bv->bv_val;
887
 
 
888
 
        if (( lim->lm_flags & SLAP_LIMITS_TYPE_MASK ) == SLAP_LIMITS_TYPE_GROUP ) {
889
 
                if ( WHATSLEFT <= STRLENOF( "group/" "/" "=\"" "\"" )
890
 
                                + lim->lm_group_oc->soc_cname.bv_len
891
 
                                + lim->lm_group_ad->ad_cname.bv_len
892
 
                                + lim->lm_pat.bv_len ) return -1;
893
 
 
894
 
                ptr = lutil_strcopy( ptr, "group/" );
895
 
                ptr = lutil_strcopy( ptr, lim->lm_group_oc->soc_cname.bv_val );
896
 
                *ptr++ = '/';
897
 
                ptr = lutil_strcopy( ptr, lim->lm_group_ad->ad_cname.bv_val );
898
 
                ptr = lutil_strcopy( ptr, "=\"" );
899
 
                ptr = lutil_strcopy( ptr, lim->lm_pat.bv_val );
900
 
                *ptr++ = '"';
 
905
        bufEnd = ptr + buflen;
 
906
        type = lim->lm_flags & SLAP_LIMITS_TYPE_MASK;
 
907
 
 
908
        if ( type == SLAP_LIMITS_TYPE_GROUP ) {
 
909
                rc = ptr_APPEND_FMT(( ptr, WHATSLEFT, "group/%s/%s=\"%s\"",
 
910
                        lim->lm_group_oc->soc_cname.bv_val,
 
911
                        lim->lm_group_ad->ad_cname.bv_val,
 
912
                        lim->lm_pat.bv_val ));
901
913
        } else {
902
 
                lm = lim->lm_flags & SLAP_LIMITS_MASK;
903
 
                switch( lm ) {
 
914
                style = lim->lm_flags & SLAP_LIMITS_MASK;
 
915
                switch( style ) {
904
916
                case SLAP_LIMITS_ANONYMOUS:
905
917
                case SLAP_LIMITS_USERS:
906
918
                case SLAP_LIMITS_ANY:
907
 
                        if ( WHATSLEFT <= strlen( lmpats[lm] ) ) return -1;
908
 
                        ptr = lutil_strcopy( ptr, lmpats[lm] );
 
919
                        rc = ptr_APPEND_BV( lmpats[style] );
909
920
                        break;
910
921
                case SLAP_LIMITS_UNDEFINED:
911
922
                case SLAP_LIMITS_EXACT:
913
924
                case SLAP_LIMITS_SUBTREE:
914
925
                case SLAP_LIMITS_CHILDREN:
915
926
                case SLAP_LIMITS_REGEX:
916
 
                        if ( WHATSLEFT <= STRLENOF( "dn." "=" "\"" "\"" )
917
 
                                        + strlen( lmpats[lm] ) + lim->lm_pat.bv_len ) return -1;
918
 
                        ptr = lutil_strcopy( ptr, "dn." );
919
 
                        ptr = lutil_strcopy( ptr, lmpats[lm] );
920
 
                        *ptr++ = '=';
921
 
                        *ptr++ = '"';
922
 
                        ptr = lutil_strcopy( ptr, lim->lm_pat.bv_val );
923
 
                        *ptr++ = '"';
 
927
                        rc = ptr_APPEND_FMT(( ptr, WHATSLEFT, "dn.%s%s=\"%s\"",
 
928
                                type == SLAP_LIMITS_TYPE_SELF ? "" : "this.",
 
929
                                lmpats[style].bv_val, lim->lm_pat.bv_val ));
924
930
                        break;
925
931
                }
926
932
        }
927
 
        bv->bv_len = ptr - bv->bv_val;
928
 
        btmp.bv_val = ptr;
929
 
        btmp.bv_len = 0;
930
 
        if ( limits_unparse_one( &lim->lm_limits,
931
 
                        SLAP_LIMIT_SIZE|SLAP_LIMIT_TIME,
932
 
                        &btmp, WHATSLEFT ) )
933
 
        {
934
 
                return -1;
 
933
        if ( rc == 0 ) {
 
934
                bv->bv_len = ptr - bv->bv_val;
 
935
                btmp.bv_val = ptr;
 
936
                btmp.bv_len = 0;
 
937
                rc = limits_unparse_one( &lim->lm_limits,
 
938
                        SLAP_LIMIT_SIZE | SLAP_LIMIT_TIME,
 
939
                        &btmp, WHATSLEFT );
 
940
                if ( rc == 0 )
 
941
                        bv->bv_len += btmp.bv_len;
935
942
        }
936
 
        bv->bv_len += btmp.bv_len;
937
 
        return 0;
 
943
        return rc;
938
944
}
939
945
 
940
946
/* Caller must provide an adequately sized buffer in bv */
941
947
int
942
 
limits_unparse_one( struct slap_limits_set *lim, int which, struct berval *bv, ber_len_t buflen )
 
948
limits_unparse_one(
 
949
        struct slap_limits_set  *lim,
 
950
        int                             which,
 
951
        struct berval   *bv,
 
952
        ber_len_t               buflen )
943
953
{
944
 
        char *ptr;
 
954
        char *ptr, *bufEnd;                     /* Updated/used by ptr_APPEND_*()/WHATSLEFT */
 
955
        ber_len_t tmpLen;                       /* Used by ptr_APPEND_FMT*() */
945
956
 
946
957
        if ( !bv || !bv->bv_val ) return -1;
947
958
 
948
959
        ptr = bv->bv_val;
 
960
        bufEnd = ptr + buflen;
949
961
 
950
962
        if ( which & SLAP_LIMIT_SIZE ) {
951
963
                if ( lim->lms_s_soft != SLAPD_DEFAULT_SIZELIMIT ) {
957
969
                                goto s_hard;
958
970
                        /* If there's also a hard limit, fully qualify this one */
959
971
                        } else if ( lim->lms_s_hard ) {
960
 
                                if ( WHATSLEFT <= STRLENOF( " size.soft=" ) ) return -1;
961
 
                                ptr = lutil_strcopy( ptr, " size.soft=" );
 
972
                                if ( ptr_APPEND_LIT( " size.soft=" ) ) return -1;
962
973
 
963
974
                        /* If doing both size & time, qualify this */
964
975
                        } else if ( which & SLAP_LIMIT_TIME ) {
965
 
                                if ( WHATSLEFT <= STRLENOF( " size=" ) ) return -1;
966
 
                                ptr = lutil_strcopy( ptr, " size=" );
 
976
                                if ( ptr_APPEND_LIT( " size=" ) ) return -1;
967
977
                        }
968
978
 
969
 
                        if ( lim->lms_s_soft == -1 ) {
970
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
971
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
972
 
                        } else {
973
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_s_soft );
974
 
                                if ( WHATSLEFT < 0 ) return -1;
975
 
                        }
976
 
                        *ptr++ = ' ';
 
979
                        if ( lim->lms_s_soft == -1
 
980
                                        ? ptr_APPEND_LIT( "unlimited " )
 
981
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_s_soft ) )
 
982
                                return -1;
977
983
                }
978
984
s_hard:
979
985
                if ( lim->lms_s_hard ) {
980
 
                        if ( WHATSLEFT <= STRLENOF( " size.hard=" ) ) return -1;
981
 
                        ptr = lutil_strcopy( ptr, " size.hard=" );
982
 
                        if ( lim->lms_s_hard == -1 ) {
983
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
984
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
985
 
                        } else {
986
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_s_hard );
987
 
                                if ( WHATSLEFT < 0 ) return -1;
988
 
                        }
989
 
                        *ptr++ = ' ';
 
986
                        if ( ptr_APPEND_LIT( " size.hard=" ) ) return -1;
 
987
                        if ( lim->lms_s_hard == -1
 
988
                                        ? ptr_APPEND_LIT( "unlimited " )
 
989
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_s_hard ) )
 
990
                                return -1;
990
991
                }
991
992
                if ( lim->lms_s_unchecked != -1 ) {
992
 
                        if ( WHATSLEFT <= STRLENOF( " size.unchecked=" ) ) return -1;
993
 
                        ptr = lutil_strcopy( ptr, " size.unchecked=" );
994
 
                        if ( lim->lms_s_unchecked == 0 ) {
995
 
                                if ( WHATSLEFT <= STRLENOF( "disabled" ) ) return -1;
996
 
                                ptr = lutil_strcopy( ptr, "disabled" );
997
 
                        } else {
998
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_s_unchecked );
999
 
                                if ( WHATSLEFT < 0 ) return -1;
1000
 
                        }
1001
 
                        *ptr++ = ' ';
 
993
                        if ( ptr_APPEND_LIT( " size.unchecked=" ) ) return -1;
 
994
                        if ( lim->lms_s_unchecked == 0
 
995
                                        ? ptr_APPEND_LIT( "disabled " )
 
996
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_s_unchecked ) )
 
997
                                return -1;
1002
998
                }
1003
999
                if ( lim->lms_s_pr_hide ) {
1004
 
                        if ( WHATSLEFT <= STRLENOF( " size.pr=noEstimate " ) ) return -1;
1005
 
                        ptr = lutil_strcopy( ptr, " size.pr=noEstimate " );
 
1000
                        if ( ptr_APPEND_LIT( " size.pr=noEstimate " ) ) return -1;
1006
1001
                }
1007
1002
                if ( lim->lms_s_pr ) {
1008
 
                        if ( WHATSLEFT <= STRLENOF( " size.pr=" ) ) return -1;
1009
 
                        ptr = lutil_strcopy( ptr, " size.pr=" );
1010
 
                        if ( lim->lms_s_pr == -1 ) {
1011
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
1012
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
1013
 
                        } else {
1014
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_s_pr );
1015
 
                                if ( WHATSLEFT < 0 ) return -1;
1016
 
                        }
1017
 
                        *ptr++ = ' ';
 
1003
                        if ( ptr_APPEND_LIT( " size.pr=" ) ) return -1;
 
1004
                        if ( lim->lms_s_pr == -1
 
1005
                                        ? ptr_APPEND_LIT( "unlimited " )
 
1006
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_s_pr ) )
 
1007
                                return -1;
1018
1008
                }
1019
1009
                if ( lim->lms_s_pr_total ) {
1020
 
                        if ( WHATSLEFT <= STRLENOF( " size.prtotal=" ) ) return -1;
1021
 
                        ptr = lutil_strcopy( ptr, " size.prtotal=" );
1022
 
                        if ( lim->lms_s_pr_total == -1 ) {
1023
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
1024
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
1025
 
                        } else if ( lim->lms_s_pr_total == -2 ) {
1026
 
                                if ( WHATSLEFT <= STRLENOF( "disabled" ) ) return -1;
1027
 
                                ptr = lutil_strcopy( ptr, "disabled" );
1028
 
                        } else {
1029
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_s_pr_total );
1030
 
                                if ( WHATSLEFT < 0 ) return -1;
1031
 
                        }
1032
 
                        *ptr++ = ' ';
 
1010
                        if ( ptr_APPEND_LIT( " size.prtotal=" ) ) return -1;
 
1011
                        if ( lim->lms_s_pr_total  == -1 ? ptr_APPEND_LIT( "unlimited " )
 
1012
                                : lim->lms_s_pr_total == -2 ? ptr_APPEND_LIT( "disabled " )
 
1013
                                : ptr_APPEND_FMT1( "%d ", lim->lms_s_pr_total ) )
 
1014
                                return -1;
1033
1015
                }
1034
1016
        }
1035
1017
 
1044
1026
 
1045
1027
                        /* If there's also a hard limit, fully qualify this one */
1046
1028
                        } else if ( lim->lms_t_hard ) {
1047
 
                                if ( WHATSLEFT <= STRLENOF( " time.soft=" ) ) return -1;
1048
 
                                ptr = lutil_strcopy( ptr, " time.soft=" );
 
1029
                                if ( ptr_APPEND_LIT( " time.soft=" ) ) return -1;
1049
1030
 
1050
1031
                        /* If doing both size & time, qualify this */
1051
1032
                        } else if ( which & SLAP_LIMIT_SIZE ) {
1052
 
                                if ( WHATSLEFT <= STRLENOF( " time=" ) ) return -1;
1053
 
                                ptr = lutil_strcopy( ptr, " time=" );
 
1033
                                if ( ptr_APPEND_LIT( " time=" ) ) return -1;
1054
1034
                        }
1055
1035
 
1056
 
                        if ( lim->lms_t_soft == -1 ) {
1057
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
1058
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
1059
 
                        } else {
1060
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_t_soft );
1061
 
                                if ( WHATSLEFT < 0 ) return -1;
1062
 
                        }
1063
 
                        *ptr++ = ' ';
 
1036
                        if ( lim->lms_t_soft == -1
 
1037
                                        ? ptr_APPEND_LIT( "unlimited " )
 
1038
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_t_soft ) )
 
1039
                                return -1;
1064
1040
                }
1065
1041
t_hard:
1066
1042
                if ( lim->lms_t_hard ) {
1067
 
                        if ( WHATSLEFT <= STRLENOF( " time.hard=" ) ) return -1;
1068
 
                        ptr = lutil_strcopy( ptr, " time.hard=" );
1069
 
                        if ( lim->lms_t_hard == -1 ) {
1070
 
                                if ( WHATSLEFT <= STRLENOF( "unlimited" ) ) return -1;
1071
 
                                ptr = lutil_strcopy( ptr, "unlimited" );
1072
 
                        } else {
1073
 
                                ptr += snprintf( ptr, WHATSLEFT, "%d", lim->lms_t_hard );
1074
 
                                if ( WHATSLEFT < 0 ) return -1;
1075
 
                        }
1076
 
                        *ptr++ = ' ';
 
1043
                        if ( ptr_APPEND_LIT( " time.hard=" ) ) return -1;
 
1044
                        if ( lim->lms_t_hard == -1
 
1045
                                        ? ptr_APPEND_LIT( "unlimited " )
 
1046
                                        : ptr_APPEND_FMT1( "%d ", lim->lms_t_hard ) )
 
1047
                                return -1;
1077
1048
                }
1078
1049
        }
1079
1050
        if ( ptr != bv->bv_val ) {
1132
1103
 
1133
1104
        /* if not root, get appropriate limits */
1134
1105
        } else {
1135
 
                ( void ) limits_get( op, &op->o_ndn, &op->ors_limit );
 
1106
                ( void ) limits_get( op, &op->ors_limit );
1136
1107
 
1137
1108
                assert( op->ors_limit != NULL );
1138
1109
 
1194
1165
                                return -1;
1195
1166
                        }
1196
1167
                        
1197
 
                        if ( op->ors_limit->lms_s_pr > 0 && ps->ps_size > op->ors_limit->lms_s_pr ) {
 
1168
                        if ( op->ors_limit->lms_s_pr > 0
 
1169
                                && ps->ps_size > op->ors_limit->lms_s_pr )
 
1170
                        {
1198
1171
                                rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
1199
1172
                                rs->sr_text = "illegal pagedResults page size";
1200
1173
                                send_ldap_result( op, rs );
1223
1196
 
1224
1197
#ifdef ABOVE_HARD_LIMIT_IS_ERROR
1225
1198
                        } else if ( pr_total > 0 && op->ors_slimit != SLAP_MAX_LIMIT
1226
 
                                        && ( op->ors_slimit == SLAP_NO_LIMIT || op->ors_slimit > pr_total ) )
 
1199
                                        && ( op->ors_slimit == SLAP_NO_LIMIT
 
1200
                                                || op->ors_slimit > pr_total ) )
1227
1201
                        {
1228
1202
                                rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
1229
1203
                                send_ldap_result( op, rs );
1236
1210
                                int     total;
1237
1211
                                int     slimit2;
1238
1212
 
1239
 
                                /* first round of pagedResults: set count to any appropriate limit */
 
1213
                                /* first round of pagedResults:
 
1214
                                 * set count to any appropriate limit */
1240
1215
 
1241
 
                                /* if the limit is set, check that it does not violate any server-side limit */
 
1216
                                /* if the limit is set, check that it does
 
1217
                                 * not violate any server-side limit */
1242
1218
#ifdef ABOVE_HARD_LIMIT_IS_ERROR
1243
 
                                if ( op->ors_slimit == SLAP_MAX_LIMIT ) {
1244
 
                                        slimit2 = op->ors_slimit = pr_total;
 
1219
                                if ( op->ors_slimit == SLAP_MAX_LIMIT )
1245
1220
#else /* ! ABOVE_HARD_LIMIT_IS_ERROR */
1246
 
                                if ( op->ors_slimit == SLAP_MAX_LIMIT || op->ors_slimit > pr_total ) {
1247
 
                                        slimit2 = op->ors_slimit = pr_total;
 
1221
                                if ( op->ors_slimit == SLAP_MAX_LIMIT
 
1222
                                        || op->ors_slimit > pr_total )
1248
1223
#endif /* ! ABOVE_HARD_LIMIT_IS_ERROR */
 
1224
                                {
 
1225
                                        slimit2 = op->ors_slimit = pr_total;
1249
1226
 
1250
1227
                                } else if ( op->ors_slimit == 0 ) {
1251
1228
                                        slimit2 = pr_total;
1264
1241
        
1265
1242
                                                } else {
1266
1243
                                                        /* use the perpage limit if any 
1267
 
                                                         * NOTE: + 1 because the given value must be legal */
 
1244
                                                         * NOTE: + 1 because given value must be legal */
1268
1245
                                                        slimit = op->ors_limit->lms_s_pr + 1;
1269
1246
                                                }
1270
1247
 
1358
1335
        }
1359
1336
 
1360
1337
        for ( i = 0; lm[ i ]; i++ ) {
1361
 
                switch ( lm[ i ]->lm_flags & SLAP_LIMITS_MASK ) {
1362
 
                case SLAP_LIMITS_REGEX:
 
1338
                if ( (lm[ i ]->lm_flags & SLAP_LIMITS_MASK) == SLAP_LIMITS_REGEX )
1363
1339
                        regfree( &lm[ i ]->lm_regex );
1364
 
                        break;
1365
 
 
1366
 
                case SLAP_LIMITS_EXACT:
1367
 
                case SLAP_LIMITS_ONE:
1368
 
                case SLAP_LIMITS_SUBTREE:
1369
 
                case SLAP_LIMITS_CHILDREN:
1370
 
                        if ( !BER_BVISNULL( &lm[ i ]->lm_pat ) ) {
1371
 
                                ch_free( lm[ i ]->lm_pat.bv_val );
1372
 
                        }
1373
 
                        break;
1374
 
 
1375
 
                default:
1376
 
                        break;
1377
 
                }
 
1340
 
 
1341
                if ( !BER_BVISNULL( &lm[ i ]->lm_pat ) )
 
1342
                        ch_free( lm[ i ]->lm_pat.bv_val );
1378
1343
 
1379
1344
                ch_free( lm[ i ] );
1380
1345
        }