summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/acl.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index 0ab96709be..41c257b999 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -1163,6 +1163,17 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
struct ldb_context *ldb;
struct ldb_dn *nc_root;
struct ldb_control *as_system;
+ const struct dsdb_schema *schema;
+ const struct dsdb_class *objectclass;
+ struct security_descriptor *sd = NULL;
+ struct dom_sid *sid = NULL;
+ struct ldb_result *acl_res;
+ static const char *acl_attrs[] = {
+ "nTSecurityDescriptor",
+ "objectClass",
+ "objectSid",
+ NULL
+ };
if (ldb_dn_is_special(req->op.del.dn)) {
return ldb_next_request(module, req);
@@ -1201,11 +1212,43 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
}
talloc_free(nc_root);
+ ret = dsdb_module_search_dn(module, req, &acl_res,
+ req->op.del.dn, acl_attrs,
+ DSDB_FLAG_NEXT_MODULE |
+ DSDB_FLAG_AS_SYSTEM |
+ DSDB_SEARCH_SHOW_RECYCLED, req);
+ /* we sould be able to find the parent */
+ if (ret != LDB_SUCCESS) {
+ DEBUG(10,("acl: failed to find object %s\n",
+ ldb_dn_get_linearized(req->op.rename.olddn)));
+ return ret;
+ }
+
+ ret = dsdb_get_sd_from_ldb_message(ldb, req, acl_res->msgs[0], &sd);
+ if (ret != LDB_SUCCESS) {
+ return ldb_operr(ldb);
+ }
+ if (!sd) {
+ return ldb_operr(ldb);
+ }
+
+ schema = dsdb_get_schema(ldb, req);
+ if (!schema) {
+ return ldb_operr(ldb);
+ }
+
+ sid = samdb_result_dom_sid(req, acl_res->msgs[0], "objectSid");
+
+ objectclass = dsdb_get_structural_oc_from_msg(schema, acl_res->msgs[0]);
+ if (!objectclass) {
+ return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR,
+ "acl_modify: Error retrieving object class for GUID.");
+ }
+
if (ldb_request_get_control(req, LDB_CONTROL_TREE_DELETE_OID)) {
- ret = dsdb_module_check_access_on_dn(module, req,
- req->op.del.dn,
- SEC_ADS_DELETE_TREE, NULL,
- req);
+ ret = acl_check_access_on_objectclass(module, req, sd, sid,
+ SEC_ADS_DELETE_TREE,
+ objectclass);
if (ret != LDB_SUCCESS) {
return ret;
}
@@ -1214,8 +1257,9 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
}
/* First check if we have delete object right */
- ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn,
- SEC_STD_DELETE, NULL, req);
+ ret = acl_check_access_on_objectclass(module, req, sd, sid,
+ SEC_STD_DELETE,
+ objectclass);
if (ret == LDB_SUCCESS) {
return ldb_next_request(module, req);
}