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

« back to all changes in this revision

Viewing changes to servers/slapd/overlays/constraint.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
 
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/constraint.c,v 1.2.2.8 2008/05/27 19:59:47 quanah Exp $ */
 
1
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/constraint.c,v 1.2.2.17 2008/11/10 18:24:27 quanah Exp $ */
2
2
/* constraint.c - Overlay to constrain attributes to certain values */
3
3
/* 
4
4
 * Copyright 2003-2004 Hewlett-Packard Company
41
41
 
42
42
#define REGEX_STR "regex"
43
43
#define URI_STR "uri"
 
44
#define SET_STR "set"
44
45
#define SIZE_STR "size"
45
46
#define COUNT_STR "count"
46
47
 
54
55
 
55
56
typedef struct constraint {
56
57
        struct constraint *ap_next;
57
 
        AttributeDescription *ap;
 
58
        AttributeDescription **ap;
 
59
 
 
60
        LDAPURLDesc *restrict_lud;
 
61
        struct berval restrict_ndn;
 
62
        Filter *restrict_filter;
 
63
        struct berval restrict_val;
 
64
 
58
65
        regex_t *re;
59
66
        LDAPURLDesc *lud;
 
67
        int set;
60
68
        size_t size;
61
69
        size_t count;
62
70
        AttributeDescription **attrs;
72
80
static ConfigDriver constraint_cf_gen;
73
81
 
74
82
static ConfigTable constraintcfg[] = {
75
 
        { "constraint_attribute", "attribute> (regex|uri) <value",
76
 
          4, 4, 0, ARG_MAGIC | CONSTRAINT_ATTRIBUTE, constraint_cf_gen,
 
83
        { "constraint_attribute", "attribute[list]> (regex|uri|set|size|count) <value> [<restrict URI>]",
 
84
          4, 0, 0, ARG_MAGIC | CONSTRAINT_ATTRIBUTE, constraint_cf_gen,
77
85
          "( OLcfgOvAt:13.1 NAME 'olcConstraintAttribute' "
78
 
          "DESC 'regular expression constraint for attribute' "
 
86
          "DESC 'constraint for list of attributes' "
79
87
          "EQUALITY caseIgnoreMatch "
80
88
          "SYNTAX OMsDirectoryString )", NULL, NULL },
81
89
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
92
100
};
93
101
 
94
102
static void
95
 
constraint_free( constraint *cp )
 
103
constraint_free( constraint *cp, int freeme )
96
104
{
 
105
        if (cp->restrict_lud)
 
106
                ldap_free_urldesc(cp->restrict_lud);
 
107
        if (!BER_BVISNULL(&cp->restrict_ndn))
 
108
                ch_free(cp->restrict_ndn.bv_val);
 
109
        if (cp->restrict_filter != NULL && cp->restrict_filter != slap_filter_objectClass_pres)
 
110
                filter_free(cp->restrict_filter);
 
111
        if (!BER_BVISNULL(&cp->restrict_val))
 
112
                ch_free(cp->restrict_val.bv_val);
97
113
        if (cp->re) {
98
114
                regfree(cp->re);
99
115
                ch_free(cp->re);
104
120
                ldap_free_urldesc(cp->lud);
105
121
        if (cp->attrs)
106
122
                ch_free(cp->attrs);
107
 
        ch_free(cp);
 
123
        if (cp->ap)
 
124
                ch_free(cp->ap);
 
125
        if (freeme)
 
126
                ch_free(cp);
108
127
}
109
128
 
110
129
static int
114
133
        constraint *cn = on->on_bi.bi_private, *cp;
115
134
        struct berval bv;
116
135
        int i, rc = 0;
117
 
        constraint ap = { NULL, NULL, NULL      }, *a2 = NULL;
 
136
        constraint ap = { NULL };
118
137
        const char *text = NULL;
119
138
        
120
139
        switch ( c->op ) {
122
141
                switch (c->type) {
123
142
                case CONSTRAINT_ATTRIBUTE:
124
143
                        for (cp=cn; cp; cp=cp->ap_next) {
125
 
                                int len;
126
144
                                char *s;
127
145
                                char *tstr = NULL;
128
 
 
129
 
                                len = cp->ap->ad_cname.bv_len + 3;
 
146
                                int quotes = 0;
 
147
                                int j;
 
148
 
 
149
                                bv.bv_len = STRLENOF("  ");
 
150
                                for (j = 0; cp->ap[j]; j++) {
 
151
                                        bv.bv_len += cp->ap[j]->ad_cname.bv_len;
 
152
                                }
 
153
 
 
154
                                /* room for commas */
 
155
                                bv.bv_len += j - 1;
 
156
 
130
157
                                if (cp->re) {
131
 
                                        len += STRLENOF(REGEX_STR);
132
158
                                        tstr = REGEX_STR;
133
159
                                } else if (cp->lud) {
134
 
                                        len += STRLENOF(URI_STR);
135
160
                                        tstr = URI_STR;
 
161
                                        quotes = 1;
 
162
                                } else if (cp->set) {
 
163
                                        tstr = SET_STR;
 
164
                                        quotes = 1;
136
165
                                } else if (cp->size) {
137
 
                                        len += STRLENOF(SIZE_STR);
138
166
                                        tstr = SIZE_STR;
139
167
                                } else if (cp->count) {
140
 
                                        len += STRLENOF(COUNT_STR);
141
168
                                        tstr = COUNT_STR;
142
169
                                }
143
 
                                len += cp->val.bv_len;
144
 
 
145
 
                                s = ch_malloc(len);
146
 
 
147
 
                                bv.bv_len = snprintf(s, len, "%s %s %s", cp->ap->ad_cname.bv_val,
148
 
                                                 tstr, cp->val.bv_val);
149
 
                                bv.bv_val = s;
 
