|
Jan Vcelak |
b2b2825 |
Fix count constraint when using multiple modifications
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
Constraint overlay doesn't take into account multiple modifications when using
|
|
Jan Vcelak |
b2b2825 |
count.
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
Example: If count for 'description' attribute is set e.g. to 2, the following
|
|
Jan Vcelak |
b2b2825 |
results in a constraint violation:
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
dn: cn=usr2, dc=my-domain,dc=com
|
|
Jan Vcelak |
b2b2825 |
add: description
|
|
Jan Vcelak |
b2b2825 |
description: d1
|
|
Jan Vcelak |
b2b2825 |
description: d2
|
|
Jan Vcelak |
b2b2825 |
description: d3-viol
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
However, this passes:
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
dn: cn=usr2, dc=my-domain,dc=com
|
|
Jan Vcelak |
b2b2825 |
add: description
|
|
Jan Vcelak |
b2b2825 |
description: d1
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
add: description
|
|
Jan Vcelak |
b2b2825 |
description: d2
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
add: description
|
|
Jan Vcelak |
b2b2825 |
description: d3
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
This patch fixes the behavior in case multiple modifications are used.
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
Author: Jan Synacek <jsynacek@redhat.com>
|
|
Jan Vcelak |
b2b2825 |
Upstream ITS: #7168
|
|
Jan Vcelak |
5172ff7 |
Upstream commit: bb8112c382c24db25b175459e340ce248fe25563
|
|
Jan Vcelak |
b2b2825 |
Resolves: #742163
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
5172ff7 |
---
|
|
Jan Vcelak |
5172ff7 |
servers/slapd/overlays/constraint.c | 117 ++++++++++++++++++++++++-----------
|
|
Jan Vcelak |
5172ff7 |
1 file changed, 80 insertions(+), 37 deletions(-)
|
|
Jan Vcelak |
5172ff7 |
|
|
Jan Vcelak |
b2b2825 |
diff --git a/servers/slapd/overlays/constraint.c b/servers/slapd/overlays/constraint.c
|
|
Jan Vcelak |
5172ff7 |
index e6a9267..538d383 100644
|
|
Jan Vcelak |
b2b2825 |
--- a/servers/slapd/overlays/constraint.c
|
|
Jan Vcelak |
b2b2825 |
+++ b/servers/slapd/overlays/constraint.c
|
|
Jan Vcelak |
5172ff7 |
@@ -838,6 +838,68 @@ add_violation:
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
static int
|
|
Jan Vcelak |
b2b2825 |
+constraint_check_count_violation( Modifications *m, Entry *target_entry, constraint *cp )
|
|
Jan Vcelak |
b2b2825 |
+{
|
|
Jan Vcelak |
b2b2825 |
+ BerVarray b = NULL;
|
|
Jan Vcelak |
b2b2825 |
+ unsigned ce = 0;
|
|
Jan Vcelak |
b2b2825 |
+ unsigned ca;
|
|
Jan Vcelak |
b2b2825 |
+ int j;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ for ( j = 0; cp->ap[j]; j++ ) {
|
|
Jan Vcelak |
b2b2825 |
+ ca = 0;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ /* Get this attribute count */
|
|
Jan Vcelak |
b2b2825 |
+ if ( target_entry )
|
|
Jan Vcelak |
b2b2825 |
+ ce = constraint_count_attr( target_entry, cp->ap[j] );
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ for( ; m; m = m->sml_next ) {
|
|
Jan Vcelak |
b2b2825 |
+ if ( cp->ap[j] == m->sml_desc ) {
|
|
Jan Vcelak |
b2b2825 |
+ switch ( m->sml_op ) {
|
|
Jan Vcelak |
b2b2825 |
+ case LDAP_MOD_DELETE:
|
|
Jan Vcelak |
5172ff7 |
+ if (( b = m->sml_values ) == NULL || b[0].bv_val == NULL ) {
|
|
Jan Vcelak |
5172ff7 |
+ ce = 0;
|
|
Jan Vcelak |
5172ff7 |
+ }
|
|
Jan Vcelak |
5172ff7 |
+ else {
|
|
Jan Vcelak |
5172ff7 |
+ /* No need to check for values' validity. Invalid values
|
|
Jan Vcelak |
5172ff7 |
+ * cause the whole transaction to die anyway. */
|
|
Jan Vcelak |
5172ff7 |
+ for ( ca = 0; b[ca].bv_val; ++ca );
|
|
Jan Vcelak |
5172ff7 |
+ ce -= ca;
|
|
Jan Vcelak |
5172ff7 |
+ }
|
|
Jan Vcelak |
b2b2825 |
+ break;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ case LDAP_MOD_ADD:
|
|
Jan Vcelak |
b2b2825 |
+ if (( b = m->sml_values ) == NULL || b[0].bv_val == NULL )
|
|
Jan Vcelak |
b2b2825 |
+ continue;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ for ( ca = 0; b[ca].bv_val; ++ca );
|
|
Jan Vcelak |
b2b2825 |
+ ce += ca;
|
|
Jan Vcelak |
b2b2825 |
+ break;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ case LDAP_MOD_REPLACE:
|
|
Jan Vcelak |
b2b2825 |
+ if (( b = m->sml_values ) == NULL || b[0].bv_val == NULL )
|
|
Jan Vcelak |
b2b2825 |
+ continue;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ for ( ca = 0; b[ca].bv_val; ++ca );
|
|
Jan Vcelak |
b2b2825 |
+ ce = ca;
|
|
Jan Vcelak |
b2b2825 |
+ break;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ default:
|
|
Jan Vcelak |
b2b2825 |
+ /* impossible! assert? */
|
|
Jan Vcelak |
b2b2825 |
+ return 1;
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ Debug(LDAP_DEBUG_TRACE,
|
|
Jan Vcelak |
b2b2825 |
+ "==> constraint_check_count_violation ce = %u, "
|
|
Jan Vcelak |
b2b2825 |
+ "ca = %u, cp->count = %lu\n",
|
|
Jan Vcelak |
b2b2825 |
+ ce, ca, (unsigned long) cp->count);
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ return ( ce > cp->count );
|
|
Jan Vcelak |
b2b2825 |
+}
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+static int
|
|
Jan Vcelak |
b2b2825 |
constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
{
|
|
Jan Vcelak |
b2b2825 |
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
|
|
Jan Vcelak |
5172ff7 |
@@ -850,6 +912,8 @@ constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
struct berval rsv = BER_BVC("modify breaks constraint");
|
|
Jan Vcelak |
b2b2825 |
int rc;
|
|
Jan Vcelak |
b2b2825 |
char *msg = NULL;
|
|
Jan Vcelak |
b2b2825 |
+ int is_v;
|
|
Jan Vcelak |
b2b2825 |
+ int first = 1;
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
if (get_relax(op)) {
|
|
Jan Vcelak |
b2b2825 |
return SLAP_CB_CONTINUE;
|
|
Jan Vcelak |
5172ff7 |
@@ -880,10 +944,12 @@ constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
/* Do we need to count attributes? */
|
|
Jan Vcelak |
b2b2825 |
for(cp = c; cp; cp = cp->ap_next) {
|
|
Jan Vcelak |
b2b2825 |
if (cp->count != 0 || cp->set || cp->restrict_lud != 0) {
|
|
Jan Vcelak |
b2b2825 |
- op->o_bd = on->on_info->oi_origdb;
|
|
Jan Vcelak |
b2b2825 |
- rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &target_entry );
|
|
Jan Vcelak |
b2b2825 |
- op->o_bd = be;
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
+ if (first) {
|
|
Jan Vcelak |
b2b2825 |
+ op->o_bd = on->on_info->oi_origdb;
|
|
Jan Vcelak |
b2b2825 |
+ rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &target_entry );
|
|
Jan Vcelak |
b2b2825 |
+ op->o_bd = be;
|
|
Jan Vcelak |
b2b2825 |
+ first = 0;
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
if (rc != 0 || target_entry == NULL) {
|
|
Jan Vcelak |
b2b2825 |
Debug(LDAP_DEBUG_TRACE,
|
|
Jan Vcelak |
b2b2825 |
"==> constraint_update rc = %d DN=\"%s\"%s\n",
|
|
Jan Vcelak |
5172ff7 |
@@ -893,7 +959,16 @@ constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
rc = LDAP_CONSTRAINT_VIOLATION;
|
|
Jan Vcelak |
b2b2825 |
goto mod_violation;
|
|
Jan Vcelak |
b2b2825 |
}
|
|
Jan Vcelak |
b2b2825 |
- break;
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ is_v = constraint_check_count_violation(m, target_entry, cp);
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ Debug(LDAP_DEBUG_TRACE,
|
|
Jan Vcelak |
b2b2825 |
+ "==> constraint_update is_v: %d\n", is_v, 0, 0);
|
|
Jan Vcelak |
b2b2825 |
+
|
|
Jan Vcelak |
b2b2825 |
+ if (is_v) {
|
|
Jan Vcelak |
b2b2825 |
+ rc = LDAP_CONSTRAINT_VIOLATION;
|
|
Jan Vcelak |
b2b2825 |
+ goto mod_violation;
|
|
Jan Vcelak |
b2b2825 |
+ }
|
|
Jan Vcelak |
b2b2825 |
}
|
|
Jan Vcelak |
b2b2825 |
}
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
5172ff7 |
@@ -912,10 +987,6 @@ constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
if ((( b = m->sml_values ) == NULL ) || (b[0].bv_val == NULL))
|
|
Jan Vcelak |
b2b2825 |
continue;
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
- /* Get this attribute count, if needed */
|
|
Jan Vcelak |
b2b2825 |
- if (target_entry)
|
|
Jan Vcelak |
b2b2825 |
- ce = constraint_count_attr(target_entry, m->sml_desc);
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
for(cp = c; cp; cp = cp->ap_next) {
|
|
Jan Vcelak |
b2b2825 |
int j;
|
|
Jan Vcelak |
b2b2825 |
for (j = 0; cp->ap[j]; j++) {
|
|
Jan Vcelak |
5172ff7 |
@@ -929,34 +1000,6 @@ constraint_update( Operation *op, SlapReply *rs )
|
|
Jan Vcelak |
b2b2825 |
continue;
|
|
Jan Vcelak |
b2b2825 |
}
|
|
Jan Vcelak |
b2b2825 |
|
|
Jan Vcelak |
b2b2825 |
- if (cp->count != 0) {
|
|
Jan Vcelak |
b2b2825 |
- unsigned ca;
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
- if (m->sml_op == LDAP_MOD_DELETE)
|
|
Jan Vcelak |
b2b2825 |
- ce = 0;
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
- for (ca = 0; b[ca].bv_val; ++ca);
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
- Debug(LDAP_DEBUG_TRACE,
|
|
Jan Vcelak |
b2b2825 |
- "==> constraint_update ce = %u, "
|
|
Jan Vcelak |
b2b2825 |
- "ca = %u, cp->count = %lu\n",
|
|
Jan Vcelak |
b2b2825 |
- ce, ca, (unsigned long) cp->count);
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
- if (m->sml_op == LDAP_MOD_ADD) {
|
|
Jan Vcelak |
b2b2825 |
- if (ca + ce > cp->count) {
|
|
Jan Vcelak |
b2b2825 |
- rc = LDAP_CONSTRAINT_VIOLATION;
|
|
Jan Vcelak |
b2b2825 |
- goto mod_violation;
|
|
Jan Vcelak |
b2b2825 |
- }
|
|
Jan Vcelak |
b2b2825 |
- }
|
|
Jan Vcelak |
b2b2825 |
- if (m->sml_op == LDAP_MOD_REPLACE) {
|
|
Jan Vcelak |
b2b2825 |
- if (ca > cp->count) {
|
|
Jan Vcelak |
b2b2825 |
- rc = LDAP_CONSTRAINT_VIOLATION;
|
|
Jan Vcelak |
b2b2825 |
- goto mod_violation;
|
|
Jan Vcelak |
b2b2825 |
- }
|
|
Jan Vcelak |
b2b2825 |
- ce = ca;
|
|
Jan Vcelak |
b2b2825 |
- }
|
|
Jan Vcelak |
b2b2825 |
- }
|
|
Jan Vcelak |
b2b2825 |
-
|
|
Jan Vcelak |
b2b2825 |
/* DELETE are to be ignored beyond this point */
|
|
Jan Vcelak |
b2b2825 |
if (( m->sml_op & LDAP_MOD_OP ) == LDAP_MOD_DELETE)
|
|
Jan Vcelak |
b2b2825 |
continue;
|
|
Jan Vcelak |
b2b2825 |
--
|
|
Jan Vcelak |
5172ff7 |
1.7.10.4
|
|
Jan Vcelak |
b2b2825 |
|