objectclass_attrs: Restrict systemOnly attributes
authorGarming Sam <garming@catalyst.net.nz>
Mon, 6 Mar 2017 23:30:09 +0000 (12:30 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 13 Mar 2017 04:10:12 +0000 (05:10 +0100)
This allows restriction of auditing attributes from being wiped.
Modifications of the RID Set must be done as SYSTEM.

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
source4/dsdb/samdb/ldb_modules/ridalloc.c
source4/dsdb/samdb/ldb_modules/wscript_build_server

index c144578f22794d39021a80b06139fb45a73bd4a5..cfacaf56420a3ae2981992ba820d8928ac576610 100644 (file)
@@ -36,6 +36,7 @@
 #include "includes.h"
 #include "ldb_module.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/samdb/ldb_modules/util.h"
 
 struct oc_context {
 
@@ -214,7 +215,46 @@ static int attr_handler(struct oc_context *ac)
                                               ldb_dn_get_linearized(msg->dn));
                        return LDB_ERR_UNWILLING_TO_PERFORM;
                }
-               
+
+               /*
+                * Enforce systemOnly checks from [ADTS] 3.1.1.5.3.2
+                * Constraints in Modify Operation
+                */
+               if (ac->req->operation == LDB_MODIFY && attr->systemOnly) {
+                       /*
+                        * Allow dbcheck and relax to bypass. objectClass, name
+                        * and distinguishedName are generally handled
+                        * elsewhere.
+                        *
+                        * The remaining cases, undelete, msDS-AdditionalDnsHostName
+                        * and wellKnownObjects are documented in the specification.
+                        */
+                       if (!ldb_request_get_control(ac->req, LDB_CONTROL_RELAX_OID) &&
+                           !ldb_request_get_control(ac->req, DSDB_CONTROL_DBCHECK) &&
+                           !ldb_request_get_control(ac->req, DSDB_CONTROL_RESTORE_TOMBSTONE_OID) &&
+                           ldb_attr_cmp(attr->lDAPDisplayName, "objectClass") != 0 &&
+                           ldb_attr_cmp(attr->lDAPDisplayName, "name") != 0 &&
+                           ldb_attr_cmp(attr->lDAPDisplayName, "distinguishedName") != 0 &&
+                           ldb_attr_cmp(attr->lDAPDisplayName, "msDS-AdditionalDnsHostName") != 0 &&
+                           ldb_attr_cmp(attr->lDAPDisplayName, "wellKnownObjects") != 0) {
+                               /*
+                                * Comparison against base schema DN is used as a substitute for
+                                * fschemaUpgradeInProgress and other specific schema checks.
+                                */
+                               if (ldb_dn_compare_base(ldb_get_schema_basedn(ldb), msg->dn) != 0) {
+                                       struct ldb_control *as_system = ldb_request_get_control(ac->req,
+                                                                                               LDB_CONTROL_AS_SYSTEM_OID);
+                                       if (!dsdb_module_am_system(ac->module) && !as_system) {
+                                               ldb_asprintf_errstring(ldb,
+                                                                      "objectclass_attrs: attribute '%s' on entry '%s' must can only be modified as system",
+                                                                      msg->elements[i].name,
+                                                                      ldb_dn_get_linearized(msg->dn));
+                                               return LDB_ERR_CONSTRAINT_VIOLATION;
+                                       }
+                               }
+                       }
+               }
+
                if (!(msg->elements[i].flags & LDB_FLAG_INTERNAL_DISABLE_VALIDATION)) {
                        werr = attr->syntax->validate_ldb(&syntax_ctx, attr,
                                                          &msg->elements[i]);
index 730272a50ce889c39957c4a6d2ddb440755cdd17..abfe14a5a805958675a32bed43d5be6567b7fe79 100644 (file)
@@ -387,7 +387,9 @@ static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *m
        }
        msg->elements[0].flags = LDB_FLAG_MOD_ADD;
 
-       ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
+       ret = dsdb_module_modify(module, msg,
+                                DSDB_FLAG_NEXT_MODULE|DSDB_FLAG_AS_SYSTEM,
+                                parent);
        if (ret != LDB_SUCCESS) {
                ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
                                       ldb_dn_get_linearized(msg->dn),
@@ -677,7 +679,7 @@ int ridalloc_allocate_rid(struct ldb_module *module, uint32_t *rid, struct ldb_r
                return ret;
        }
 
-       ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
+       ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE|DSDB_FLAG_AS_SYSTEM, parent);
        if (ret != LDB_SUCCESS) {
                talloc_free(tmp_ctx);
                return ret;
@@ -807,7 +809,7 @@ int ridalloc_allocate_rid_pool_fsmo(struct ldb_module *module, struct dsdb_fsmo_
                return ret;
        }
 
-       ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
+       ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE|DSDB_FLAG_AS_SYSTEM, parent);
        if (ret != LDB_SUCCESS) {
                ldb_asprintf_errstring(ldb, "Failed to modify RID Set object %s - %s",
                                       ldb_dn_get_linearized(rid_set_dn), ldb_errstring(ldb));
index 8131566ff5c682739488cffbf7558a4a4f2d3717..41b3fe70b3729f99c3f79d8fb100d24ef5efd544 100644 (file)
@@ -224,7 +224,7 @@ bld.SAMBA_MODULE('ldb_objectclass_attrs',
        subsystem='ldb',
        init_function='ldb_objectclass_attrs_module_init',
        module_init_name='ldb_init_module',
-       deps='talloc samdb samba-util',
+       deps='talloc samdb DSDB_MODULE_HELPERS samba-util',
        internal_module=False,
        )