170
 
 
171
                                bv.bv_len += strlen(tstr);
 
172
                                bv.bv_len += cp->val.bv_len + 2*quotes;
 
173
 
 
174
                                if (cp->restrict_lud != NULL) {
 
175
                                        bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\"");
 
176
                                }
 
177
 
 
178
                                s = bv.bv_val = ch_malloc(bv.bv_len + 1);
 
179
 
 
180
                                s = lutil_strncopy( s, cp->ap[0]->ad_cname.bv_val, cp->ap[0]->ad_cname.bv_len );
 
181
                                for (j = 1; cp->ap[j]; j++) {
 
182
                                        *s++ = ',';
 
183
                                        s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len );
 
184
                                }
 
185
                                *s++ = ' ';
 
186
                                s = lutil_strcopy( s, tstr );
 
187
                                *s++ = ' ';
 
188
                                if ( quotes ) *s++ = '"';
 
189
                                s = lutil_strncopy( s, cp->val.bv_val, cp->val.bv_len );
 
190
                                if ( quotes ) *s++ = '"';
 
191
                                if (cp->restrict_lud != NULL) {
 
192
                                        s = lutil_strcopy( s, " restrict=\"" );
 
193
                                        s = lutil_strncopy( s, cp->restrict_val.bv_val, cp->restrict_val.bv_len );
 
194
                                        *s++ = '"';
 
195
                                }
 
196
                                *s = '\0';
 
197
 
150
198
                                rc = value_add_one( &c->rvalue_vals, &bv );
151
 
                                if (rc) return rc;
152
 
                                rc = value_add_one( &c->rvalue_nvals, &bv );
153
 
                                if (rc) return rc;
154
 
                                ch_free(s);
 
199
                                if (rc == LDAP_SUCCESS)
 
200
                                        rc = value_add_one( &c->rvalue_nvals, &bv );
 
201
                                ch_free(bv.bv_val);
 
202
                                if (rc) return rc;
155
203
                        }
156
204
                        break;
157
205
                default:
168
216
                                /* zap all constraints */
169
217
                                while (cn) {
170
218
                                        cp = cn->ap_next;
171
 
                                        constraint_free( cn );
 
219
                                        constraint_free( cn, 1 );
172
220
                                        cn = cp;
173
221
                                }
174
222
                                                
184
232
                                if (cp) {
185
233
                                        /* zap cp, and join cpp to cp->ap_next */
186
234
                                        *cpp = cp->ap_next;
187
 
                                        constraint_free( cp );
 
235
                                        constraint_free( cp, 1 );
188
236
                                }
189
237
                                on->on_bi.bi_private = cn;
190
238
                        }
198
246
        case SLAP_CONFIG_ADD:
199
247
        case LDAP_MOD_ADD:
200
248
                switch (c->type) {
201
 
                case CONSTRAINT_ATTRIBUTE:
202
 
                        if ( slap_str2ad( c->argv[1], &ap.ap, &text ) ) {
203
 
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
204
 
                                        "%s <%s>: %s\n", c->argv[0], c->argv[1], text );
205
 
                                Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
206
 
                                           "%s: %s\n", c->log, c->cr_msg, 0 );
207
 
                                return( ARG_BAD_CONF );
 
249
                case CONSTRAINT_ATTRIBUTE: {
 
250
                        int j;
 
251
                        char **attrs = ldap_str2charray( c->argv[1], "," );
 
252
 
 
253
                        for ( j = 0; attrs[j]; j++)
 
254
                                /* just count */ ;
 
255
                        ap.ap = ch_calloc( sizeof(AttributeDescription*), j + 1 );
 
256
                        for ( j = 0; attrs[j]; j++) {
 
257
                                if ( slap_str2ad( attrs[j], &ap.ap[j], &text ) ) {
 
258
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
259
                                                "%s <%s>: %s\n", c->argv[0], attrs[j], text );
 
260
                                        rc = ARG_BAD_CONF;
 
261
                                        goto done;
 
262
                                }
208
263
                        }
209
264
 
210
265
                        if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) {
218
273
                                        regerror( err, ap.re, errmsg, sizeof(errmsg) );
219
274
                                        ch_free(ap.re);
220
275
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
221
 
                                           "%s %s: Illegal regular expression \"%s\": Error %s",
222
 
                                           c->argv[0], c->argv[1], c->argv[3], errmsg);
223
 
                                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
224
 
                                                "%s: %s\n", c->log, c->cr_msg, 0 );
 
276
                                                "%s %s: Illegal regular expression \"%s\": Error %s",
 
277
                                                c->argv[0], c->argv[1], c->argv[3], errmsg);
225
278
                                        ap.re = NULL;
226
 
                                        return( ARG_BAD_CONF );
 
279
                                        rc = ARG_BAD_CONF;
 
280
                                        goto done;
227
281
                                }
228
282
                                ber_str2bv( c->argv[3], 0, 1, &ap.val );
229
283
                        } else if ( strcasecmp( c->argv[2], SIZE_STR ) == 0 ) {
244
298
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
245
299
                                                "%s %s: Invalid URI \"%s\"",
246
300
                                                c->argv[0], c->argv[1], c->argv[3]);
247
 
                                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
248
 
                                                "%s: %s\n", c->log, c->cr_msg, 0 );
249
 
                                        return( ARG_BAD_CONF );
 
301
                                        rc = ARG_BAD_CONF;
 
302
                                        goto done;
250
303
                                }
251
304
 
252
305
                                if (ap.lud->lud_host != NULL) {
253
306
                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
254
307
                                                "%s %s: unsupported hostname in URI \"%s\"",
255
308
                                                c->argv[0], c->argv[1], c->argv[3]);
256
 
                                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
257
 
                                                "%s: %s\n", c->log, c->cr_msg, 0 );
