473 lines
17 KiB
Diff
473 lines
17 KiB
Diff
From ae9eb6c7d85deda7a20867eeecb8835defc1990a Mon Sep 17 00:00:00 2001
|
|
From: Nadezhda Ivanova <nivanova@symas.com>
|
|
Date: Mon, 18 Oct 2021 14:27:59 +0300
|
|
Subject: [PATCH 136/266] CVE-2020-25722: s4-acl: Make sure Control Access
|
|
Rights honor the Applies-to attribute
|
|
|
|
Validate Writes and Control Access Rights only grant access if the
|
|
object is of the type listed in the Right's appliesTo attribute. For
|
|
example, even though a Validated-SPN access may be granted to a user
|
|
object in the SD, it should only pass if the object is of class
|
|
computer This patch enforces the appliesTo attribute classes for
|
|
access checks from within the ldb stack.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14832
|
|
|
|
Signed-off-by: Nadezhda Ivanova <nivanova@symas.com>
|
|
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
|
|
Conflict:NA
|
|
Reference:https://gitlab.com/samba-team/samba/-/commit/ae9eb6c7d85deda7a20867eeecb8835defc1990a
|
|
---
|
|
source4/dsdb/common/util.c | 11 +++
|
|
source4/dsdb/samdb/ldb_modules/acl.c | 87 +++++++++++++++++++----
|
|
source4/dsdb/samdb/ldb_modules/acl_util.c | 40 +++++++++++
|
|
source4/dsdb/samdb/ldb_modules/dirsync.c | 13 +++-
|
|
source4/dsdb/samdb/ldb_modules/samldb.c | 56 ++++++++-------
|
|
6 files changed, 168 insertions(+), 40 deletions(-)
|
|
delete mode 100644 selftest/knownfail.d/bug-14832
|
|
|
|
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
|
|
index ef03782f588..62e04d08003 100644
|
|
--- a/source4/dsdb/common/util.c
|
|
+++ b/source4/dsdb/common/util.c
|
|
@@ -1179,6 +1179,17 @@ struct ldb_dn *samdb_sites_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
|
|
return new_dn;
|
|
}
|
|
|
|
+struct ldb_dn *samdb_extended_rights_dn(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx)
|
|
+{
|
|
+ struct ldb_dn *new_dn;
|
|
+
|
|
+ new_dn = ldb_dn_copy(mem_ctx, ldb_get_config_basedn(sam_ctx));
|
|
+ if ( ! ldb_dn_add_child_fmt(new_dn, "CN=Extended-Rights")) {
|
|
+ talloc_free(new_dn);
|
|
+ return NULL;
|
|
+ }
|
|
+ return new_dn;
|
|
+}
|
|
/*
|
|
work out the domain sid for the current open ldb
|
|
*/
|
|
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
|
|
index b1bbf936006..9cae15881de 100644
|
|
--- a/source4/dsdb/samdb/ldb_modules/acl.c
|
|
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
|
|
@@ -698,7 +698,12 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx,
|
|
return LDB_SUCCESS;
|
|
}
|
|
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_VALIDATE_SPN,
|
|
SEC_ADS_SELF_WRITE,
|
|
sid);
|
|
@@ -911,7 +916,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
|
|
return ldb_next_request(module, req);
|
|
}
|
|
|
|
-/* ckecks if modifications are allowed on "Member" attribute */
|
|
+/* checks if modifications are allowed on "Member" attribute */
|
|
static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
|
struct ldb_module *module,
|
|
struct ldb_request *req,
|
|
@@ -925,6 +930,16 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
|
struct ldb_context *ldb = ldb_module_get_ctx(module);
|
|
struct ldb_dn *user_dn;
|
|
struct ldb_message_element *member_el;
|
|
+ const struct ldb_message *msg = NULL;
|
|
+
|
|
+ if (req->operation == LDB_MODIFY) {
|
|
+ msg = req->op.mod.message;
|
|
+ } else if (req->operation == LDB_ADD) {
|
|
+ msg = req->op.add.message;
|
|
+ } else {
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
|
+ }
|
|
+
|
|
/* if we have wp, we can do whatever we like */
|
|
if (acl_check_access_on_attribute(module,
|
|
mem_ctx,
|
|
@@ -935,13 +950,13 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
|
return LDB_SUCCESS;
|
|
}
|
|
/* if we are adding/deleting ourselves, check for self membership */
|
|
- ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
|
|
- &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
|
|
+ ret = dsdb_find_dn_by_sid(ldb, mem_ctx,
|
|
+ &acl_user_token(module)->sids[PRIMARY_USER_SID_INDEX],
|
|
&user_dn);
|
|
if (ret != LDB_SUCCESS) {
|
|
return ret;
|
|
}
|
|
- member_el = ldb_msg_find_element(req->op.mod.message, "member");
|
|
+ member_el = ldb_msg_find_element(msg, "member");
|
|
if (!member_el) {
|
|
return ldb_operr(ldb);
|
|
}
|
|
@@ -955,13 +970,18 @@ static int acl_check_self_membership(TALLOC_CTX *mem_ctx,
|
|
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
|
}
|
|
}
|
|
- ret = acl_check_extended_right(mem_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(mem_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_SELF_MEMBERSHIP,
|
|
SEC_ADS_SELF_WRITE,
|
|
sid);
|
|
if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
|
|
dsdb_acl_debug(sd, acl_user_token(module),
|
|
- req->op.mod.message->dn,
|
|
+ msg->dn,
|
|
true,
|
|
10);
|
|
}
|
|
@@ -1021,6 +1041,9 @@ static int acl_check_password_rights(
|
|
* so we don't have to strict verification of the input.
|
|
*/
|
|
ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
sd,
|
|
acl_user_token(module),
|
|
GUID_DRS_USER_CHANGE_PASSWORD,
|
|
@@ -1044,7 +1067,12 @@ static int acl_check_password_rights(
|
|
* the only caller is samdb_set_password_internal(),
|
|
* so we don't have to strict verification of the input.
|
|
*/
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
sid);
|
|
@@ -1097,7 +1125,12 @@ static int acl_check_password_rights(
|
|
if (rep_attr_cnt > 0) {
|
|
pav->pwd_reset = true;
|
|
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
sid);
|
|
@@ -1107,7 +1140,12 @@ static int acl_check_password_rights(
|
|
if (add_attr_cnt != del_attr_cnt) {
|
|
pav->pwd_reset = true;
|
|
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
sid);
|
|
@@ -1117,7 +1155,12 @@ static int acl_check_password_rights(
|
|
if (add_val_cnt == 1 && del_val_cnt == 1) {
|
|
pav->pwd_reset = false;
|
|
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_USER_CHANGE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
sid);
|
|
@@ -1131,7 +1174,12 @@ static int acl_check_password_rights(
|
|
if (add_val_cnt == 1 && del_val_cnt == 0) {
|
|
pav->pwd_reset = true;
|
|
|
|
- ret = acl_check_extended_right(tmp_ctx, sd, acl_user_token(module),
|
|
+ ret = acl_check_extended_right(tmp_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_FORCE_CHANGE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
sid);
|
|
@@ -1686,6 +1734,9 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx,
|
|
struct ldb_result *acl_res;
|
|
struct security_descriptor *sd = NULL;
|
|
struct dom_sid *sid = NULL;
|
|
+ const struct dsdb_schema *schema = NULL;
|
|
+ const struct dsdb_class *objectclass = NULL;
|
|
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
|
|
static const char *acl_attrs[] = {
|
|
"nTSecurityDescriptor",
|
|
"objectClass",
|
|
@@ -1706,10 +1757,20 @@ static int acl_check_reanimate_tombstone(TALLOC_CTX *mem_ctx,
|
|
|
|
ret = dsdb_get_sd_from_ldb_message(mem_ctx, req, acl_res->msgs[0], &sd);
|
|
sid = samdb_result_dom_sid(mem_ctx, acl_res->msgs[0], "objectSid");
|
|
+ schema = dsdb_get_schema(ldb, req);
|
|
+ if (!schema) {
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
|
+ }
|
|
+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]);
|
|
if (ret != LDB_SUCCESS || !sd) {
|
|
return ldb_operr(ldb_module_get_ctx(module));
|
|
}
|
|
- return acl_check_extended_right(mem_ctx, sd, acl_user_token(module),
|
|
+ return acl_check_extended_right(mem_ctx,
|
|
+ module,
|
|
+ req,
|
|
+ objectclass,
|
|
+ sd,
|
|
+ acl_user_token(module),
|
|
GUID_DRS_REANIMATE_TOMBSTONE,
|
|
SEC_ADS_CONTROL_ACCESS, sid);
|
|
}
|
|
diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c
|
|
index f917d99517a..08a95c1c310 100644
|
|
--- a/source4/dsdb/samdb/ldb_modules/acl_util.c
|
|
+++ b/source4/dsdb/samdb/ldb_modules/acl_util.c
|
|
@@ -197,6 +197,9 @@ fail:
|
|
|
|
/* checks for validated writes */
|
|
int acl_check_extended_right(TALLOC_CTX *mem_ctx,
|
|
+ struct ldb_module *module,
|
|
+ struct ldb_request *req,
|
|
+ const struct dsdb_class *objectclass,
|
|
struct security_descriptor *sd,
|
|
struct security_token *token,
|
|
const char *ext_right,
|
|
@@ -208,6 +211,43 @@ int acl_check_extended_right(TALLOC_CTX *mem_ctx,
|
|
uint32_t access_granted;
|
|
struct object_tree *root = NULL;
|
|
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
|
|
+ static const char *no_attrs[] = { NULL };
|
|
+ struct ldb_result *extended_rights_res = NULL;
|
|
+ struct ldb_dn *extended_rights_dn = NULL;
|
|
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
|
|
+ int ret = 0;
|
|
+
|
|
+ /*
|
|
+ * Find the extended right and check if applies to
|
|
+ * the objectclass of the object
|
|
+ */
|
|
+ extended_rights_dn = samdb_extended_rights_dn(ldb, req);
|
|
+ if (!extended_rights_dn) {
|
|
+ ldb_set_errstring(ldb,
|
|
+ "access_check: CN=Extended-Rights dn could not be generated!");
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
|
+ }
|
|
+
|
|
+ /* Note: we are checking only the structural object class. */
|
|
+ ret = dsdb_module_search(module, req, &extended_rights_res,
|
|
+ extended_rights_dn, LDB_SCOPE_ONELEVEL,
|
|
+ no_attrs,
|
|
+ DSDB_FLAG_NEXT_MODULE |
|
|
+ DSDB_FLAG_AS_SYSTEM,
|
|
+ req,
|
|
+ "(&(rightsGuid=%s)(appliesTo=%s))",
|
|
+ ext_right,
|
|
+ GUID_string(tmp_ctx,
|
|
+ &(objectclass->schemaIDGUID)));
|
|
+
|
|
+ if (ret != LDB_SUCCESS) {
|
|
+ return ret;
|
|
+ } else if (extended_rights_res->count == 0 ) {
|
|
+ ldb_debug(ldb, LDB_DEBUG_TRACE,
|
|
+ "acl_check_extended_right: Could not find appliesTo for %s\n",
|
|
+ ext_right);
|
|
+ return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
|
+ }
|
|
|
|
GUID_from_string(ext_right, &right);
|
|
|
|
diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c
|
|
index 21555491159..a58e290607c 100644
|
|
--- a/source4/dsdb/samdb/ldb_modules/dirsync.c
|
|
+++ b/source4/dsdb/samdb/ldb_modules/dirsync.c
|
|
@@ -1065,7 +1065,9 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
|
|
if (!(dirsync_ctl->flags & LDAP_DIRSYNC_OBJECT_SECURITY)) {
|
|
struct dom_sid *sid;
|
|
struct security_descriptor *sd = NULL;
|
|
- const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", NULL };
|
|
+ const char *acl_attrs[] = { "nTSecurityDescriptor", "objectSid", "objectClass", NULL };
|
|
+ const struct dsdb_schema *schema = NULL;
|
|
+ const struct dsdb_class *objectclass = NULL;
|
|
/*
|
|
* If we don't have the flag and if we have the "replicate directory change" granted
|
|
* then we upgrade ourself to system to not be blocked by the acl
|
|
@@ -1095,7 +1097,14 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req
|
|
if (ret != LDB_SUCCESS) {
|
|
return ret;
|
|
}
|
|
- ret = acl_check_extended_right(dsc, sd, acl_user_token(module), GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid);
|
|
+ schema = dsdb_get_schema(ldb, req);
|
|
+ if (!schema) {
|
|
+ return LDB_ERR_OPERATIONS_ERROR;
|
|
+ }
|
|
+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]);
|
|
+ ret = acl_check_extended_right(dsc, module, req, objectclass,
|
|
+ sd, acl_user_token(module),
|
|
+ GUID_DRS_GET_CHANGES, SEC_ADS_CONTROL_ACCESS, sid);
|
|
|
|
if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) {
|
|
return ret;
|
|
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
|
|
index 5352af1099f..6db7840b0c1 100644
|
|
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
|
|
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
|
|
@@ -2192,12 +2192,15 @@ static int samldb_check_user_account_control_objectclass_invariants(
|
|
return LDB_SUCCESS;
|
|
}
|
|
|
|
-static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
|
- struct security_descriptor **domain_sd)
|
|
+static int samldb_get_domain_secdesc_and_oc(struct samldb_ctx *ac,
|
|
+ struct security_descriptor **domain_sd,
|
|
+ const struct dsdb_class **objectclass)
|
|
{
|
|
- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
|
+ const char * const sd_attrs[] = {"ntSecurityDescriptor", "objectClass", NULL};
|
|
struct ldb_result *res;
|
|
struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
|
+ const struct dsdb_schema *schema = NULL;
|
|
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
|
int ret = dsdb_module_search_dn(ac->module, ac, &res,
|
|
domain_dn,
|
|
sd_attrs,
|
|
@@ -2210,6 +2213,11 @@ static int samldb_get_domain_secdesc(struct samldb_ctx *ac,
|
|
return ldb_module_operr(ac->module);
|
|
}
|
|
|
|
+ schema = dsdb_get_schema(ldb, ac->req);
|
|
+ if (!schema) {
|
|
+ return ldb_module_operr(ac->module);;
|
|
+ }
|
|
+ *objectclass = dsdb_get_structural_oc_from_msg(schema, res->msgs[0]);
|
|
return dsdb_get_sd_from_ldb_message(ldb_module_get_ctx(ac->module),
|
|
ac, res->msgs[0], domain_sd);
|
|
|
|
@@ -2228,6 +2236,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
|
bool need_acl_check = false;
|
|
struct security_token *user_token;
|
|
struct security_descriptor *domain_sd;
|
|
+ const struct dsdb_class *objectclass = NULL;
|
|
const struct uac_to_guid {
|
|
uint32_t uac;
|
|
uint32_t priv_to_change_from;
|
|
@@ -2313,7 +2322,7 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
|
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
|
}
|
|
|
|
- ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
|
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
|
if (ret != LDB_SUCCESS) {
|
|
return ret;
|
|
}
|
|
@@ -2344,7 +2353,11 @@ static int samldb_check_user_account_control_acl(struct samldb_ctx *ac,
|
|
ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
|
}
|
|
} else if (map[i].guid) {
|
|
- ret = acl_check_extended_right(ac, domain_sd,
|
|
+ ret = acl_check_extended_right(ac,
|
|
+ ac->module,
|
|
+ ac->req,
|
|
+ objectclass,
|
|
+ domain_sd,
|
|
user_token,
|
|
map[i].guid,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
@@ -2684,12 +2697,11 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac,
|
|
{
|
|
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
|
int ret = 0;
|
|
- struct ldb_result *res = NULL;
|
|
- const char * const sd_attrs[] = {"ntSecurityDescriptor", NULL};
|
|
struct security_token *user_token = NULL;
|
|
struct security_descriptor *domain_sd = NULL;
|
|
struct ldb_dn *domain_dn = ldb_get_default_basedn(ldb_module_get_ctx(ac->module));
|
|
const char *operation = "";
|
|
+ const struct dsdb_class *objectclass = NULL;
|
|
|
|
if (dsdb_module_am_system(ac->module)) {
|
|
return LDB_SUCCESS;
|
|
@@ -2711,24 +2723,15 @@ static int samldb_check_pwd_last_set_acl(struct samldb_ctx *ac,
|
|
return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
|
}
|
|
|
|
- ret = dsdb_module_search_dn(ac->module, ac, &res,
|
|
- domain_dn,
|
|
- sd_attrs,
|
|
- DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED,
|
|
- ac->req);
|
|
- if (ret != LDB_SUCCESS) {
|
|
- return ret;
|
|
- }
|
|
- if (res->count != 1) {
|
|
- return ldb_module_operr(ac->module);
|
|
- }
|
|
-
|
|
- ret = dsdb_get_sd_from_ldb_message(ldb, ac, res->msgs[0], &domain_sd);
|
|
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
|
if (ret != LDB_SUCCESS) {
|
|
return ret;
|
|
}
|
|
-
|
|
- ret = acl_check_extended_right(ac, domain_sd,
|
|
+ ret = acl_check_extended_right(ac,
|
|
+ ac->module,
|
|
+ ac->req,
|
|
+ objectclass,
|
|
+ domain_sd,
|
|
user_token,
|
|
GUID_DRS_UNEXPIRE_PASSWORD,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
@@ -3758,16 +3761,21 @@ static int samldb_check_sensitive_attributes(struct samldb_ctx *ac)
|
|
el = ldb_msg_find_element(ac->msg, "msDS-SecondaryKrbTgtNumber");
|
|
if (el) {
|
|
struct security_descriptor *domain_sd;
|
|
+ const struct dsdb_class *objectclass = NULL;
|
|
/*
|
|
* msDS-SecondaryKrbTgtNumber allows the creator to
|
|
* become an RODC, this is trusted as an RODC
|
|
* account
|
|
*/
|
|
- ret = samldb_get_domain_secdesc(ac, &domain_sd);
|
|
+ ret = samldb_get_domain_secdesc_and_oc(ac, &domain_sd, &objectclass);
|
|
if (ret != LDB_SUCCESS) {
|
|
return ret;
|
|
}
|
|
- ret = acl_check_extended_right(ac, domain_sd,
|
|
+ ret = acl_check_extended_right(ac,
|
|
+ ac->module,
|
|
+ ac->req,
|
|
+ objectclass,
|
|
+ domain_sd,
|
|
user_token,
|
|
GUID_DRS_DS_INSTALL_REPLICA,
|
|
SEC_ADS_CONTROL_ACCESS,
|
|
--
|
|
2.23.0
|
|
|