From: Garming Sam Date: Mon, 6 Mar 2017 23:30:09 +0000 (+1300) Subject: objectclass_attrs: Restrict systemOnly attributes X-Git-Tag: tdb-1.3.13~482 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c4aa78ba875f3a9ca4e586823ce63826da8daa90;p=thirdparty%2Fsamba.git objectclass_attrs: Restrict systemOnly attributes This allows restriction of auditing attributes from being wiped. Modifications of the RID Set must be done as SYSTEM. Signed-off-by: Garming Sam Reviewed-by: Andrew Bartlett --- diff --git a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c index c144578f227..cfacaf56420 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass_attrs.c @@ -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]); diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 730272a50ce..abfe14a5a80 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -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)); diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build_server b/source4/dsdb/samdb/ldb_modules/wscript_build_server index 8131566ff5c..41b3fe70b37 100644 --- a/source4/dsdb/samdb/ldb_modules/wscript_build_server +++ b/source4/dsdb/samdb/ldb_modules/wscript_build_server @@ -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, )