258
 
 
259
309
                                        ldap_free_urldesc(ap.lud);
260
 
 
261
 
                                        return( ARG_BAD_CONF );
 
310
                                        rc = ARG_BAD_CONF;
 
311
                                        goto done;
262
312
                                }
263
313
 
264
314
                                for ( i=0; ap.lud->lud_attrs[i]; i++);
271
321
                                                        ch_free( ap.attrs );
272
322
                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
273
323
                                                                "%s <%s>: %s\n", c->argv[0], ap.lud->lud_attrs[i], text );
274
 
                                                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
275
 
                                                                   "%s: %s\n", c->log, c->cr_msg, 0 );
276
 
                                                        return( ARG_BAD_CONF );
 
324
                                                        rc = ARG_BAD_CONF;
 
325
                                                        goto done;
277
326
                                                }
278
327
                                        }
279
328
                                        ap.attrs[i] = NULL;
280
329
                                }
281
330
 
282
 
                                if (ap.lud->lud_dn == NULL)
 
331
                                if (ap.lud->lud_dn == NULL) {
283
332
                                        ap.lud->lud_dn = ch_strdup("");
284
 
 
285
 
                                if (ap.lud->lud_filter == NULL)
 
333
                                } else {
 
334
                                        struct berval dn, ndn;
 
335
 
 
336
                                        ber_str2bv( ap.lud->lud_dn, 0, 0, &dn );
 
337
                                        if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) {
 
338
                                                /* cleanup */
 
339
                                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
340
                                                        "%s %s: URI %s DN normalization failed",
 
341
                                                        c->argv[0], c->argv[1], c->argv[3] );
 
342
                                                Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
 
343
                                                           "%s: %s\n", c->log, c->cr_msg, 0 );
 
344
                                                rc = ARG_BAD_CONF;
 
345
                                                goto done;
 
346
                                        }
 
347
                                        ldap_memfree( ap.lud->lud_dn );
 
348
                                        ap.lud->lud_dn = ndn.bv_val;
 
349
                                }
 
350
 
 
351
                                if (ap.lud->lud_filter == NULL) {
286
352
                                        ap.lud->lud_filter = ch_strdup("objectClass=*");
287
 
 
288
 
                                ber_str2bv( c->argv[3], 0, 1, &ap.val );
 
353
                                } else if ( ap.lud->lud_filter[0] == '(' ) {
 
354
                                        ber_len_t len = strlen( ap.lud->lud_filter );
 
355
                                        if ( ap.lud->lud_filter[len - 1] != ')' ) {
 
356
                                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
357
                                                        "%s %s: invalid URI filter: %s",
 
358
                                                        c->argv[0], c->argv[1], ap.lud->lud_filter );
 
359
                                                rc = ARG_BAD_CONF;
 
360
                                                goto done;
 
361
                                        }
 
362
                                        AC_MEMCPY( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 );
 
363
                                        ap.lud->lud_filter[len - 2] = '\0';
 
364
                                }
 
365
 
 
366
                                ber_str2bv( c->argv[3], 0, 1, &ap.val );
 
367
 
 
368
                        } else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) {
 
369
                                ap.set = 1;
 
370
                                ber_str2bv( c->argv[3], 0, 1, &ap.val );
 
371
 
289
372
                        } else {
290
373
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
291
 
                                   "%s %s: Unknown constraint type: %s",
292
 
                                   c->argv[0], c->argv[1], c->argv[2] );
 
374
                                        "%s %s: Unknown constraint type: %s",
 
375
                                        c->argv[0], c->argv[1], c->argv[2] );
 
376
                                rc = ARG_BAD_CONF;
 
377
                                goto done;
 
378
                        }
 
379
 
 
380
                        if ( c->argc > 4 ) {
 
381
                                int argidx;
 
382
 
 
383
                                for ( argidx = 4; argidx < c->argc; argidx++ ) {
 
384
                                        if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) {
 
385
                                                int err;
 
386
                                                char *arg = c->argv[argidx] + STRLENOF("restrict=");
 
387
 
 
388
                                                err = ldap_url_parse(arg, &ap.restrict_lud);
 
389
                                                if ( err != LDAP_URL_SUCCESS ) {
 
390
                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
391
                                                                "%s %s: Invalid restrict URI \"%s\"",
 
392
                                                                c->argv[0], c->argv[1], arg);
 
393
                                                        rc = ARG_BAD_CONF;
 
394
                                                        goto done;
 
395
                                                }
 
396
 
 
397
                                                if (ap.restrict_lud->lud_host != NULL) {
 
398
                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
399
                                                                "%s %s: unsupported hostname in restrict URI \"%s\"",
 
400
                                                                c->argv[0], c->argv[1], arg);
 
401
                                                        rc = ARG_BAD_CONF;
 
402
                                                        goto done;
 
403
                                                }
 
404
 
 
405
                                                if ( ap.restrict_lud->lud_attrs != NULL ) {
 
406
                                                        if ( ap.restrict_lud->lud_attrs[0] != '\0' ) {
 
407
                                                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
408
                                                                        "%s %s: attrs not allowed in restrict URI %s\n",
 
409
                                                                        c->argv[0], c->argv[1], arg);
 
410
                                                                rc = ARG_BAD_CONF;
 
411
                                                                goto done;
 
412
                                                        }
 
413
                                                        ldap_memvfree((void *)ap.restrict_lud->lud_attrs);
 
414
                                                        ap.restrict_lud->lud_attrs = NULL;
 
415
                                                }
 
