diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/acl.c | 220 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/acl_util.c | 255 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/config.mk | 3 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.h | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/wscript_build | 2 |
5 files changed, 260 insertions, 222 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 497e1add5c..2781b4cae5 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -64,58 +64,6 @@ struct acl_context { struct dsdb_schema *schema; }; -static struct security_token *acl_user_token(struct ldb_module *module) -{ - 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 NULL; - } - 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_operr(ldb); - } - ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn, - acl_attrs, - DSDB_FLAG_NEXT_MODULE | - 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(ldb, acl_res, - mem_ctx, - session_info->security_token, - dn, - access, - guid); -} - - static int acl_module_init(struct ldb_module *module) { struct ldb_context *ldb; @@ -189,122 +137,6 @@ done: return ldb_next_init(module); } -static const struct GUID *get_oc_guid_from_message(struct ldb_module *module, - const struct dsdb_schema *schema, - struct ldb_message *msg) -{ - struct ldb_message_element *oc_el; - - oc_el = ldb_msg_find_element(msg, "objectClass"); - if (!oc_el) { - return NULL; - } - - return class_schemaid_guid_by_lDAPDisplayName(schema, - (char *)oc_el->values[oc_el->num_values-1].data); -} - -static int acl_check_access_on_attribute(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct security_descriptor *sd, - struct dom_sid *rp_sid, - uint32_t access, - const struct dsdb_attribute *attr) -{ - int ret; - NTSTATUS status; - uint32_t access_granted; - struct object_tree *root = NULL; - struct object_tree *new_node = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - struct security_token *token = acl_user_token(module); - if (attr) { - if (!GUID_all_zero(&attr->attributeSecurityGUID)) { - if (!insert_in_object_tree(tmp_ctx, - &attr->attributeSecurityGUID, access, - &root, &new_node)) { - DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n")); - goto fail; - } - - if (!insert_in_object_tree(tmp_ctx, - &attr->schemaIDGUID, access, &new_node, &new_node)) { - DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n")); - goto fail; - } - } - else { - if (!insert_in_object_tree(tmp_ctx, - &attr->schemaIDGUID, access, &root, &new_node)) { - DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n")); - goto fail; - } - } - } - status = sec_access_check_ds(sd, token, - access, - &access_granted, - root, - rp_sid); - if (!NT_STATUS_IS_OK(status)) { - ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - } - else { - ret = LDB_SUCCESS; - } - talloc_free(tmp_ctx); - return ret; -fail: - talloc_free(tmp_ctx); - return ldb_operr(ldb_module_get_ctx(module)); -} - -static int acl_check_access_on_class(struct ldb_module *module, - const struct dsdb_schema *schema, - TALLOC_CTX *mem_ctx, - struct security_descriptor *sd, - struct dom_sid *rp_sid, - uint32_t access, - const char *class_name) -{ - int ret; - NTSTATUS status; - uint32_t access_granted; - struct object_tree *root = NULL; - struct object_tree *new_node = NULL; - const struct GUID *guid; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - struct security_token *token = acl_user_token(module); - if (class_name) { - guid = class_schemaid_guid_by_lDAPDisplayName(schema, class_name); - if (!guid) { - DEBUG(10, ("acl_search: cannot find class %s\n", - class_name)); - goto fail; - } - if (!insert_in_object_tree(tmp_ctx, - guid, access, - &root, &new_node)) { - DEBUG(10, ("acl_search: cannot add to object tree guid\n")); - goto fail; - } - } - status = sec_access_check_ds(sd, token, - access, - &access_granted, - root, - rp_sid); - if (!NT_STATUS_IS_OK(status)) { - ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - } - else { - ret = LDB_SUCCESS; - } - return ret; -fail: - return ldb_operr(ldb_module_get_ctx(module)); -} - static int acl_allowedAttributes(struct ldb_module *module, const struct dsdb_schema *schema, struct ldb_message *sd_msg, @@ -647,44 +479,6 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } -/* checks for validated writes */ -static int acl_check_extended_right(TALLOC_CTX *mem_ctx, - struct security_descriptor *sd, - struct security_token *token, - const char *ext_right, - uint32_t right_type, - struct dom_sid *sid) -{ - struct GUID right; - NTSTATUS status; - uint32_t access_granted; - struct object_tree *root = NULL; - struct object_tree *new_node = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - - GUID_from_string(ext_right, &right); - - if (!insert_in_object_tree(tmp_ctx, &right, right_type, - &root, &new_node)) { - DEBUG(10, ("acl_ext_right: cannot add to object tree\n")); - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - status = sec_access_check_ds(sd, token, - right_type, - &access_granted, - root, - sid); - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - } - talloc_free(tmp_ctx); - return LDB_SUCCESS; -} - - /* ckecks if modifications are allowed on "Member" attribute */ static int acl_check_self_membership(TALLOC_CTX *mem_ctx, struct ldb_module *module, @@ -1352,20 +1146,6 @@ static int acl_search(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, down_req); } -static const char *acl_user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) -{ - 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 "UNKNOWN (NULL)"; - } - - return talloc_asprintf(mem_ctx, "%s\\%s", - session_info->server_info->domain_name, - session_info->server_info->account_name); -} - static int acl_extended(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c new file mode 100644 index 0000000000..27d7fa8cdd --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/acl_util.c @@ -0,0 +1,255 @@ +/* + ACL utility functions + + Copyright (C) Nadezhda Ivanova 2010 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* + * Name: acl_util + * + * Component: ldb ACL modules + * + * Description: Some auxiliary functions used for access checking + * + * Author: Nadezhda Ivanova + */ +#include "includes.h" +#include "ldb_module.h" +#include "auth/auth.h" +#include "libcli/security/security.h" +#include "dsdb/samdb/samdb.h" +#include "librpc/gen_ndr/ndr_security.h" +#include "param/param.h" +#include "dsdb/samdb/ldb_modules/util.h" + +struct security_token *acl_user_token(struct ldb_module *module) +{ + 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 NULL; + } + 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_operr(ldb); + } + ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn, + acl_attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_SEARCH_SHOW_DELETED); + if (ret != LDB_SUCCESS) { + DEBUG(0,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn))); + return ret; + } + return dsdb_check_access_on_dn_internal(ldb, acl_res, + mem_ctx, + session_info->security_token, + dn, + access, + guid); +} + +int acl_check_access_on_attribute(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct security_descriptor *sd, + struct dom_sid *rp_sid, + uint32_t access, + const struct dsdb_attribute *attr) +{ + int ret; + NTSTATUS status; + uint32_t access_granted; + struct object_tree *root = NULL; + struct object_tree *new_node = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct security_token *token = acl_user_token(module); + if (attr) { + if (!GUID_all_zero(&attr->attributeSecurityGUID)) { + if (!insert_in_object_tree(tmp_ctx, + &attr->attributeSecurityGUID, access, + &root, &new_node)) { + DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n")); + goto fail; + } + + if (!insert_in_object_tree(tmp_ctx, + &attr->schemaIDGUID, access, &new_node, &new_node)) { + DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n")); + goto fail; + } + } + else { + if (!insert_in_object_tree(tmp_ctx, + &attr->schemaIDGUID, access, &root, &new_node)) { + DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n")); + goto fail; + } + } + } + status = sec_access_check_ds(sd, token, + access, + &access_granted, + root, + rp_sid); + if (!NT_STATUS_IS_OK(status)) { + ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + } + else { + ret = LDB_SUCCESS; + } + talloc_free(tmp_ctx); + return ret; +fail: + talloc_free(tmp_ctx); + return ldb_operr(ldb_module_get_ctx(module)); +} + +int acl_check_access_on_class(struct ldb_module *module, + const struct dsdb_schema *schema, + TALLOC_CTX *mem_ctx, + struct security_descriptor *sd, + struct dom_sid *rp_sid, + uint32_t access, + const char *class_name) +{ + int ret; + NTSTATUS status; + uint32_t access_granted; + struct object_tree *root = NULL; + struct object_tree *new_node = NULL; + const struct GUID *guid; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + struct security_token *token = acl_user_token(module); + if (class_name) { + guid = class_schemaid_guid_by_lDAPDisplayName(schema, class_name); + if (!guid) { + DEBUG(10, ("acl_search: cannot find class %s\n", + class_name)); + goto fail; + } + if (!insert_in_object_tree(tmp_ctx, + guid, access, + &root, &new_node)) { + DEBUG(10, ("acl_search: cannot add to object tree guid\n")); + goto fail; + } + } + status = sec_access_check_ds(sd, token, + access, + &access_granted, + root, + rp_sid); + if (!NT_STATUS_IS_OK(status)) { + ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + } + else { + ret = LDB_SUCCESS; + } + return ret; +fail: + return ldb_operr(ldb_module_get_ctx(module)); +} + +const struct GUID *get_oc_guid_from_message(struct ldb_module *module, + const struct dsdb_schema *schema, + struct ldb_message *msg) +{ + struct ldb_message_element *oc_el; + + oc_el = ldb_msg_find_element(msg, "objectClass"); + if (!oc_el) { + return NULL; + } + + return class_schemaid_guid_by_lDAPDisplayName(schema, + (char *)oc_el->values[oc_el->num_values-1].data); +} + + +/* checks for validated writes */ +int acl_check_extended_right(TALLOC_CTX *mem_ctx, + struct security_descriptor *sd, + struct security_token *token, + const char *ext_right, + uint32_t right_type, + struct dom_sid *sid) +{ + struct GUID right; + NTSTATUS status; + uint32_t access_granted; + struct object_tree *root = NULL; + struct object_tree *new_node = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + GUID_from_string(ext_right, &right); + + if (!insert_in_object_tree(tmp_ctx, &right, right_type, + &root, &new_node)) { + DEBUG(10, ("acl_ext_right: cannot add to object tree\n")); + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + status = sec_access_check_ds(sd, token, + right_type, + &access_granted, + root, + sid); + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + } + talloc_free(tmp_ctx); + return LDB_SUCCESS; +} + +const char *acl_user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) +{ + 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 "UNKNOWN (NULL)"; + } + + return talloc_asprintf(mem_ctx, "%s\\%s", + session_info->server_info->domain_name, + session_info->server_info->account_name); +} diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 4c968cd713..93ce5645b7 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -5,7 +5,8 @@ PRIVATE_DEPENDENCIES = LIBLDB LIBNDR SAMDB_SCHEMA MESSAGING DSDB_MODULE_HELPERS_OBJ_FILES = \ $(dsdbsrcdir)/samdb/ldb_modules/util.o \ - $(dsdbsrcdir)/samdb/ldb_modules/ridalloc.o + $(dsdbsrcdir)/samdb/ldb_modules/ridalloc.o \ + $(dsdbsrcdir)/samdb/ldb_modules/acl_util.o $(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c))) diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h index 8634f76d87..0d4b692da9 100644 --- a/source4/dsdb/samdb/ldb_modules/util.h +++ b/source4/dsdb/samdb/ldb_modules/util.h @@ -24,6 +24,8 @@ struct dsdb_schema; struct GUID; struct dsdb_attribute; struct dsdb_fsmo_extended_op; +struct security_descriptor; +struct dom_sid; #include "dsdb/samdb/ldb_modules/util_proto.h" #include "dsdb/common/util.h" diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build b/source4/dsdb/samdb/ldb_modules/wscript_build index c8461d6ecc..f6b5c28456 100644 --- a/source4/dsdb/samdb/ldb_modules/wscript_build +++ b/source4/dsdb/samdb/ldb_modules/wscript_build @@ -1,7 +1,7 @@ #!/usr/bin/env python bld.SAMBA_SUBSYSTEM('DSDB_MODULE_HELPERS', - source='util.c ridalloc.c', + source='util.c ridalloc.c acl_util.c', autoproto='util_proto.h', deps='ldb LIBNDR SAMDB_SCHEMA MESSAGING' ) |