]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9204 Gate relax on MANAGE access
authorOndřej Kuzník <ondra@mistotebe.net>
Thu, 9 Apr 2026 14:31:27 +0000 (15:31 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Fri, 10 Apr 2026 19:40:36 +0000 (19:40 +0000)
doc/man/man5/slapo-constraint.5
servers/slapd/overlays/constraint.c

index e6a12d2892ea2f0239ad376c0dd5b0f401ec6ce1..e53c4eeaeffa02fdd3106ce1a26c8d9b27403757 100644 (file)
@@ -21,9 +21,11 @@ It constrains only LDAP \fIadd\fP, \fImodify\fP and \fIrename\fP commands
 and only seeks to control the \fIadd\fP and \fIreplace\fP values
 of \fImodify\fP and \fIrename\fP requests.
 .LP
-No constraints are applied for operations performed with the
+Constraints can be lifted for operations where the
 .I relax
-control set.
+control is set and the user has
+.B manage
+privileges to the relevant attribute.
 .SH CONFIGURATION
 These
 .B slapd.conf
@@ -115,7 +117,11 @@ to maintain backwards compatibility.
 Any attempt to add or modify an attribute named as part of the
 constraint overlay specification which does not fit the 
 constraint listed will fail with a
-LDAP_CONSTRAINT_VIOLATION error.
+LDAP_CONSTRAINT_VIOLATION error unless the
+.I relax
+control was set and the user has
+.B manage
+privilege on the attribute in question.
 .SH EXAMPLES
 .LP
 .RS
index 2e45d201d577bf79b82d6a975a36f8766893f41e..8c0c2bc661a32e4525a25109e34dc4c53a0fd709 100644 (file)
@@ -855,7 +855,7 @@ constraint_add( Operation *op, SlapReply *rs )
        int rc = 0;
        char *msg = NULL;
 
-       if ( get_relax(op) || be_shadow_update( op ) ) {
+       if ( be_shadow_update( op ) ) {
                return SLAP_CB_CONTINUE;
        }
 
@@ -889,6 +889,13 @@ constraint_add( Operation *op, SlapReply *rs )
                                continue;
                        }
 
+                       /* No need to check if user asked to Relax this op and has MANAGE
+                        * access to the attribute */
+                       if ( get_relax(op) && access_allowed( op, op->ora_e, a->a_desc,
+                                               NULL, ACL_MANAGE, NULL ) ) {
+                               continue;
+                       }
+
                        Debug(LDAP_DEBUG_TRACE, 
                                "==> constraint_add, "
                                "a->a_numvals = %u, cp->count = %lu\n",
@@ -936,7 +943,8 @@ add_violation:
 
 
 static int
-constraint_check_count_violation( Modifications *m, Entry *target_entry, constraint *cp )
+constraint_check_count_violation( Operation *op, Modifications *m, Entry
+               *target_entry, constraint *cp )
 {
        BerVarray b = NULL;
        unsigned ce = 0;
@@ -990,6 +998,10 @@ constraint_check_count_violation( Modifications *m, Entry *target_entry, constra
                        }
                }
                if ( ce > cp->count ) {
+                       if ( get_relax(op) && access_allowed( op, target_entry, cp->ap[j],
+                                               NULL, ACL_MANAGE, NULL ) ) {
+                               continue;
+                       }
                        return 1;
                }
        }
@@ -1013,7 +1025,7 @@ constraint_update( Operation *op, SlapReply *rs )
        char *msg = NULL;
        int is_v;
 
-       if ( get_relax(op) || be_shadow_update( op ) ) {
+       if ( be_shadow_update( op ) ) {
                return SLAP_CB_CONTINUE;
        }
 
@@ -1057,7 +1069,7 @@ constraint_update( Operation *op, SlapReply *rs )
                                continue;
                        }
 
-                       is_v = constraint_check_count_violation(m, target_entry, cp);
+                       is_v = constraint_check_count_violation(op, m, target_entry, cp);
 
                        Debug(LDAP_DEBUG_TRACE,
                                "==> constraint_update is_v: %d\n", is_v );
@@ -1085,6 +1097,13 @@ constraint_update( Operation *op, SlapReply *rs )
                if ((( b = m->sml_values ) == NULL ) || (b[0].bv_val == NULL))
                        continue;
 
+               /* No need to check if user asked to Relax this op and has MANAGE
+                * access to the attribute */
+               if ( get_relax(op) && access_allowed( op, target_entry, m->sml_desc,
+                                       NULL, ACL_MANAGE, NULL ) ) {
+                       continue;
+               }
+
                for(cp = c; cp; cp = cp->ap_next) {
                        int j;
                        for (j = 0; cp->ap[j]; j++) {