416
 
 
417
                                                if (ap.restrict_lud->lud_dn != NULL) {
 
418
                                                        if (ap.restrict_lud->lud_dn[0] == '\0') {
 
419
                                                                ldap_memfree(ap.restrict_lud->lud_dn);
 
420
                                                                ap.restrict_lud->lud_dn = NULL;
 
421
 
 
422
                                                        } else {
 
423
                                                                struct berval dn, ndn;
 
424
                                                                int j;
 
425
 
 
426
                                                                ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn);
 
427
                                                                if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) {
 
428
                                                                        /* cleanup */
 
429
                                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
430
                                                                                "%s %s: restrict URI %s DN normalization failed",
 
431
                                                                                c->argv[0], c->argv[1], arg );
 
432
                                                                        rc = ARG_BAD_CONF;
 
433
                                                                        goto done;
 
434
                                                                }
 
435
 
 
436
                                                                assert(c->be != NULL);
 
437
                                                                if (c->be->be_nsuffix == NULL) {
 
438
                                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
439
                                                                                "%s %s: restrict URI requires suffix",
 
440
                                                                                c->argv[0], c->argv[1] );
 
441
                                                                        rc = ARG_BAD_CONF;
 
442
                                                                        goto done;
 
443
                                                                }
 
444
 
 
445
                                                                for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) {
 
446
                                                                        if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break;
 
447
                                                                }
 
448
 
 
449
                                                                if (BER_BVISNULL(&c->be->be_nsuffix[j])) {
 
450
                                                                        /* error */
 
451
                                                                        snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
452
                                                                                "%s %s: restrict URI DN %s not within database naming context(s)",
 
453
                                                                                c->argv[0], c->argv[1], dn.bv_val );
 
454
                                                                        rc = ARG_BAD_CONF;
 
455
                                                                        goto done;
 
456
                                                                }
 
457
 
 
458
                                                                ap.restrict_ndn = ndn;
 
459
                                                        }
 
460
                                                }
 
461
 
 
462
                                                if (ap.restrict_lud->lud_filter != NULL) {
 
463
                                                        ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter);
 
464
                                                        if (ap.restrict_filter == NULL) {
 
465
                                                                /* error */
 
466
                                                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
467
                                                                        "%s %s: restrict URI filter %s invalid",
 
468
                                                                        c->argv[0], c->argv[1], ap.restrict_lud->lud_filter );
 
469
                                                                rc = ARG_BAD_CONF;
 
470
                                                                goto done;
 
471
                                                        }
 
472
                                                }
 
473
 
 
474
                                                ber_str2bv(c->argv[argidx], 0, 1, &ap.restrict_val);
 
475
 
 
476
                                        } else {
 
477
                                                /* cleanup */
 
478
                                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
 
479
                                                        "%s %s: unrecognized arg #%d (%s)",
 
480
                                                        c->argv[0], c->argv[1], argidx, c->argv[argidx] );
 
481
                                                rc = ARG_BAD_CONF;
 
482
                                                goto done;
 
483
                                        }
 
484
                                }
 
485
                        }
 
486
 
 
487
done:;
 
488
                        if ( rc == LDAP_SUCCESS ) {
 
489
                                constraint *a2 = ch_calloc( sizeof(constraint), 1 );
 
490
                                a2->ap_next = on->on_bi.bi_private;
 
491
                                a2->ap = ap.ap;
 
492
                                a2->re = ap.re;
 
493
                                a2->val = ap.val;
 
494
                                a2->lud = ap.lud;
 
495
                                a2->set = ap.set;
 
496
                                a2->size = ap.size;
 
497
                                a2->count = ap.count;
 
498
                                if ( a2->lud ) {
 
499
                                        ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn);
 
500
                                        ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter);
 
501
                                }
 
502
                                a2->attrs = ap.attrs;
 
503
                                a2->restrict_lud = ap.restrict_lud;
 
504
                                a2->restrict_ndn = ap.restrict_ndn;
 
505
                                a2->restrict_filter = ap.restrict_filter;
 
506
                                a2->restrict_val = ap.restrict_val;
 
507
                                on->on_bi.bi_private = a2;
 
508
 
 
509
                        } else {
293
510
                                Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
294
 
                                   "%s: %s\n", c->log, c->cr_msg, 0 );
295
 
                                return ( ARG_BAD_CONF );
 
511
                                           "%s: %s\n", c->log, c->cr_msg, 0 );
 
512
                                constraint_free( &ap, 0 );
296
513
                        }
297
514
 
298
 
                        a2 = ch_calloc( sizeof(constraint), 1 );
299
 
                        a2->ap_next = on->on_bi.bi_private;
300
 
                        a2->ap = ap.ap;
301
 
                        a2->re = ap.re;
302
 
                        a2->val = ap.val;
303
 
                        a2->lud = ap.lud;
304
 
                        a2->size = ap.size;
305
 
                        a2->count = ap.count;
306
 
                        if ( a2->lud ) {
307
 
                                ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn);
308
 
                                ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter);
309
 
                        }
310
 
                        a2->attrs = ap.attrs;
311
 
                        on->on_bi.bi_private = a2;
312
 
                        break;
 
515
                        ldap_memvfree((void**)attrs);
 
516
                        } break;
313
517
                default:
314
518
                        abort();
315
519
                        break;
