From be79f572ed2a5853917eeede3991c1674ad655a6 Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Fri, 12 Mar 2010 03:13:51 +0200 Subject: [PATCH] Split the dsdb_access_check_on_dn. Split the dsdb_access_check_on_dn so it can be reused for checks from both within the module stack and outside it. --- source4/dsdb/common/dsdb_access.c | 85 +++++++++++++++++++++--------------- source4/dsdb/samdb/ldb_modules/acl.c | 49 ++++++++++++++++++--- 2 files changed, 93 insertions(+), 41 deletions(-) diff --git a/source4/dsdb/common/dsdb_access.c b/source4/dsdb/common/dsdb_access.c index 1f8b795a7bd..40233f9379d 100644 --- a/source4/dsdb/common/dsdb_access.c +++ b/source4/dsdb/common/dsdb_access.c @@ -26,22 +26,13 @@ */ #include "includes.h" -#include "events/events.h" #include "ldb.h" #include "ldb_errors.h" -#include "../lib/util/util_ldb.h" -#include "../lib/crypto/crypto.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "../libds/common/flags.h" #include "libcli/ldap/ldap_ndr.h" #include "param/param.h" -#include "libcli/auth/libcli_auth.h" -#include "librpc/gen_ndr/ndr_drsblobs.h" -#include "system/locale.h" #include "auth/auth.h" -#include "lib/util/tsort.h" void dsdb_acl_debug(struct security_descriptor *sd, struct security_token *token, @@ -113,38 +104,20 @@ int dsdb_get_dom_sid_from_ldb_message(TALLOC_CTX *mem_ctx, return LDB_SUCCESS; } -int dsdb_check_access_on_dn(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - uint32_t access, - const struct GUID *guid) +int dsdb_check_access_on_dn_internal(struct ldb_result *acl_res, + TALLOC_CTX *mem_ctx, + struct security_token *token, + struct ldb_dn *dn, + uint32_t access, + const struct GUID *guid) { - int ret; - struct ldb_result *acl_res; struct security_descriptor *sd = NULL; struct dom_sid *sid = NULL; struct object_tree *root = NULL; struct object_tree *new_node = NULL; NTSTATUS status; uint32_t access_granted; - static const char *acl_attrs[] = { - "nTSecurityDescriptor", - "objectSid", - NULL - }; - - struct auth_session_info *session_info - = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo"); - if(!session_info) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search(ldb, mem_ctx, &acl_res, dn, LDB_SCOPE_BASE, acl_attrs, NULL); - /* 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(dn))); - return ret; - } + int ret; ret = dsdb_get_sd_from_ldb_message(mem_ctx, acl_res->msgs[0], &sd); if (ret != LDB_SUCCESS) { @@ -164,14 +137,14 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb, return LDB_ERR_OPERATIONS_ERROR; } } - status = sec_access_check_ds(sd, session_info->security_token, + status = sec_access_check_ds(sd, token, access, &access_granted, root, sid); if (!NT_STATUS_IS_OK(status)) { dsdb_acl_debug(sd, - session_info->security_token, + token, dn, true, 10); @@ -179,3 +152,43 @@ int dsdb_check_access_on_dn(struct ldb_context *ldb, } return LDB_SUCCESS; } + +/* performs an access check from outside the module stack + * given the dn of the object to be checked, the required access + * guid is either the guid of the extended right, or NULL + */ + +int dsdb_check_access_on_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + uint32_t access, + const struct GUID *guid) +{ + int ret; + struct ldb_result *acl_res; + static const char *acl_attrs[] = { + "nTSecurityDescriptor", + "objectSid", + NULL + }; + + struct auth_session_info *session_info + = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo"); + if(!session_info) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search(ldb, mem_ctx, &acl_res, dn, LDB_SCOPE_BASE, acl_attrs, NULL); + if (ret != LDB_SUCCESS) { + DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn))); + return ret; + } + + return dsdb_check_access_on_dn_internal(acl_res, + mem_ctx, + session_info->security_token, + dn, + access, + guid); +} + diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 9280de1b97c..b0c1e2fa9e2 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -82,6 +82,45 @@ static struct security_token *acl_user_token(struct ldb_module *module) return session_info->security_token; } +/* performs an access check from inside the module stack + * given the dn of the object to be checked, the required access + * guid is either the guid of the extended right, or NULL + */ + +int dsdb_module_check_access_on_dn(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + uint32_t access, + const struct GUID *guid) +{ + int ret; + struct ldb_result *acl_res; + static const char *acl_attrs[] = { + "nTSecurityDescriptor", + "objectSid", + NULL + }; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct auth_session_info *session_info + = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo"); + if(!session_info) { + return LDB_ERR_OPERATIONS_ERROR; + } + ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn, + acl_attrs, DSDB_SEARCH_SHOW_DELETED); + if (ret != LDB_SUCCESS) { + DEBUG(10,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn))); + return ret; + } + return dsdb_check_access_on_dn_internal(acl_res, + mem_ctx, + session_info->security_token, + dn, + access, + guid); +} + + static int acl_module_init(struct ldb_module *module) { struct ldb_context *ldb; @@ -606,7 +645,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req) guid = class_schemaid_guid_by_lDAPDisplayName(dsdb_get_schema(ldb), (char *)oc_el->values[oc_el->num_values-1].data); - ret = dsdb_check_access_on_dn(ldb, req, parent, SEC_ADS_CREATE_CHILD, guid); + ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_CREATE_CHILD, guid); if (ret != LDB_SUCCESS) { return ret; } @@ -787,7 +826,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req) } ldb = ldb_module_get_ctx(module); /* first check if we have delete object right */ - ret = dsdb_check_access_on_dn(ldb, req, req->op.del.dn, SEC_STD_DELETE, NULL); + ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn, SEC_STD_DELETE, NULL); if (ret == LDB_SUCCESS) { return ldb_next_request(module, req); } @@ -801,7 +840,7 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req) return ldb_module_done(req, NULL, NULL, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS); } - ret = dsdb_check_access_on_dn(ldb, req, parent, SEC_ADS_DELETE_CHILD, NULL); + ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_DELETE_CHILD, NULL); if (ret != LDB_SUCCESS) { return ret; } @@ -932,7 +971,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req) return ldb_module_done(req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } - ret = dsdb_check_access_on_dn(ldb, req, newparent, SEC_ADS_CREATE_CHILD, guid); + ret = dsdb_module_check_access_on_dn(module, req, newparent, SEC_ADS_CREATE_CHILD, guid); if (ret != LDB_SUCCESS) { DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn))); return ret; @@ -949,7 +988,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } /* what about delete child on the current parent */ - ret = dsdb_check_access_on_dn(ldb, req, oldparent, SEC_ADS_DELETE_CHILD, NULL); + ret = dsdb_module_check_access_on_dn(module, req, oldparent, SEC_ADS_DELETE_CHILD, NULL); if (ret != LDB_SUCCESS) { DEBUG(10,("acl:access_denied renaming %s", ldb_dn_get_linearized(req->op.rename.olddn))); return ldb_module_done(req, NULL, NULL, ret); -- 2.11.4.GIT