[openldap] fix: count constraint broken when using multiple modifications

jvcelak jvcelak at fedoraproject.org
Tue Feb 21 14:45:43 UTC 2012


commit b2b2825914b9514969888407ddd99787e5d5a0dc
Author: Jan Vcelak <jvcelak at redhat.com>
Date:   Tue Feb 21 15:44:56 2012 +0100

    fix: count constraint broken when using multiple modifications
    
    Resolves: #795766

 openldap-constraint-count.patch |  190 +++++++++++++++++++++++++++++++++++++++
 openldap.spec                   |    4 +
 2 files changed, 194 insertions(+), 0 deletions(-)
---
diff --git a/openldap-constraint-count.patch b/openldap-constraint-count.patch
new file mode 100644
index 0000000..1a7677a
--- /dev/null
+++ b/openldap-constraint-count.patch
@@ -0,0 +1,190 @@
+Fix count constraint when using multiple modifications
+
+Constraint overlay doesn't take into account multiple modifications when using
+count.
+
+Example: If count for 'description' attribute is set e.g. to 2, the following
+results in a constraint violation:
+
+dn: cn=usr2, dc=my-domain,dc=com
+add: description
+description: d1
+description: d2
+description: d3-viol
+
+However, this passes:
+
+dn: cn=usr2, dc=my-domain,dc=com
+add: description
+description: d1
+-
+add: description
+description: d2
+-
+add: description
+description: d3
+
+This patch fixes the behavior in case multiple modifications are used.
+
+Author: Jan Synacek <jsynacek at redhat.com>
+Upstream ITS: #7168
+Resolves: #742163
+
+diff --git a/servers/slapd/overlays/constraint.c b/servers/slapd/overlays/constraint.c
+index e6a9267..2988af6 100644
+--- a/servers/slapd/overlays/constraint.c
++++ b/servers/slapd/overlays/constraint.c
+@@ -838,6 +838,60 @@ 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++ ) {
++		ca = 0;
++
++		/* 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 ) {
++				switch ( m->sml_op ) {
++				case LDAP_MOD_DELETE:
++					ce = 0;
++					break;
++
++				case LDAP_MOD_ADD:
++					if (( b = m->sml_values ) == NULL  || b[0].bv_val == NULL )
++						continue;
++
++					for ( ca = 0; b[ca].bv_val; ++ca );
++					ce += ca;
++					break;
++
++				case LDAP_MOD_REPLACE:
++					if (( b = m->sml_values ) == NULL  || b[0].bv_val == NULL )
++						continue;
++
++					for ( ca = 0; b[ca].bv_val; ++ca );
++					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 )
+ {
+ 	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
+@@ -850,6 +904,8 @@ constraint_update( Operation *op, SlapReply *rs )
+ 	struct berval rsv = BER_BVC("modify breaks constraint");
+ 	int rc;
+ 	char *msg = NULL;
++	int is_v;
++	int first = 1;
+ 
+ 	if (get_relax(op)) {
+ 		return SLAP_CB_CONTINUE;
+@@ -880,10 +936,12 @@ constraint_update( Operation *op, SlapReply *rs )
+ 	/* 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 (first) {
++				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;
++				first = 0;
++			}
+ 			if (rc != 0 || target_entry == NULL) {
+ 				Debug(LDAP_DEBUG_TRACE, 
+ 					"==> constraint_update rc = %d DN=\"%s\"%s\n",
+@@ -893,7 +951,16 @@ constraint_update( Operation *op, SlapReply *rs )
+ 					rc = LDAP_CONSTRAINT_VIOLATION;
+ 				goto mod_violation;
+ 			}
+-			break;
++
++			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 +979,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 +992,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;
+-- 
+1.7.7.6
+
diff --git a/openldap.spec b/openldap.spec
index d9b6909..6c73a24 100644
--- a/openldap.spec
+++ b/openldap.spec
@@ -38,6 +38,7 @@ Patch6: openldap-userconfig-setgid.patch
 Patch7: openldap-dns-priority.patch
 Patch8: openldap-syncrepl-unset-tls-options.patch
 Patch9: openldap-result-write-polling.patch
+Patch10: openldap-constraint-count.patch
 
 # Fedora specific patches
 Patch100: openldap-fedora-systemd.patch
@@ -142,6 +143,7 @@ pushd openldap-%{version}
 %patch7 -p1
 %patch8 -p1
 %patch9 -p1
+%patch10 -p1
 
 %patch100 -p1
 
@@ -655,6 +657,8 @@ exit 0
 %changelog
 * Tue Feb 21 2012 Jan Vcelak <jvcelak at redhat.com> 2.4.29-3
 - fix: ldap_result does not succeed for sssd (#771484)
+- Jan Synáček <jsynacek at redhat.com>:
+  + fix: count constraint broken when using multiple modifications (#795766)
 
 * Mon Feb 20 2012 Jan Vcelak <jvcelak at redhat.com> 2.4.29-2
 - fix update: provide ldif2ldbm, not ldib2ldbm (#437104)


More information about the scm-commits mailing list