339
543
static int
340
544
constraint_violation( constraint *c, struct berval *bv, Operation *op, SlapReply *rs)
341
545
{
342
 
        if ((!c) || (!bv)) return 0;
 
546
        if ((!c) || (!bv)) return LDAP_SUCCESS;
343
547
        
344
548
        if ((c->re) &&
345
549
                (regexec(c->re, bv->bv_val, 0, NULL, 0) == REG_NOMATCH))
346
 
                return 1; /* regular expression violation */
 
550
                return LDAP_CONSTRAINT_VIOLATION; /* regular expression violation */
347
551
 
348
552
        if ((c->size) && (bv->bv_len > c->size))
349
 
                return 1; /* size violation */
 
553
                return LDAP_CONSTRAINT_VIOLATION; /* size violation */
350
554
 
351
555
        if (c->lud) {
352
556
                Operation nop = *op;
380
584
                        nop.o_req_dn = dn;
381
585
                        nop.o_req_ndn = dn;
382
586
                        nop.o_bd = select_backend(&nop.o_req_ndn, 1 );
383
 
                        if (!nop.o_bd || !nop.o_bd->be_search) {
384
 
                                return 1; /* unexpected error */
 
587
                        if (!nop.o_bd) {
 
588
                                return LDAP_NO_SUCH_OBJECT; /* unexpected error */
 
589
                        }
 
590
                        if (!nop.o_bd->be_search) {
 
591
                                return LDAP_OTHER; /* unexpected error */
385
592
                        }
386
593
                } else {
387
594
                        nop.o_req_dn = nop.o_bd->be_nsuffix[0];
427
634
                }
428
635
                *ptr++ = ')';
429
636
                *ptr++ = ')';
430
 
 
431
 
                Debug(LDAP_DEBUG_TRACE, 
432
 
                        "==> constraint_violation uri filter = %s\n",
433
 
                        filterstr.bv_val, 0, 0);
 
637
                *ptr++ = '\0';
434
638
 
435
639
                nop.ors_filterstr = filterstr;
436
640
                nop.ors_filter = str2filter_x(&nop, filterstr.bv_val);
437
 
 
438
 
                rc = nop.o_bd->be_search( &nop, &nrs );
 
641
                if ( nop.ors_filter == NULL ) {
 
642
                        Debug( LDAP_DEBUG_ANY,
 
643
                                "%s constraint_violation uri filter=\"%s\" invalid\n",
 
644
                                op->o_log_prefix, filterstr.bv_val, 0 );
 
645
                        rc = LDAP_OTHER;
 
646
 
 
647
                } else {
 
648
                        Debug(LDAP_DEBUG_TRACE, 
 
649
                                "==> constraint_violation uri filter = %s\n",
 
650
                                filterstr.bv_val, 0, 0);
 
651
 
 
652
                        rc = nop.o_bd->be_search( &nop, &nrs );
439
653
                
 
654
                        Debug(LDAP_DEBUG_TRACE, 
 
655
                                "==> constraint_violation uri rc = %d, found = %d\n",
 
656
                                rc, found, 0);
 
657
                }
440
658
                op->o_tmpfree(filterstr.bv_val, op->o_tmpmemctx);
441
 
                Debug(LDAP_DEBUG_TRACE, 
442
 
                        "==> constraint_violation uri rc = %d, found = %d\n",
443
 
                        rc, found, 0);
444
659
 
445
 
                if((rc != LDAP_SUCCESS) && (rc != LDAP_NO_SUCH_OBJECT)) {
446
 
                        send_ldap_error(op, rs, rc, 
447
 
                                "constraint_violation uri search failed");
448
 
                        return 1; /* unexpected error */
 
660
                if ((rc != LDAP_SUCCESS) && (rc != LDAP_NO_SUCH_OBJECT)) {
 
661
                        return rc; /* unexpected error */
449
662
                }
450
663
 
451
664
                if (!found)
452
 
                        return 1; /* constraint violation */
 
665
                        return LDAP_CONSTRAINT_VIOLATION; /* constraint violation */
453
666
                        
454
667
        }
455
 
        
456
 
        return 0;
 
668
 
 
669
        return LDAP_SUCCESS;
457
670
}
458
671
 
459
672
static char *
479
692
}
480
693
 
481
694
static int
 
695
constraint_check_restrict( Operation *op, constraint *c, Entry *e )
 
696
{
 
697
        assert( c->restrict_lud != NULL );
 
698
 
 
699
        if ( c->restrict_lud->lud_dn != NULL ) {
 
700
                int diff = e->e_nname.bv_len - c->restrict_ndn.bv_len;
 
701
 
 
702
                if ( diff < 0 ) {
 
703
                        return 0;
 
704
                }
 
705
 
 
706
                if ( c->restrict_lud->lud_scope == LDAP_SCOPE_BASE ) {
 
707
                        return bvmatch( &e->e_nname, &c->restrict_ndn );
 
708
                }
 
709
 
 
710
                if ( !dnIsSuffix( &e->e_nname, &c->restrict_ndn ) ) {
 
711
                        return 0;
 
712
                }
 
713
 
 
714
                if ( c->restrict_lud->lud_scope != LDAP_SCOPE_SUBTREE ) {
 
715
                        struct berval pdn;
 
716
 
 
717
                        if ( diff == 0 ) {
 
718
                                return 0;
 
719
                        }
 
720
 
 
721
                        dnParent( &e->e_nname, &pdn );
 
722
 
 
723
                        if ( c->restrict_lud->lud_scope == LDAP_SCOPE_ONELEVEL
 
724
                                && pdn.bv_len != c->restrict_ndn.bv_len )
 
725
                        {
 
726
                                return 0;
 
727
                        }
 
728
                }
 
729
        }
 
730
 
 
731
        if ( c->restrict_filter != NULL ) {
 
732
                int rc;
 
733
                struct berval save_dn = op->o_dn, save_ndn = op->o_ndn;
 
734
 
 
735
                op->o_dn = op->o_bd->be_rootdn;
 
736
                op->o_ndn = op->o_bd->be_rootndn;
 
737
                rc = test_filter( op, e, c->restrict_filter );
 
738
                op->o_dn = save_dn;
 
739
                op->o_ndn = save_ndn;
 
740
 
 
741
                if ( rc != LDAP_COMPARE_TRUE ) {
 
742
                        return 0;
 
743
                }
 
744
        }
 
745
 
 
746
        return 1;
 
747
}
 
