s4-drs: Do not allow system-critical attributes to be RODC filtered
[vlendec/samba-autobuild/.git] / source4 / dsdb / samdb / ldb_modules / objectclass.c
index 329bd81ae3630c56780a8b969f1a5f1c3ffd45c5..e51038d06f70620489ab78a2e431843d9d38d24f 100644 (file)
@@ -378,6 +378,27 @@ static int fix_check_attributes(struct ldb_context *ldb,
        return LDB_SUCCESS;
 }
 
+/*
+ * return true if msg carries an attributeSchema that is intended to be RODC
+ * filtered but is also a system-critical attribute.
+ */
+static bool check_rodc_critical_attribute(struct ldb_message *msg)
+{
+       uint32_t schemaFlagsEx, searchFlags, rodc_filtered_flags;
+
+       schemaFlagsEx = ldb_msg_find_attr_as_uint(msg, "schemaFlagsEx", 0);
+       searchFlags = ldb_msg_find_attr_as_uint(msg, "searchFlags", 0);
+       rodc_filtered_flags = (SEARCH_FLAG_RODC_ATTRIBUTE | SEARCH_FLAG_CONFIDENTIAL);
+
+       if ((schemaFlagsEx & SCHEMA_FLAG_ATTR_IS_CRITICAL) &&
+               ((searchFlags & rodc_filtered_flags) == rodc_filtered_flags)) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+
 static int objectclass_do_add(struct oc_context *ac);
 
 static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
@@ -404,6 +425,12 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_OBJECT_CLASS_VIOLATION;
        }
 
+       /* do not allow to mark an attributeSchema as RODC filtered if it
+        * is system-critical */
+       if (check_rodc_critical_attribute(req->op.add.message)) {
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
        ac = oc_init_context(module, req);
        if (ac == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
@@ -722,6 +749,12 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req
                return LDB_ERR_UNWILLING_TO_PERFORM;
        }
 
+       /* do not allow to mark an attributeSchema as RODC filtered if it
+        * is system-critical */
+       if (check_rodc_critical_attribute(req->op.mod.message)) {
+               return LDB_ERR_UNWILLING_TO_PERFORM;
+       }
+
        ac = oc_init_context(module, req);
        if (ac == NULL) {
                ldb_oom(ldb);