X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Foverlays%2Fconstraint.c;h=f2c645c609c04f4fc6c6040ca47b65ae2517da4d;hb=e6910e0a0c689b289837e75352541ee3fc966064;hp=e6a9267ba7d15e3639e900b97e22584e98b596b2;hpb=1878d201c1e0a7f42b0d5ee66d7f5a2368027c9c;p=openldap diff --git a/servers/slapd/overlays/constraint.c b/servers/slapd/overlays/constraint.c index e6a9267ba7..f2c645c609 100644 --- a/servers/slapd/overlays/constraint.c +++ b/servers/slapd/overlays/constraint.c @@ -181,7 +181,7 @@ constraint_cf_gen( ConfigArgs *c ) } if (cp->count || cp->size) { - int len = snprintf(val_buf, sizeof(val_buf), "%d", val); + int len = snprintf(val_buf, sizeof(val_buf), "%zd", val); if (len <= 0) { /* error */ return -1; @@ -771,7 +771,7 @@ constraint_add( Operation *op, SlapReply *rs ) int rc; char *msg = NULL; - if (get_relax(op)) { + if (get_relax(op) || SLAPD_SYNC_IS_SYNCCONN( op->o_connid )) { return SLAP_CB_CONTINUE; } @@ -837,6 +837,57 @@ add_violation: } +static int +constraint_check_count_violation( Modifications *m, Entry *target_entry, constraint *cp ) +{ + BerVarray b = NULL; + unsigned ce = 0; + unsigned ca; + int j; + + for ( j = 0; cp->ap[j]; j++ ) { + /* Get this attribute count */ + if ( target_entry ) + ce = constraint_count_attr( target_entry, cp->ap[j] ); + + for( ; m; m = m->sml_next ) { + if ( cp->ap[j] == m->sml_desc ) { + ca = m->sml_numvals; + switch ( m->sml_op ) { + case LDAP_MOD_DELETE: + if ( !ca || ca > ce ) { + ce = 0; + } else { + /* No need to check for values' validity. Invalid values + * cause the whole transaction to die anyway. */ + ce -= ca; + } + break; + + case LDAP_MOD_ADD: + ce += ca; + break; + + case LDAP_MOD_REPLACE: + ce = ca; + break; + + default: + /* impossible! assert? */ + return 1; + } + + Debug(LDAP_DEBUG_TRACE, + "==> constraint_check_count_violation ce = %u, " + "ca = %u, cp->count = %lu\n", + ce, ca, (unsigned long) cp->count); + } + } + } + + return ( ce > cp->count ); +} + static int constraint_update( Operation *op, SlapReply *rs ) { @@ -850,8 +901,9 @@ constraint_update( Operation *op, SlapReply *rs ) struct berval rsv = BER_BVC("modify breaks constraint"); int rc; char *msg = NULL; + int is_v; - if (get_relax(op)) { + if (get_relax(op) || SLAPD_SYNC_IS_SYNCCONN( op->o_connid )) { return SLAP_CB_CONTINUE; } @@ -877,13 +929,13 @@ constraint_update( Operation *op, SlapReply *rs ) return(rs->sr_err); } + op->o_bd = on->on_info->oi_origdb; + rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &target_entry ); + op->o_bd = be; + /* Do we need to count attributes? */ for(cp = c; cp; cp = cp->ap_next) { - if (cp->count != 0 || cp->set || cp->restrict_lud != 0) { - op->o_bd = on->on_info->oi_origdb; - rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &target_entry ); - op->o_bd = be; - + if (cp->count != 0) { if (rc != 0 || target_entry == NULL) { Debug(LDAP_DEBUG_TRACE, "==> constraint_update rc = %d DN=\"%s\"%s\n", @@ -893,7 +945,20 @@ constraint_update( Operation *op, SlapReply *rs ) rc = LDAP_CONSTRAINT_VIOLATION; goto mod_violation; } - break; + + if (cp->restrict_lud && constraint_check_restrict(op, cp, target_entry) == 0) { + continue; + } + + is_v = constraint_check_count_violation(m, target_entry, cp); + + Debug(LDAP_DEBUG_TRACE, + "==> constraint_update is_v: %d\n", is_v, 0, 0); + + if (is_v) { + rc = LDAP_CONSTRAINT_VIOLATION; + goto mod_violation; + } } } @@ -912,10 +977,6 @@ constraint_update( Operation *op, SlapReply *rs ) if ((( b = m->sml_values ) == NULL ) || (b[0].bv_val == NULL)) continue; - /* Get this attribute count, if needed */ - if (target_entry) - ce = constraint_count_attr(target_entry, m->sml_desc); - for(cp = c; cp; cp = cp->ap_next) { int j; for (j = 0; cp->ap[j]; j++) { @@ -929,34 +990,6 @@ constraint_update( Operation *op, SlapReply *rs ) continue; } - if (cp->count != 0) { - unsigned ca; - - if (m->sml_op == LDAP_MOD_DELETE) - ce = 0; - - for (ca = 0; b[ca].bv_val; ++ca); - - Debug(LDAP_DEBUG_TRACE, - "==> constraint_update ce = %u, " - "ca = %u, cp->count = %lu\n", - ce, ca, (unsigned long) cp->count); - - if (m->sml_op == LDAP_MOD_ADD) { - if (ca + ce > cp->count) { - rc = LDAP_CONSTRAINT_VIOLATION; - goto mod_violation; - } - } - if (m->sml_op == LDAP_MOD_REPLACE) { - if (ca > cp->count) { - rc = LDAP_CONSTRAINT_VIOLATION; - goto mod_violation; - } - ce = ca; - } - } - /* DELETE are to be ignored beyond this point */ if (( m->sml_op & LDAP_MOD_OP ) == LDAP_MOD_DELETE) continue;