748
 
 
749
static int
482
750
constraint_add( Operation *op, SlapReply *rs )
483
751
{
484
752
        slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
485
 
        Backend *be = op->o_bd;
486
753
        Attribute *a;
487
754
        constraint *c = on->on_bi.bi_private, *cp;
488
755
        BerVarray b = NULL;
489
756
        int i;
490
757
        struct berval rsv = BER_BVC("add breaks constraint");
491
 
        char *msg;
 
758
        int rc;
 
759
        char *msg = NULL;
 
760
 
 
761
        if (get_relax(op)) {
 
762
                return SLAP_CB_CONTINUE;
 
763
        }
492
764
 
493
765
        if ((a = op->ora_e->e_attrs) == NULL) {
494
766
                op->o_bd->bd_info = (BackendInfo *)(on->on_info);
495
767
                send_ldap_error(op, rs, LDAP_INVALID_SYNTAX,
496
 
                        "constraint_add() got null op.ora_e.e_attrs");
 
768
                        "constraint_add: no attrs");
497
769
                return(rs->sr_err);
498
770
        }
499
771
 
502
774
                if (is_at_operational(a->a_desc->ad_type)) continue;
503
775
 
504
776
                for(cp = c; cp; cp = cp->ap_next) {
505
 
                        if (cp->ap != a->a_desc) continue;
 
777
                        int j;
 
778
                        for (j = 0; cp->ap[j]; j++) {
 
779
                                if (cp->ap[j] == a->a_desc) break;
 
780
                        }
 
781
                        if (cp->ap[j] == NULL) continue;
506
782
                        if ((b = a->a_vals) == NULL) continue;
507
 
                                
 
783
 
 
784
                        if (cp->restrict_lud != NULL && constraint_check_restrict(op, cp, op->ora_e) == 0) {
 
785
                                continue;
 
786
                        }
 
787
 
508
788
                        Debug(LDAP_DEBUG_TRACE, 
509
789
                                "==> constraint_add, "
510
 
                                "a->a_numvals = %d, cp->count = %d\n",
511
 
                                a->a_numvals, cp->count, 0);
 
790
                                "a->a_numvals = %u, cp->count = %lu\n",
 
791
                                a->a_numvals, (unsigned long) cp->count, 0);
512
792
 
513
 
                        if ((cp->count != 0) && (a->a_numvals > cp->count))
 
793
                        if ((cp->count != 0) && (a->a_numvals > cp->count)) {
 
794
                                rc = LDAP_CONSTRAINT_VIOLATION;
514
795
                                goto add_violation;
 
796
                        }
515
797
 
516
 
                        for(i=0; b[i].bv_val; i++) 
517
 
                                if (constraint_violation( cp, &b[i], op, rs))
 
798
                        for ( i = 0; b[i].bv_val; i++ ) {
 
799
                                rc = constraint_violation( cp, &b[i], op, rs );
 
800
                                if ( rc ) {
518
801
                                        goto add_violation;
 
802
                                }
 
803
                        }
 
804
 
 
805
                        if (cp->set && acl_match_set(&cp->val, op, op->ora_e, NULL) == 0) {
 
806
                                rc = LDAP_CONSTRAINT_VIOLATION;
 
807
                                goto add_violation; /* constraint violation */
 
808
                        }
 
809
 
519
810
                }
520
811
        }
 
812
 
521
813
        /* Default is to just fall through to the normal processing */
522
814
        return SLAP_CB_CONTINUE;
523
815
 
524
816
add_violation:
525
817
        op->o_bd->bd_info = (BackendInfo *)(on->on_info);
526
 
        msg = print_message( &rsv, a->a_desc );
527
 
        send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION, msg );
 
818
        if (rc == LDAP_CONSTRAINT_VIOLATION ) {
 
819
                msg = print_message( &rsv, a->a_desc );
 
820
        }
 
821
        send_ldap_error(op, rs, rc, msg );
528
822
        ch_free(msg);
529
823
        return (rs->sr_err);
530
824
}
531
825
 
532
826
 
533
827
static int
534
 
constraint_modify( Operation *op, SlapReply *rs )
 
828
constraint_update( Operation *op, SlapReply *rs )
535
829
{
536
830
        slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
537
831
        Backend *be = op->o_bd;
538
832
        constraint *c = on->on_bi.bi_private, *cp;
539
 
        Entry *target_entry = NULL;
540
 
        Modifications *m;
 
833
        Entry *target_entry = NULL, *target_entry_copy = NULL;
 
834
        Modifications *modlist, *m;
541
835
        BerVarray b = NULL;
542
836
        int i;
543
837
        struct berval rsv = BER_BVC("modify breaks constraint");
544
 
        char *msg;
 
838
        int rc;
 
839
        char *msg = NULL;
 
840
 
 
841
        if (get_relax(op)) {
 
842
                return SLAP_CB_CONTINUE;
 
843
        }
 
844
 
 
845
        switch ( op->o_tag ) {
 
846
        case LDAP_REQ_MODIFY:
 
847
                modlist = op->orm_modlist;
 
848
                break;
 
849
 
 
850
        case LDAP_REQ_MODRDN:
 
851
                modlist = op->orr_modlist;
 
852
                break;
 
853
 
 
854
        default:
 
855
                /* impossible! assert? */
 
856
                return LDAP_OTHER;
 
857
        }
545
858
        
546
 
        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "constraint_modify()", 0,0,0);
547
 
        if ((m = op->orm_modlist) == NULL) {
 
859
        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "constraint_update()\n", 0,0,0);
 
860
        if ((m = modlist) == NULL) {
548
861
                op->o_bd->bd_info = (BackendInfo *)(on->on_info);
549
862
                send_ldap_error(op, rs, LDAP_INVALID_SYNTAX,
550
 
                                                "constraint_modify() got null orm_modlist");
 
863
                                                "constraint_update() got null modlist");
