[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