122
141
switch (c->type) {
123
142
case CONSTRAINT_ATTRIBUTE:
124
143
for (cp=cn; cp; cp=cp->ap_next) {
127
145
char *tstr = NULL;
129
len = cp->ap->ad_cname.bv_len + 3;
149
bv.bv_len = STRLENOF(" ");
150
for (j = 0; cp->ap[j]; j++) {
151
bv.bv_len += cp->ap[j]->ad_cname.bv_len;
154
/* room for commas */
131
len += STRLENOF(REGEX_STR);
132
158
tstr = REGEX_STR;
133
159
} else if (cp->lud) {
134
len += STRLENOF(URI_STR);
162
} else if (cp->set) {
136
165
} else if (cp->size) {
137
len += STRLENOF(SIZE_STR);
139
167
} else if (cp->count) {
140
len += STRLENOF(COUNT_STR);
141
168
tstr = COUNT_STR;
143
len += cp->val.bv_len;
147
bv.bv_len = snprintf(s, len, "%s %s %s", cp->ap->ad_cname.bv_val,
148
tstr, cp->val.bv_val);
171
bv.bv_len += strlen(tstr);
172
bv.bv_len += cp->val.bv_len + 2*quotes;
174
if (cp->restrict_lud != NULL) {
175
bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\"");
178
s = bv.bv_val = ch_malloc(bv.bv_len + 1);
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++) {
183
s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len );
186
s = lutil_strcopy( s, tstr );
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 );
150
198
rc = value_add_one( &c->rvalue_vals, &bv );
152
rc = value_add_one( &c->rvalue_nvals, &bv );
199
if (rc == LDAP_SUCCESS)
200
rc = value_add_one( &c->rvalue_nvals, &bv );
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 );
279
328
ap.attrs[i] = NULL;
282
if (ap.lud->lud_dn == NULL)
331
if (ap.lud->lud_dn == NULL) {
283
332
ap.lud->lud_dn = ch_strdup("");
285
if (ap.lud->lud_filter == NULL)
334
struct berval dn, ndn;
336
ber_str2bv( ap.lud->lud_dn, 0, 0, &dn );
337
if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) {
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 );
347
ldap_memfree( ap.lud->lud_dn );
348
ap.lud->lud_dn = ndn.bv_val;
351
if (ap.lud->lud_filter == NULL) {
286
352
ap.lud->lud_filter = ch_strdup("objectClass=*");
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 );
362
AC_MEMCPY( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 );
363
ap.lud->lud_filter[len - 2] = '\0';
366
ber_str2bv( c->argv[3], 0, 1, &ap.val );
368
} else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) {
370
ber_str2bv( c->argv[3], 0, 1, &ap.val );
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] );
383
for ( argidx = 4; argidx < c->argc; argidx++ ) {
384
if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) {
386
char *arg = c->argv[argidx] + STRLENOF("restrict=");
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);
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);
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);
413
ldap_memvfree((void *)ap.restrict_lud->lud_attrs);
414
ap.restrict_lud->lud_attrs = NULL;
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;
423
struct berval dn, ndn;
426
ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn);
427
if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) {
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 );
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] );
445
for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) {
446
if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break;
449
if (BER_BVISNULL(&c->be->be_nsuffix[j])) {
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 );
458
ap.restrict_ndn = ndn;
462
if (ap.restrict_lud->lud_filter != NULL) {
463
ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter);
464
if (ap.restrict_filter == NULL) {
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 );
474
ber_str2bv(c->argv[argidx], 0, 1, &ap.restrict_val);
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] );
488
if ( rc == LDAP_SUCCESS ) {
489
constraint *a2 = ch_calloc( sizeof(constraint), 1 );
490
a2->ap_next = on->on_bi.bi_private;
497
a2->count = ap.count;
499
ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn);
500
ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter);
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;
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 );
298
a2 = ch_calloc( sizeof(constraint), 1 );
299
a2->ap_next = on->on_bi.bi_private;
305
a2->count = ap.count;
307
ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn);
308
ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter);
310
a2->attrs = ap.attrs;
311
on->on_bi.bi_private = a2;
515
ldap_memvfree((void**)attrs);
695
constraint_check_restrict( Operation *op, constraint *c, Entry *e )
697
assert( c->restrict_lud != NULL );
699
if ( c->restrict_lud->lud_dn != NULL ) {
700
int diff = e->e_nname.bv_len - c->restrict_ndn.bv_len;
706
if ( c->restrict_lud->lud_scope == LDAP_SCOPE_BASE ) {
707
return bvmatch( &e->e_nname, &c->restrict_ndn );
710
if ( !dnIsSuffix( &e->e_nname, &c->restrict_ndn ) ) {
714
if ( c->restrict_lud->lud_scope != LDAP_SCOPE_SUBTREE ) {
721
dnParent( &e->e_nname, &pdn );
723
if ( c->restrict_lud->lud_scope == LDAP_SCOPE_ONELEVEL
724
&& pdn.bv_len != c->restrict_ndn.bv_len )
731
if ( c->restrict_filter != NULL ) {
733
struct berval save_dn = op->o_dn, save_ndn = op->o_ndn;
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 );
739
op->o_ndn = save_ndn;
741
if ( rc != LDAP_COMPARE_TRUE ) {
482
750
constraint_add( Operation *op, SlapReply *rs )
484
752
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
485
Backend *be = op->o_bd;
487
754
constraint *c = on->on_bi.bi_private, *cp;
488
755
BerVarray b = NULL;
490
757
struct berval rsv = BER_BVC("add breaks constraint");
762
return SLAP_CB_CONTINUE;
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);
502
774
if (is_at_operational(a->a_desc->ad_type)) continue;
504
776
for(cp = c; cp; cp = cp->ap_next) {
505
if (cp->ap != a->a_desc) continue;
778
for (j = 0; cp->ap[j]; j++) {
779
if (cp->ap[j] == a->a_desc) break;
781
if (cp->ap[j] == NULL) continue;
506
782
if ((b = a->a_vals) == NULL) continue;
784
if (cp->restrict_lud != NULL && constraint_check_restrict(op, cp, op->ora_e) == 0) {
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);
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;
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 );
518
801
goto add_violation;
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 */
521
813
/* Default is to just fall through to the normal processing */
522
814
return SLAP_CB_CONTINUE;
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 );
821
send_ldap_error(op, rs, rc, msg );
529
823
return (rs->sr_err);
534
constraint_modify( Operation *op, SlapReply *rs )
828
constraint_update( Operation *op, SlapReply *rs )
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;
833
Entry *target_entry = NULL, *target_entry_copy = NULL;
834
Modifications *modlist, *m;
541
835
BerVarray b = NULL;
543
837
struct berval rsv = BER_BVC("modify breaks constraint");
842
return SLAP_CB_CONTINUE;
845
switch ( op->o_tag ) {
846
case LDAP_REQ_MODIFY:
847
modlist = op->orm_modlist;
850
case LDAP_REQ_MODRDN:
851
modlist = op->orr_modlist;
855
/* impossible! assert? */
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);
554
867
/* Do we need to count attributes? */
555
868
for(cp = c; cp; cp = cp->ap_next) {
556
if (cp->count != 0) {
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 );
563
874
if (rc != 0 || target_entry == NULL) {
564
875
Debug(LDAP_DEBUG_TRACE,
565
"==> constraint_modify rc = %d\n",
876
"==> constraint_update rc = %d DN=\"%s\"%s\n",
877
rc, op->o_req_ndn.bv_val,
878
target_entry ? "" : " not found" );
880
rc = LDAP_CONSTRAINT_VIOLATION;
567
881
goto mod_violation;
887
rc = LDAP_CONSTRAINT_VIOLATION;
573
888
for(;m; m = m->sml_next) {
576
/* Get this attribute count, if needed */
578
ce = constraint_count_attr(target_entry, m->sml_desc);
580
891
if (is_at_operational( m->sml_desc->ad_type )) continue;
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))
617
948
if (( m->sml_op & LDAP_MOD_OP ) == LDAP_MOD_DELETE)
620
for(i=0; b[i].bv_val; i++)
621
if (constraint_violation( cp, &b[i], op, rs))
951
for ( i = 0; b[i].bv_val; i++ ) {
952
rc = constraint_violation( cp, &b[i], op, rs );
958
if (cp->set && target_entry) {
959
if (target_entry_copy == NULL) {
962
target_entry_copy = entry_dup(target_entry);
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;
969
if ( op->orr_nnewSup ) {
970
pdn = *op->orr_nnewSup;
973
dnParent( &target_entry_copy->e_nname, &pdn );
976
build_new_dn( &ndn, &pdn, &op->orr_nnewrdn, NULL );
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 );
983
/* apply modifications, in an attempt
984
* to estimate what the entry would
985
* look like in case all modifications
987
for ( ml = modlist; ml; ml = ml->sml_next ) {
988
Modification *mod = &ml->sml_mod;
990
char textbuf[SLAP_TEXT_BUFLEN];
991
size_t textlen = sizeof(textbuf);
994
switch ( mod->sm_op ) {
996
err = modify_add_values( target_entry_copy,
997
mod, get_permissiveModify(op),
998
&text, textbuf, textlen );
1001
case LDAP_MOD_DELETE:
1002
err = modify_delete_values( target_entry_copy,
1003
mod, get_permissiveModify(op),
1004
&text, textbuf, textlen );
1007
case LDAP_MOD_REPLACE:
1008
err = modify_replace_values( target_entry_copy,
1009
mod, get_permissiveModify(op),
1010
&text, textbuf, textlen );
1013
case LDAP_MOD_INCREMENT:
1014
err = modify_increment_values( target_entry_copy,
1015
mod, get_permissiveModify(op),
1016
&text, textbuf, textlen );
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 ) {
1035
if ( err != LDAP_SUCCESS ) {
1042
if ( acl_match_set(&cp->val, op, target_entry_copy, NULL) == 0) {
1043
rc = LDAP_CONSTRAINT_VIOLATION;
626
1050
if (target_entry) {
627
1051
op->o_bd = on->on_info->oi_origdb;
628
1052
be_entry_release_r(op, target_entry);
1056
if (target_entry_copy) {
1057
entry_free(target_entry_copy);
631
1060
return SLAP_CB_CONTINUE;
634
1064
if (target_entry) {