551
864
                return(rs->sr_err);
552
865
        }
553
866
 
554
867
        /* Do we need to count attributes? */
555
868
        for(cp = c; cp; cp = cp->ap_next) {
556
 
                if (cp->count != 0) {
557
 
                        int rc;
558
 
 
 
869
                if (cp->count != 0 || cp->set || cp->restrict_lud != 0) {
559
870
                        op->o_bd = on->on_info->oi_origdb;
560
871
                        rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &target_entry );
561
872
                        op->o_bd = be;
562
873
 
563
874
                        if (rc != 0 || target_entry == NULL) {
564
875
                                Debug(LDAP_DEBUG_TRACE, 
565
 
                                        "==> constraint_modify rc = %d\n",
566
 
                                        rc, 0, 0);
 
876
                                        "==> constraint_update rc = %d DN=\"%s\"%s\n",
 
877
                                        rc, op->o_req_ndn.bv_val,
 
878
                                        target_entry ? "" : " not found" );
 
879
                                if ( rc == 0 ) 
 
880
                                        rc = LDAP_CONSTRAINT_VIOLATION;
567
881
                                goto mod_violation;
568
882
                        }
569
883
                        break;
570
884
                }
571
885
        }
572
 
                
 
886
 
 
887
        rc = LDAP_CONSTRAINT_VIOLATION;
