+ int j;
+ for (j = 0; cp->ap[j]; j++) {
+ if (cp->ap[j] == m->sml_desc) {
+ break;
+ }
+ }
+ if (cp->ap[j] == NULL) continue;
+
+ if (cp->restrict_lud != NULL && constraint_check_restrict(op, cp, target_entry) == 0) {
+ 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;
+
+ for ( i = 0; b[i].bv_val; i++ ) {
+ rc = constraint_violation( cp, &b[i], op );
+ if ( rc ) {
+ goto mod_violation;
+ }
+ }
+
+ if (cp->set && target_entry) {
+ if (target_entry_copy == NULL) {
+ Modifications *ml;
+
+ target_entry_copy = entry_dup(target_entry);
+
+ /* if rename, set the new entry's name
+ * (in normalized form only) */
+ if ( op->o_tag == LDAP_REQ_MODRDN ) {
+ struct berval pdn, ndn = BER_BVNULL;
+
+ if ( op->orr_nnewSup ) {
+ pdn = *op->orr_nnewSup;
+
+ } else {
+ dnParent( &target_entry_copy->e_nname, &pdn );
+ }
+
+ build_new_dn( &ndn, &pdn, &op->orr_nnewrdn, NULL );
+
+ ber_memfree( target_entry_copy->e_nname.bv_val );
+ target_entry_copy->e_nname = ndn;
+ ber_bvreplace( &target_entry_copy->e_name, &ndn );
+ }
+
+ /* apply modifications, in an attempt
+ * to estimate what the entry would
+ * look like in case all modifications
+ * pass */
+ for ( ml = modlist; ml; ml = ml->sml_next ) {
+ Modification *mod = &ml->sml_mod;
+ const char *text;
+ char textbuf[SLAP_TEXT_BUFLEN];
+ size_t textlen = sizeof(textbuf);
+ int err;
+
+ switch ( mod->sm_op ) {
+ case LDAP_MOD_ADD:
+ err = modify_add_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_DELETE:
+ err = modify_delete_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_REPLACE:
+ err = modify_replace_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ break;
+
+ case LDAP_MOD_INCREMENT:
+ err = modify_increment_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ break;
+
+ case SLAP_MOD_SOFTADD:
+ mod->sm_op = LDAP_MOD_ADD;
+ err = modify_add_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ mod->sm_op = SLAP_MOD_SOFTADD;
+ if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
+ err = LDAP_SUCCESS;
+ }
+ break;
+
+ case SLAP_MOD_SOFTDEL:
+ mod->sm_op = LDAP_MOD_ADD;
+ err = modify_delete_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ mod->sm_op = SLAP_MOD_SOFTDEL;
+ if ( err == LDAP_NO_SUCH_ATTRIBUTE ) {
+ err = LDAP_SUCCESS;
+ }
+ break;
+
+ case SLAP_MOD_ADD_IF_NOT_PRESENT:
+ if ( attr_find( target_entry_copy->e_attrs, mod->sm_desc ) ) {
+ err = LDAP_SUCCESS;
+ break;
+ }
+ mod->sm_op = LDAP_MOD_ADD;
+ err = modify_add_values( target_entry_copy,
+ mod, get_permissiveModify(op),
+ &text, textbuf, textlen );
+ mod->sm_op = SLAP_MOD_ADD_IF_NOT_PRESENT;
+ break;
+
+ default:
+ err = LDAP_OTHER;
+ break;
+ }
+
+ if ( err != LDAP_SUCCESS ) {
+ rc = err;
+ goto mod_violation;
+ }
+ }
+ }
+
+ if ( acl_match_set(&cp->val, op, target_entry_copy, NULL) == 0) {
+ rc = LDAP_CONSTRAINT_VIOLATION;
+ goto mod_violation;