diff options
author | Stefan Metzmacher <metze@samba.org> | 2013-01-17 16:21:10 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2013-01-21 16:12:45 +0100 |
commit | 8f8d97f9fe05b2de1403676a148ab7b90a83812b (patch) | |
tree | 79bb7c6fc217fa5a7142be3cf751c3b3c8b935ea | |
parent | 8aa855573067418c84f71aa3a20e5f472343851d (diff) | |
download | samba-8f8d97f9fe05b2de1403676a148ab7b90a83812b.tar.gz samba-8f8d97f9fe05b2de1403676a148ab7b90a83812b.tar.bz2 samba-8f8d97f9fe05b2de1403676a148ab7b90a83812b.zip |
dsdb-acl: make use of acl_check_access_on_objectclass() for the object in acl_delete()
We should only use dsdb_module_check_access_on_dn() on the parent.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/acl.c | 56 |
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); } |