573
888
        for(;m; m = m->sml_next) {
574
 
                int ce = 0;
575
 
 
576
 
                /* Get this attribute count, if needed */
577
 
                if (target_entry)
578
 
                        ce = constraint_count_attr(target_entry, m->sml_desc);
 
889
                unsigned ce = 0;
579
890
 
580
891
                if (is_at_operational( m->sml_desc->ad_type )) continue;
 
892
 
581
893
                if ((( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_ADD) &&
582
894
                        (( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_REPLACE) &&
583
895
                        (( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_DELETE))
587
899
                if ((( b = m->sml_values ) == NULL ) || (b[0].bv_val == NULL))
588
900
                        continue;
589
901
 
 
902
                /* Get this attribute count, if needed */
 
903
                if (target_entry)
 
904
                        ce = constraint_count_attr(target_entry, m->sml_desc);
 
905
 
590
906
                for(cp = c; cp; cp = cp->ap_next) {
591
 
                        if (cp->ap != m->sml_desc) continue;
592
 
                        
 
907
                        int j;
 
908
                        for (j = 0; cp->ap[j]; j++) {
 
909
                                if (cp->ap[j] == m->sml_desc) {
 
910
                                        break;
 
911
                                }
 
912
                        }
 
913
                        if (cp->ap[j] == NULL) continue;
 
914
 
 
915
                        if (cp->restrict_lud != NULL && constraint_check_restrict(op, cp, target_entry) == 0) {
 
916
                                continue;
 
917
                        }
 
918
 
593
919
                        if (cp->count != 0) {
594
 
                                int ca;
 
920
                                unsigned ca;
595
921
 
596
922
                                if (m->sml_op == LDAP_MOD_DELETE)
597
923
                                        ce = 0;
599
925
                                for (ca = 0; b[ca].bv_val; ++ca);
600
926
 
601
927
                                Debug(LDAP_DEBUG_TRACE, 
602
 
                                        "==> constraint_modify ce = %d, "
603
 
                                        "ca = %d, cp->count = %d\n",
604
 
                                        ce, ca, cp->count);
 
928
                                        "==> constraint_update ce = %u, "
 
929
                                        "ca = %u, cp->count = %lu\n",
 
930
                                        ce, ca, (unsigned long) cp->count);
605
931
 
606
 
                                if (m->sml_op == LDAP_MOD_ADD)
607
 
                                        if (ca + ce > cp->count)
 
932
                                if (m->sml_op == LDAP_MOD_ADD) {
 
933
                                        if (ca + ce > cp->count) {
 
934
                                                rc = LDAP_CONSTRAINT_VIOLATION;
608
935
                                                goto mod_violation;
 
936
                                        }
 
937
                                }
609
938
                                if (m->sml_op == LDAP_MOD_REPLACE) {
610
 
                                        if (ca > cp->count)
 
939
                                        if (ca > cp->count) {
 
940
                                                rc = LDAP_CONSTRAINT_VIOLATION;
611
941
                                                goto mod_violation;
 
942
                                        }
612
943
                                        ce = ca;
613
944
                                }
614
945
                        } 
617
948
                        if (( m->sml_op & LDAP_MOD_OP ) == LDAP_MOD_DELETE)
618
949
                                continue;
619
950
 
620
 
                        for(i=0; b[i].bv_val; i++)
621
 
                                if (constraint_violation( cp, &b[i], op, rs))
622
 
                                        goto mod_violation;
 
951
                        for ( i = 0; b[i].bv_val; i++ ) {
 
952
                                rc = constraint_violation( cp, &b[i], op, rs );
 
953
                                if ( rc ) {
 
954
                                        goto mod_violation;
 
955
                                }
 
956
                        }
 
957
 
 
958
                        if (cp->set && target_entry) {
 
959
                                if (target_entry_copy == NULL) {
 
960
                                        Modifications *ml;
 
961
 
 
962
                                        target_entry_copy = entry_dup(target_entry);
 
963
 
 
964
                                        /* if rename, set the new entry's name
 
965
                                         * (in normalized form only) */
 
966
                                        if ( op->o_tag == LDAP_REQ_MODRDN ) {
 
967
                                                struct berval pdn, ndn = BER_BVNULL;
 
968
 
 
969
                                                if ( op->orr_nnewSup ) {
 
970
                                                        pdn = *op->orr_nnewSup;
 
971
 
 
972
                                                } else {
 
973
                                                        dnParent( &target_entry_copy->e_nname, &pdn );
 
974
                                                }
 
975
 
 
976
                                                build_new_dn( &ndn, &pdn, &op->orr_nnewrdn, NULL ); 
 
977
 
 
978
                                                ber_memfree( target_entry_copy->e_nname.bv_val );
 
979
                                                target_entry_copy->e_nname = ndn;
 
980
                                                ber_bvreplace( &target_entry_copy->e_name, &ndn );
 
981
                                        }
 
982
 
 
983
                                        /* apply modifications, in an attempt
 
984
                                         * to estimate what the entry would
 
985
                                         * look like in case all modifications
 
986
                                         * pass */
 
987
                                        for ( ml = modlist; ml; ml = ml->sml_next ) {
 
988
                                                Modification *mod = &ml->sml_mod;
 
989
                                                const char *text;
 
990
                                                char textbuf[SLAP_TEXT_BUFLEN];
 
991
                                                size_t textlen = sizeof(textbuf);
 
992
                                                int err;
 
993
 
 
994
                                                switch ( mod->sm_op ) {
 
995
                                                case LDAP_MOD_ADD:
 
996
                                                        err = modify_add_values( target_entry_copy,
 
997
                                                                mod, get_permissiveModify(op),
 
998
                                                                &text, textbuf, textlen );
 
999
                                                        break;
 
1000
 
 
1001
                                                case LDAP_MOD_DELETE:
 
1002
                                                        err = modify_delete_values( target_entry_copy,
 
1003
                                                                mod, get_permissiveModify(op),
 
1004
                                                                &text, textbuf, textlen );
 
1005
                                                        break;
 
1006
 
 
1007
                                                case LDAP_MOD_REPLACE:
 
1008
                                                        err = modify_replace_values( target_entry_copy,
 
1009
                                                                mod, get_permissiveModify(op),
 
1010
                                                                &text, textbuf, textlen );
 
1011
                                                        break;
 
1012
 
 
1013
                                                case LDAP_MOD_INCREMENT:
 
1014
                                                        err = modify_increment_values( target_entry_copy,
 
1015
                                                                mod, get_permissiveModify(op),
 
1016
                                                                &text, textbuf, textlen );
 
1017
                                                        break;
 
1018
 
 
1019
                                                case SLAP_MOD_SOFTADD:
 
1020
                                                        mod->sm_op = LDAP_MOD_ADD;
 
1021
                                                        err = modify_add_values( target_entry_copy,
 
1022
                                                                mod, get_permissiveModify(op),
 
1023
                                                                &text, textbuf, textlen );
 
1024
                                                        mod->sm_op = SLAP_MOD_SOFTADD;
 
1025
                                                        if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
 
1026
                                                                err = LDAP_SUCCESS;
 
1027
                                                        }
 
1028
                                                        break;
 
1029
 
 
1030
                                                default:
 
1031
                                                        err = LDAP_OTHER;
 
1032
                                                        break;
 
1033
                                                }
 
1034
 
 
1035
                                                if ( err != LDAP_SUCCESS ) {
 
1036
                                                        rc = err;
 
1037
                                                        goto mod_violation;
 
1038
                                                }
 
1039
                                        }
 
1040
                                }
 
1041
 
 
1042
                                if ( acl_match_set(&cp->val, op, target_entry_copy, NULL) == 0) {
 
1043
                                        rc = LDAP_CONSTRAINT_VIOLATION;
 
1044
                                        goto mod_violation;
 
1045
                                }
 
1046
                        }
623
1047
                }
624
1048
        }
625
 
        
 
1049
 
626
1050
        if (target_entry) {
627
1051
                op->o_bd = on->on_info->oi_origdb;
628
1052
                be_entry_release_r(op, target_entry);
629
1053
                op->o_bd = be;
630
1054
        }
 
1055
 
 
1056
        if (target_entry_copy) {
 
1057
                entry_free(target_entry_copy);
 
1058
        }
 
1059
 
631
1060
        return SLAP_CB_CONTINUE;
 
1061
 
632
1062
mod_violation:
633
1063
        /* violation */
634
1064
        if (target_entry) {
636
1066
                be_entry_release_r(op, target_entry);
637
1067
                op->o_bd = be;
638
1068
        }
 
1069
 
 
1070
        if (target_entry_copy) {
 
1071
                entry_free(target_entry_copy);
 
1072
        }
 
1073
 
639
1074
        op->o_bd->bd_info = (BackendInfo *)(on->on_info);
640
 
        msg = print_message( &rsv, m->sml_desc );
641
 
        send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION, msg );
 
1075
        if ( rc == LDAP_CONSTRAINT_VIOLATION ) {
 
1076
                msg = print_message( &rsv, m->sml_desc );
 
1077
        }
 
1078
        send_ldap_error( op, rs, LDAP_CONSTRAINT_VIOLATION, msg );
642
1079
        ch_free(msg);
643
1080
        return (rs->sr_err);
644
1081
}
653
1090
 
654
1091
        for ( ap = on->on_bi.bi_private; ap; ap = a2 ) {
655
1092
                a2 = ap->ap_next;
656
 
                constraint_free( ap );
 
1093
                constraint_free( ap, 1 );
657
1094
        }
658
1095
 
659
1096
        return 0;
671
1108
        constraint_ovl.on_bi.bi_type = "constraint";
672
1109
        constraint_ovl.on_bi.bi_db_close = constraint_close;
673
1110
        constraint_ovl.on_bi.bi_op_add = constraint_add;
674
 
        constraint_ovl.on_bi.bi_op_modify = constraint_modify;
 
1111
        constraint_ovl.on_bi.bi_op_modify = constraint_update;
 
1112
        constraint_ovl.on_bi.bi_op_modrdn = constraint_update;
675
1113
 
676
1114
        constraint_ovl.on_bi.bi_private = NULL;
677
1115