From b57928ae1ef4a30ab134a501800f78abfd057813 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 16:12:22 +0100 Subject: [PATCH 01/22] s4:dsdb/schema_data: fix debug message in schema_data_modify() Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit ac9bd1e63a8adfb96eb5c9f996e60c2d99aba5e1) --- source4/dsdb/samdb/ldb_modules/schema_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/schema_data.c b/source4/dsdb/samdb/ldb_modules/schema_data.c index 3e0bb9c..223d698 100644 --- a/source4/dsdb/samdb/ldb_modules/schema_data.c +++ b/source4/dsdb/samdb/ldb_modules/schema_data.c @@ -325,7 +325,7 @@ static int schema_data_modify(struct ldb_module *module, struct ldb_request *req if (!schema->fsmo.update_allowed && !rodc) { ldb_debug_set(ldb, LDB_DEBUG_ERROR, - "schema_data_add: updates are not allowed: reject request\n"); + "schema_data_modify: updates are not allowed: reject request\n"); return LDB_ERR_UNWILLING_TO_PERFORM; } -- 1.7.9.5 From 65738e485f60fe62ced2f290ae38ccc302b80863 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Nov 2012 14:49:11 +0100 Subject: [PATCH 02/22] s4:dsdb/dirsync: check result of replUpToDateVector fetch on nc_root Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 7fe1e61ab908264f2ac7b8df666b254ae2af4488) --- source4/dsdb/samdb/ldb_modules/dirsync.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c index 3f22f15..701170a 100644 --- a/source4/dsdb/samdb/ldb_modules/dirsync.c +++ b/source4/dsdb/samdb/ldb_modules/dirsync.c @@ -729,6 +729,10 @@ static int dirsync_create_vector(struct ldb_request *req, nc_root, attrVector, DSDB_FLAG_NEXT_MODULE, req); + if (ret != LDB_SUCCESS) { + return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, + "Unable to get replUpToDateVector for current NC"); + } if (resVector->count != 0) { DATA_BLOB blob; -- 1.7.9.5 From d50e481278e934e6340a55c615bc6904a2b4fa15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 09:51:45 +0100 Subject: [PATCH 03/22] s4:dsdb/dirsync: use the correct nc_root to fetch replUpToDateVector Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 6991fb385e3956892d904f871052aaede1137a29) --- source4/dsdb/samdb/ldb_modules/dirsync.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c index 701170a..5b00566 100644 --- a/source4/dsdb/samdb/ldb_modules/dirsync.c +++ b/source4/dsdb/samdb/ldb_modules/dirsync.c @@ -705,12 +705,10 @@ static int dirsync_create_vector(struct ldb_request *req, struct ldb_result *resVector; const char* attrVector[] = {"replUpToDateVector", NULL }; uint64_t highest_usn; - struct ldb_dn *nc_root; uint32_t count = 1; int ret; struct drsuapi_DsReplicaCursor *tab; - nc_root = ldb_get_default_basedn(ldb); ret = ldb_sequence_number(ldb, LDB_SEQ_HIGHEST_SEQ, &highest_usn); if (ret != LDB_SUCCESS) { return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "Unable to get highest USN from current NC"); @@ -726,7 +724,7 @@ static int dirsync_create_vector(struct ldb_request *req, ret = dsdb_module_search_dn(dsc->module, dsc, &resVector, - nc_root, + dsc->nc_root, attrVector, DSDB_FLAG_NEXT_MODULE, req); if (ret != LDB_SUCCESS) { -- 1.7.9.5 From 52356e1a2e54acd43b5e1bbce46a4ef3a8e1bfb3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2012 08:59:40 +0100 Subject: [PATCH 04/22] s4:dsdb/dirsync: explicitly ask for sdctr->secinfo_flags = 0xF A value of 0 is mapped to 0xF. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 8563348a01206874ff215a55d0c542912740e84b) --- source4/dsdb/samdb/ldb_modules/dirsync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/dirsync.c b/source4/dsdb/samdb/ldb_modules/dirsync.c index 5b00566..662d0c3 100644 --- a/source4/dsdb/samdb/ldb_modules/dirsync.c +++ b/source4/dsdb/samdb/ldb_modules/dirsync.c @@ -1121,7 +1121,7 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req */ if (ldb_attr_in_list(attrs, "*")) { struct ldb_sd_flags_control *sdctr = talloc_zero(dsc, struct ldb_sd_flags_control); - sdctr->secinfo_flags = 0; + sdctr->secinfo_flags = 0xF; ret = ldb_request_add_control(req, LDB_CONTROL_SD_FLAGS_OID, false, sdctr); if (ret != LDB_SUCCESS) { return ret; @@ -1186,7 +1186,7 @@ static int dirsync_ldb_search(struct ldb_module *module, struct ldb_request *req } } else { struct ldb_sd_flags_control *sdctr = talloc_zero(dsc, struct ldb_sd_flags_control); - sdctr->secinfo_flags = 0; + sdctr->secinfo_flags = 0xF; ret = ldb_request_add_control(req, LDB_CONTROL_SD_FLAGS_OID, false, sdctr); attrs = talloc_array(dsc, const char*, 4); if (attrs == NULL) { -- 1.7.9.5 From 5e57d320e6db33840d2985e23f575e765e43a0a9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Nov 2012 13:38:07 +0100 Subject: [PATCH 05/22] s4:dsdb/rootdse: remove unused variable Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 964d96d2c31211601b8854dd3d532112fd2aaece) --- source4/dsdb/samdb/ldb_modules/rootdse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 0668d1a..4096214 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -1220,7 +1220,6 @@ static int rootdse_schemaupdatenow(struct ldb_module *module, struct ldb_request static int rootdse_schemaupgradeinprogress(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_result *ext_res; int ret = LDB_SUCCESS; struct ldb_dn *schema_dn; -- 1.7.9.5 From ca9b87ff1d77ec610a3b37722bf9201df9f4d4a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 12 Nov 2012 14:19:34 +0100 Subject: [PATCH 06/22] s4:dsdb/rootdse: do helper searches AS_SYSTEM As anonymous users can read all rootdse attributes, we should do helper searches with DSDB_FLAG_AS_SYSTEM in order to avoid unnecessary access checks. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit a882b41d44b20476a0b1549260e07be3398f9752) --- source4/dsdb/samdb/ldb_modules/rootdse.c | 36 ++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 4096214..ba71b5f 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -183,7 +183,11 @@ static int dsdb_module_we_are_master(struct ldb_module *module, struct ldb_dn *d struct ldb_dn *owner_dn; ret = dsdb_module_search_dn(module, tmp_ctx, &res, - dn, attrs, DSDB_FLAG_NEXT_MODULE|DSDB_SEARCH_SHOW_EXTENDED_DN, parent); + dn, attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_EXTENDED_DN, + parent); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -259,7 +263,10 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms int ret; const char *dns_attrs[] = { "dNSHostName", NULL }; ret = dsdb_module_search_dn(module, msg, &res, samdb_server_dn(ldb, msg), - dns_attrs, DSDB_FLAG_NEXT_MODULE, req); + dns_attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + req); if (ret == LDB_SUCCESS) { const char *hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL); if (hostname != NULL) { @@ -486,7 +493,9 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms ret = dsdb_module_search_dn(module, req, &res, attr_dn, no_attrs, - DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_EXTENDED_DN, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_EXTENDED_DN, req); if (ret != LDB_SUCCESS) { return ldb_operr(ldb); @@ -887,7 +896,10 @@ static int rootdse_init(struct ldb_module *module) */ ret = dsdb_module_search(module, mem_ctx, &res, ldb_get_default_basedn(ldb), - LDB_SCOPE_BASE, attrs, DSDB_FLAG_NEXT_MODULE, NULL, NULL); + LDB_SCOPE_BASE, attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + NULL, NULL); if (ret == LDB_SUCCESS && res->count == 1) { int domain_behaviour_version = ldb_msg_find_attr_as_int(res->msgs[0], @@ -909,7 +921,10 @@ static int rootdse_init(struct ldb_module *module) ret = dsdb_module_search(module, mem_ctx, &res, samdb_partitions_dn(ldb, mem_ctx), - LDB_SCOPE_BASE, attrs, DSDB_FLAG_NEXT_MODULE, NULL, NULL); + LDB_SCOPE_BASE, attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + NULL, NULL); if (ret == LDB_SUCCESS && res->count == 1) { int forest_behaviour_version = ldb_msg_find_attr_as_int(res->msgs[0], @@ -933,14 +948,20 @@ static int rootdse_init(struct ldb_module *module) * the @ROOTDSE record */ ret = dsdb_module_search(module, mem_ctx, &res, ldb_dn_new(mem_ctx, ldb, "@ROOTDSE"), - LDB_SCOPE_BASE, ds_attrs, DSDB_FLAG_NEXT_MODULE, NULL, NULL); + LDB_SCOPE_BASE, ds_attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + NULL, NULL); if (ret == LDB_SUCCESS && res->count == 1) { struct ldb_dn *ds_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0], "dsServiceName"); if (ds_dn) { ret = dsdb_module_search(module, mem_ctx, &res, ds_dn, - LDB_SCOPE_BASE, attrs, DSDB_FLAG_NEXT_MODULE, NULL, NULL); + LDB_SCOPE_BASE, attrs, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + NULL, NULL); if (ret == LDB_SUCCESS && res->count == 1) { int domain_controller_behaviour_version = ldb_msg_find_attr_as_int(res->msgs[0], @@ -1033,6 +1054,7 @@ static int dsdb_find_optional_feature(struct ldb_module *module, struct ldb_cont ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, NULL, DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | DSDB_SEARCH_SEARCH_ALL_PARTITIONS, parent, "(&(objectClass=msDS-OptionalFeature)" -- 1.7.9.5 From 2eb2a318cd402a41ec219299b90bd7c81bf805af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 Nov 2012 06:59:33 +0100 Subject: [PATCH 07/22] s4:dsdb/objectclass: do helper searches AS_SYSTEM and with SHOW_RECYCLED Note that SHOW_RECYCLED implies SHOW_DELETED. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 844b736a1dd05159850ccc28eee1b3e625489139) --- source4/dsdb/samdb/ldb_modules/objectclass.c | 34 +++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 0743600..590927a 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -351,6 +351,13 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req) return ret; } + ret = dsdb_request_add_controls(search_req, + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED); + if (ret != LDB_SUCCESS) { + return ret; + } + ac->step_fn = objectclass_do_add; return ldb_next_request(ac->module, search_req); @@ -797,6 +804,13 @@ static int oc_modify_callback(struct ldb_request *req, struct ldb_reply *ares) return ldb_module_done(ac->req, NULL, NULL, ret); } + ret = dsdb_request_add_controls(search_req, + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + ac->step_fn = objectclass_do_mod; ret = ldb_next_request(ac->module, search_req); @@ -1021,9 +1035,9 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req /* we have to add the show recycled control, as otherwise DRS deletes will be refused as we will think the target parent does not exist */ - ret = ldb_request_add_control(search_req, LDB_CONTROL_SHOW_RECYCLED_OID, - false, NULL); - + ret = dsdb_request_add_controls(search_req, + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED); if (ret != LDB_SUCCESS) { return ret; } @@ -1071,6 +1085,13 @@ static int objectclass_do_rename(struct oc_context *ac) return ret; } + ret = dsdb_request_add_controls(search_req, + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED); + if (ret != LDB_SUCCESS) { + return ret; + } + ac->step_fn = objectclass_do_rename2; return ldb_next_request(ac->module, search_req); @@ -1251,6 +1272,13 @@ static int objectclass_delete(struct ldb_module *module, struct ldb_request *req return ret; } + ret = dsdb_request_add_controls(search_req, + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED); + if (ret != LDB_SUCCESS) { + return ret; + } + ac->step_fn = objectclass_do_delete; return ldb_next_request(ac->module, search_req); -- 1.7.9.5 From 6906283ff31090e5bf55741798046021b1fc7448 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 Nov 2012 06:59:33 +0100 Subject: [PATCH 08/22] s4:dsdb/extended_dn_in: do helper searches AS_SYSTEM and with SHOW_RECYCLED Note that SHOW_RECYCLED implies SHOW_DELETED. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 659277a89dfd4226db9ea44709010ad7e3768fd6) --- source4/dsdb/samdb/ldb_modules/extended_dn_in.c | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c index c21a1ea..034d22a 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c @@ -412,7 +412,8 @@ static int extended_dn_filter_callback(struct ldb_parse_tree *tree, void *privat } dsdb_flags = DSDB_FLAG_NEXT_MODULE | - DSDB_SEARCH_SHOW_DELETED | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED | DSDB_SEARCH_SHOW_EXTENDED_DN; if (guid_val) { @@ -555,6 +556,7 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req } else { /* It looks like we need to map the DN */ const struct ldb_val *sid_val, *guid_val, *wkguid_val; + uint32_t dsdb_flags = 0; if (!ldb_dn_match_allowed(dn, req)) { return ldb_error(ldb_module_get_ctx(module), @@ -651,7 +653,7 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req base_dn_scope, base_dn_filter, base_dn_attrs, - req->controls, + NULL, ac, extended_base_callback, req); LDB_REQ_SET_LOCATION(down_req); @@ -659,17 +661,16 @@ static int extended_dn_in_fix(struct ldb_module *module, struct ldb_request *req return ldb_operr(ldb_module_get_ctx(module)); } + dsdb_flags = DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED | + DSDB_SEARCH_SHOW_EXTENDED_DN; if (all_partitions) { - struct ldb_search_options_control *control; - control = talloc(down_req, struct ldb_search_options_control); - control->search_options = 2; - ret = ldb_request_replace_control(down_req, - LDB_CONTROL_SEARCH_OPTIONS_OID, - true, control); - if (ret != LDB_SUCCESS) { - ldb_oom(ldb_module_get_ctx(module)); - return ret; - } + dsdb_flags |= DSDB_SEARCH_SEARCH_ALL_PARTITIONS; + } + + ret = dsdb_request_add_controls(down_req, dsdb_flags); + if (ret != LDB_SUCCESS) { + return ret; } /* perform the search */ -- 1.7.9.5 From 8bf8cc853702989ea19b79c3da231637c8655a10 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 09:33:53 +0100 Subject: [PATCH 09/22] s4:dsdb/extended_dn_store: do helper searches AS_SYSTEM Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 8d900d06ff89136016ef2f139d6c33b306c87e93) --- source4/dsdb/samdb/ldb_modules/extended_dn_store.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c index 57dc883..28ad9d0 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_store.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_store.c @@ -276,7 +276,9 @@ static int extended_store_replace(struct extended_dn_context *ac, } ret = dsdb_request_add_controls(os->search_req, - DSDB_SEARCH_SHOW_RECYCLED|DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED | + DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); if (ret != LDB_SUCCESS) { talloc_free(os); return ret; -- 1.7.9.5 From cd0deae4efd284df0455c1223ac566fdf0b53f46 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 07:14:31 +0100 Subject: [PATCH 10/22] s4:dsdb/acl_util: do helper searches AS_SYSTEM The search is done in order to do access checks. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 1cdecf1234bffc37a9898b666371b2dd25ad158d) --- source4/dsdb/samdb/ldb_modules/acl_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c index 50bf888..c25979d 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_util.c +++ b/source4/dsdb/samdb/ldb_modules/acl_util.c @@ -74,6 +74,7 @@ int dsdb_module_check_access_on_dn(struct ldb_module *module, ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn, acl_attrs, DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | DSDB_SEARCH_SHOW_RECYCLED, parent); if (ret != LDB_SUCCESS) { -- 1.7.9.5 From 22f93f723421d8e669a98121d315f2b8503e8659 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 12:33:35 +0100 Subject: [PATCH 11/22] s4:dsdb/acl_util: add dsdb_request_sd_flags() helper function Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 2916313f8016720fb36180db341efbf7b91522f6) --- source4/dsdb/samdb/ldb_modules/acl_util.c | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/acl_util.c b/source4/dsdb/samdb/ldb_modules/acl_util.c index c25979d..aa7e1aa 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_util.c +++ b/source4/dsdb/samdb/ldb_modules/acl_util.c @@ -202,3 +202,40 @@ const char *acl_user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) session_info->info->domain_name, session_info->info->account_name); } + +uint32_t dsdb_request_sd_flags(struct ldb_request *req, bool *explicit) +{ + struct ldb_control *sd_control; + uint32_t sd_flags = 0; + + if (explicit) { + *explicit = false; + } + + sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID); + if (sd_control) { + struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data; + + sd_flags = sdctr->secinfo_flags; + + if (explicit) { + *explicit = true; + } + + /* mark it as handled */ + sd_control->critical = 0; + } + + /* we only care for the last 4 bits */ + sd_flags &= 0x0000000F; + + /* + * MS-ADTS 3.1.1.3.4.1.11 says that no bits + * equals all 4 bits + */ + if (sd_flags == 0) { + sd_flags = 0xF; + } + + return sd_flags; +} -- 1.7.9.5 From fc43fd28a43f9d16b6a0234393b08495007154c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 10:15:58 +0100 Subject: [PATCH 12/22] s4:dsdb/descriptor: do searches for nTSecurityDescriptor AS_SYSTEM and with SHOW_RECYCLED Note that SHOW_RECYCLED implies SHOW_DELETED. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 690b5e11618eb0385272d6a003761db22369e620) --- source4/dsdb/samdb/ldb_modules/descriptor.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index 0a26288..db8bba7 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -521,7 +521,9 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) /* we aren't any NC */ ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn, parent_attrs, - DSDB_FLAG_NEXT_MODULE, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, req); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n", @@ -581,7 +583,7 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; - struct ldb_control *sd_recalculate_control, *sd_flags_control, *show_deleted_control; + struct ldb_control *sd_recalculate_control, *sd_flags_control; struct ldb_request *mod_req; struct ldb_message *msg; struct ldb_result *current_res, *parent_res; @@ -591,7 +593,7 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) struct ldb_dn *parent_dn, *dn; struct ldb_message_element *objectclass_element; int ret; - uint32_t instanceType, sd_flags = 0, flags; + uint32_t instanceType, sd_flags = 0; const struct dsdb_schema *schema; DATA_BLOB *sd; const struct dsdb_class *objectclass; @@ -604,8 +606,6 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor"); /* This control forces the recalculation of the SD also when * no modification is performed. */ - show_deleted_control = ldb_request_get_control(req, - LDB_CONTROL_SHOW_DELETED_OID); sd_recalculate_control = ldb_request_get_control(req, LDB_CONTROL_RECALCULATE_SD_OID); if (!user_sd && !sd_recalculate_control) { @@ -618,13 +618,12 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) if (ldb_dn_is_special(dn)) { return ldb_next_request(module, req); } - flags = DSDB_FLAG_NEXT_MODULE; - if (show_deleted_control) { - flags |= DSDB_SEARCH_SHOW_DELETED; - } + ret = dsdb_module_search_dn(module, req, ¤t_res, dn, current_attrs, - flags, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, req); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR,"descriptor_modify: Could not find %s\n", @@ -644,7 +643,9 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) } ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn, parent_attrs, - DSDB_FLAG_NEXT_MODULE, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, req); if (ret != LDB_SUCCESS) { ldb_debug(ldb, LDB_DEBUG_ERROR, "descriptor_modify: Could not find SD for %s\n", -- 1.7.9.5 From f1353810c7dc04ebadcffb91340ca30ed91a5991 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 15:24:46 +0100 Subject: [PATCH 13/22] s4:dsdb/descriptor: always use descriptor_search_callback if we return nTSecurityDescriptor If the nTSecurityDescriptor is explicitly specified without the SD Flags control we should go through descriptor_search_callback(). This is not strictly needed at the moment, but makes the code clearer and might avoid surprises in the future. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 67045fafe8a826792a51a504aa85ee6d8e137059) --- source4/dsdb/samdb/ldb_modules/descriptor.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index db8bba7..a876346 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -739,9 +739,20 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) struct ldb_control *sd_control; struct ldb_request *down_req; struct descriptor_context *ac; + bool show_sd = false; sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID); - if (!sd_control) { + if (sd_control != NULL) { + show_sd = true; + } + + if (!show_sd && + ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor")) + { + show_sd = true; + } + + if (!show_sd) { return ldb_next_request(module, req); } -- 1.7.9.5 From 7cfbc5e54a632e7db9ad5fa170abe67a7c0bbde5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 13:05:31 +0100 Subject: [PATCH 14/22] s4:dsdb/descriptor: make use of dsdb_request_sd_flags() Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit f018772e0ca981857036078342456ef17858b966) --- source4/dsdb/samdb/ldb_modules/descriptor.c | 62 +++++++-------------------- 1 file changed, 15 insertions(+), 47 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index a876346..a764d69 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -56,6 +56,7 @@ struct descriptor_context { struct ldb_val *parentsd_val; struct ldb_message_element *sd_element; struct ldb_val *sd_val; + uint32_t sd_flags; int (*step_fn)(struct descriptor_context *); }; @@ -384,12 +385,10 @@ static struct descriptor_context *descriptor_init_context(struct ldb_module *mod static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct descriptor_context *ac; - struct ldb_control *sd_control; struct ldb_val *sd_val = NULL; struct ldb_message_element *sd_el; DATA_BLOB *show_sd; int ret; - uint32_t sd_flags = 0; ac = talloc_get_type(req->context, struct descriptor_context); @@ -402,30 +401,16 @@ static int descriptor_search_callback(struct ldb_request *req, struct ldb_reply ares->response, ares->error); } - sd_control = ldb_request_get_control(ac->req, LDB_CONTROL_SD_FLAGS_OID); - if (sd_control) { - struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_control->data; - sd_flags = sdctr->secinfo_flags; - /* we only care for the last 4 bits */ - sd_flags = sd_flags & 0x0000000F; - if (sd_flags == 0) { - /* MS-ADTS 3.1.1.3.4.1.11 says that no bits - equals all 4 bits */ - sd_flags = 0xF; - } - } - switch (ares->type) { case LDB_REPLY_ENTRY: - if (sd_flags != 0) { - sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor"); - if (sd_el) { - sd_val = sd_el->values; - } + sd_el = ldb_msg_find_element(ares->message, "nTSecurityDescriptor"); + if (sd_el) { + sd_val = sd_el->values; } + if (sd_val) { show_sd = descr_get_descriptor_to_show(ac->module, ac->req, - sd_val, sd_flags); + sd_val, ac->sd_flags); if (!show_sd) { ret = LDB_ERR_OPERATIONS_ERROR; goto fail; @@ -468,6 +453,7 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL }; uint32_t instanceType; bool isNC = false; + uint32_t sd_flags = dsdb_request_sd_flags(req, NULL); ldb = ldb_module_get_ctx(module); dn = req->op.add.message->dn; @@ -583,7 +569,7 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; - struct ldb_control *sd_recalculate_control, *sd_flags_control; + struct ldb_control *sd_recalculate_control; struct ldb_request *mod_req; struct ldb_message *msg; struct ldb_result *current_res, *parent_res; @@ -593,7 +579,8 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) struct ldb_dn *parent_dn, *dn; struct ldb_message_element *objectclass_element; int ret; - uint32_t instanceType, sd_flags = 0; + uint32_t instanceType; + uint32_t sd_flags = dsdb_request_sd_flags(req, NULL); const struct dsdb_schema *schema; DATA_BLOB *sd; const struct dsdb_class *objectclass; @@ -657,7 +644,6 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) } parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor"); } - sd_flags_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID); schema = dsdb_get_schema(ldb, req); @@ -672,15 +658,7 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) return ldb_operr(ldb); } - if (sd_flags_control) { - struct ldb_sd_flags_control *sdctr = (struct ldb_sd_flags_control *)sd_flags_control->data; - sd_flags = sdctr->secinfo_flags; - /* we only care for the last 4 bits */ - sd_flags = sd_flags & 0x0000000F; - } - if (sd_flags != 0) { - old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor"); - } + old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor"); sd = get_new_descriptor(module, dn, req, objectclass, parent_sd, @@ -711,9 +689,6 @@ static int descriptor_modify(struct ldb_module *module, struct ldb_request *req) } /* mark the controls as non-critical since we've handled them */ - if (sd_flags_control != NULL) { - sd_flags_control->critical = 0; - } if (sd_recalculate_control != NULL) { sd_recalculate_control->critical = 0; } @@ -736,15 +711,11 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) { int ret; struct ldb_context *ldb; - struct ldb_control *sd_control; struct ldb_request *down_req; struct descriptor_context *ac; - bool show_sd = false; - - sd_control = ldb_request_get_control(req, LDB_CONTROL_SD_FLAGS_OID); - if (sd_control != NULL) { - show_sd = true; - } + bool explicit_sd_flags = false; + uint32_t sd_flags = dsdb_request_sd_flags(req, &explicit_sd_flags); + bool show_sd = explicit_sd_flags; if (!show_sd && ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor")) @@ -761,6 +732,7 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) if (ac == NULL) { return ldb_operr(ldb); } + ac->sd_flags = sd_flags; ret = ldb_build_search_req_ex(&down_req, ldb, ac, req->op.search.base, @@ -774,10 +746,6 @@ static int descriptor_search(struct ldb_module *module, struct ldb_request *req) if (ret != LDB_SUCCESS) { return ret; } - /* mark it as handled */ - if (sd_control) { - sd_control->critical = 0; - } return ldb_next_request(ac->module, down_req); } -- 1.7.9.5 From af51af0e22ddac968d43b4e78b8d491815d67215 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 14:13:17 +0100 Subject: [PATCH 15/22] s4:dsdb/descriptor: make it clear that the SD Flags are ignored on add See [MS-ADTS] 6.1.3.2 SD Flags Control: ... When performing an LDAP add operation, the client can supply an SD flags control with the operation; however, it will be ignored by the server. ... Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 42898590bb386a13b4f0d7b0294561a78df7e268) --- source4/dsdb/samdb/ldb_modules/descriptor.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index a764d69..12186f2 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -535,9 +535,15 @@ static int descriptor_add(struct ldb_module *module, struct ldb_request *req) return ldb_operr(ldb); } + /* + * The SD_FLAG control is ignored on add + * and we default to all bits set. + */ + sd_flags = 0xF; + sd = get_new_descriptor(module, dn, req, objectclass, parent_sd, - user_sd, NULL, 0); + user_sd, NULL, sd_flags); msg = ldb_msg_copy_shallow(req, req->op.add.message); if (sd != NULL) { if (sd_element != NULL) { -- 1.7.9.5 From 05b857eb01bc399249a53436edf85c276eb09cab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 07:14:31 +0100 Subject: [PATCH 16/22] s4:dsdb/acl: do helper searches AS_SYSTEM and with SHOW_RECYCLED The searches are done in order to do access checks and the results are not directly exposed to the client. Note that SHOW_RECYCLED implies SHOW_DELETED. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 329afc1a203056b1f4a43dd6c98ec2067c64f962) --- source4/dsdb/samdb/ldb_modules/acl.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 1a41ee2..0c4131f 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -112,7 +112,9 @@ static int acl_module_init(struct ldb_module *module) ret = dsdb_module_search_dn(module, mem_ctx, &res, ldb_dn_new(mem_ctx, ldb, "@KLUDGEACL"), attrs, - DSDB_FLAG_NEXT_MODULE, NULL); + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, + NULL); if (ret != LDB_SUCCESS) { goto done; } @@ -652,7 +654,9 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, &acl_res, req->op.mod.message->dn, acl_attrs, DSDB_FLAG_NEXT_MODULE | - DSDB_SEARCH_SHOW_DELETED, req); + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, + req); if (ret != LDB_SUCCESS) { talloc_free(tmp_ctx); return ret; @@ -666,7 +670,8 @@ static int acl_check_spn(TALLOC_CTX *mem_ctx, &netbios_res, partitions_dn, LDB_SCOPE_ONELEVEL, netbios_attrs, - DSDB_FLAG_NEXT_MODULE, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM, req, "(ncName=%s)", ldb_dn_get_linearized(ldb_get_default_basedn(ldb))); @@ -974,7 +979,9 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) } ret = dsdb_module_search_dn(module, tmp_ctx, &acl_res, req->op.mod.message->dn, acl_attrs, - DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DELETED, + DSDB_FLAG_NEXT_MODULE | + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, req); if (ret != LDB_SUCCESS) { @@ -1257,6 +1264,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req) ret = dsdb_module_search_dn(module, tmp_ctx, &acl_res, req->op.rename.olddn, 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) { @@ -1462,7 +1470,9 @@ static int acl_search_callback(struct ldb_request *req, struct ldb_reply *ares) ret = dsdb_module_search_dn(ac->module, ac, &acl_res, ares->message->dn, acl_attrs, DSDB_FLAG_NEXT_MODULE | - DSDB_SEARCH_SHOW_DELETED, req); + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, + req); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } -- 1.7.9.5 From cd8ff16afd442c540f58e87da029b04b7a518af9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 12:15:00 +0100 Subject: [PATCH 17/22] s4:dsdb/acl: remove unused "acl:perform" option Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 3d57f17db94ddb5d5d8021158548ea7aebe16cd1) --- source4/dsdb/samdb/ldb_modules/acl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 0c4131f..9a7b01b 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -49,7 +49,6 @@ struct extended_access_check_attribute { }; struct acl_private { - bool acl_perform; const char **password_attrs; void *cached_schema_ptr; uint64_t cached_schema_metadata_usn; @@ -100,8 +99,6 @@ static int acl_module_init(struct ldb_module *module) return ldb_oom(ldb); } - data->acl_perform = lpcfg_parm_bool(ldb_get_opaque(ldb, "loadparm"), - NULL, "acl", "perform", false); ldb_module_set_private(module, data); mem_ctx = talloc_new(module); -- 1.7.9.5 From f74e3d008a1447453cb3bae1fe6fe8a074c1ac7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 12:12:41 +0100 Subject: [PATCH 18/22] s4:dsdb/acl: don't protect confidential attributes when "acl:search = yes" is set In that case the acl_read module does the protection. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 95b480fd98d9647c679672abac49c9f4ca5b3219) --- source4/dsdb/samdb/ldb_modules/acl.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 9a7b01b..ca99c91 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -49,6 +49,7 @@ struct extended_access_check_attribute { }; struct acl_private { + bool acl_search; const char **password_attrs; void *cached_schema_ptr; uint64_t cached_schema_metadata_usn; @@ -99,6 +100,8 @@ static int acl_module_init(struct ldb_module *module) return ldb_oom(ldb); } + data->acl_search = lpcfg_parm_bool(ldb_get_opaque(ldb, "loadparm"), + NULL, "acl", "search", false); ldb_module_set_private(module, data); mem_ctx = talloc_new(module); @@ -1393,6 +1396,14 @@ static int acl_search_update_confidential_attrs(struct acl_context *ac, struct dsdb_attribute *a; uint32_t n = 0; + if (data->acl_search) { + /* + * If acl:search is activated, the acl_read module + * protects confidential attributes. + */ + return LDB_SUCCESS; + } + if ((ac->schema == data->cached_schema_ptr) && (ac->schema->loaded_usn == data->cached_schema_loaded_usn) && (ac->schema->metadata_usn == data->cached_schema_metadata_usn)) -- 1.7.9.5 From f51b76ecef8dcd7167f218559f20c647057b29af Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 14:10:43 +0100 Subject: [PATCH 19/22] s4:dsdb/acl: calculate the correct access_mask when modifying nTSecurityDescriptor The access_mask depends on the SD Flags. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 53b100bb59dadbc7cfb727a4ad1566302ff6c831) --- source4/dsdb/samdb/ldb_modules/acl.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index ca99c91..50af3b2 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -1024,8 +1024,21 @@ static int acl_modify(struct ldb_module *module, struct ldb_request *req) req->op.mod.message->elements[i].name); if (ldb_attr_cmp("nTSecurityDescriptor", req->op.mod.message->elements[i].name) == 0) { + uint32_t sd_flags = dsdb_request_sd_flags(req, NULL); + uint32_t access_mask = 0; + + if (sd_flags & (SECINFO_OWNER|SECINFO_GROUP)) { + access_mask |= SEC_STD_WRITE_OWNER; + } + if (sd_flags & SECINFO_DACL) { + access_mask |= SEC_STD_WRITE_DAC; + } + if (sd_flags & SECINFO_SACL) { + access_mask |= SEC_FLAG_SYSTEM_SECURITY; + } + status = sec_access_check_ds(sd, acl_user_token(module), - SEC_STD_WRITE_DAC, + access_mask, &access_granted, NULL, sid); -- 1.7.9.5 From 6bb34781bc0912e662dd8d91b868883624809c02 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 09:31:25 +0100 Subject: [PATCH 20/22] s4:dsdb/acl_read: do search for instanceType AS_SYSTEM and with SHOW_RECYCLED Note that SHOW_RECYCLED implies SHOW_DELETED. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit ca3c0e28ef5d43f0af487e45a56f2929f5f23b4e) --- source4/dsdb/samdb/ldb_modules/acl_read.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index e2a2d4c..bc75d32 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -287,7 +287,9 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) ret = dsdb_module_search_dn(module, req, &res, req->op.search.base, acl_attrs, DSDB_FLAG_NEXT_MODULE | - DSDB_SEARCH_SHOW_DELETED, req); + DSDB_FLAG_AS_SYSTEM | + DSDB_SEARCH_SHOW_RECYCLED, + req); if (ret != LDB_SUCCESS) { return ldb_error(ldb, ret, "acl_read: Error retrieving instanceType for base."); -- 1.7.9.5 From e239c9aa3326e703f51ddecf6680ceeebfa1aa60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Nov 2012 14:04:09 +0100 Subject: [PATCH 21/22] s4:dsdb/acl_read: specify the correct access_mask for nTSecurityDescriptor We need to base the access mask on the given SD Flags. Originally, we always checked for SEC_FLAG_SYSTEM_SECURITY, which could lead to INSUFFICIENT_RIGHTS when we should have been allowed to read. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit fa676769e0d5d3f161b295f06f643fdacebb82ca) --- source4/dsdb/samdb/ldb_modules/acl_read.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index bc75d32..60b0d87 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -44,6 +44,7 @@ struct aclread_context { struct ldb_request *req; const char * const *attrs; const struct dsdb_schema *schema; + uint32_t sd_flags; bool sd; bool instance_type; bool object_sid; @@ -149,7 +150,17 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) } /* nTSecurityDescriptor is a special case */ if (is_sd) { - access_mask = SEC_FLAG_SYSTEM_SECURITY|SEC_STD_READ_CONTROL; + access_mask = 0; + + if (ac->sd_flags & (SECINFO_OWNER|SECINFO_GROUP)) { + access_mask |= SEC_STD_READ_CONTROL; + } + if (ac->sd_flags & SECINFO_DACL) { + access_mask |= SEC_STD_READ_CONTROL; + } + if (ac->sd_flags & SECINFO_SACL) { + access_mask |= SEC_FLAG_SYSTEM_SECURITY; + } } else { access_mask = SEC_ADS_READ_PROP; } @@ -158,6 +169,11 @@ static int aclread_callback(struct ldb_request *req, struct ldb_reply *ares) access_mask |= SEC_ADS_CONTROL_ACCESS; } + if (access_mask == 0) { + aclread_mark_inaccesslible(&msg->elements[i]); + continue; + } + ret = acl_check_access_on_attribute(ac->module, tmp_ctx, sd, @@ -332,6 +348,8 @@ static int aclread_search(struct ldb_module *module, struct ldb_request *req) * expensive so we'd better had the ntsecuritydescriptor to the list of * searched attribute and then remove it ! */ + ac->sd_flags = dsdb_request_sd_flags(ac->req, NULL); + ac->sd = !(ldb_attr_in_list(req->op.search.attrs, "nTSecurityDescriptor")); if (req->op.search.attrs && !ldb_attr_in_list(req->op.search.attrs, "*")) { if (!ldb_attr_in_list(req->op.search.attrs, "instanceType")) { -- 1.7.9.5 From 8b8bf7043251249ec73cf496a32011e127710659 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 18 Nov 2012 18:57:03 +0100 Subject: [PATCH 22/22] s4:dsdb/acl_read: enable acl checking on search by default (bug #8620) Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 990448b4997d1a2423e5dd4da1e37ad51f99bf3a) --- selftest/knownfail | 8 -------- selftest/target/Samba4.pm | 3 --- source4/dsdb/samdb/ldb_modules/acl.c | 2 +- source4/dsdb/samdb/ldb_modules/acl_read.c | 2 +- 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 30aef76..85634ab 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -133,7 +133,6 @@ ^samba4.smb2.acls.*.generic ^samba4.smb2.acls.*.inheritflags ^samba4.smb2.acls.*.owner -^samba4.ldap.acl.*.ntSecurityDescriptor.* # ACL extended checks on search not enabled by default ^samba4.ldap.dirsync.python.dc..__main__.ExtendedDirsyncTests.test_dirsync_deleted_items #^samba4.ldap.dirsync.python.dc..__main__.ExtendedDirsyncTests.* ^samba4.drs.fsmo.python @@ -158,13 +157,6 @@ ^samba4.smb2.oplock.stream1 # samba 4 oplocks are a mess ^samba4.smb2.getinfo.getinfo # streams on directories does not work ^samba4.ntvfs.cifs.krb5.base.createx_access.createx_access\(.*\)$ -^samba4.ldap.acl.*.AclSearchTests.test_search_anonymous3\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search1\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search2\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search3\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search4\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search5\(.*\)$ # ACL search behaviour not enabled by default -^samba4.ldap.acl.*.AclSearchTests.test_search6\(.*\)$ # ACL search behaviour not enabled by default ^samba4.rpc.lsa.forest.trust #Not fully provided by Samba4 ^samba4.blackbox.kinit\(.*\).kinit with user password for expired password\(.*\) # We need to work out why this fails only during the pw change ^samba4.blackbox.dbcheck\(vampire_dc\).dbcheck\(vampire_dc:local\) # Due to replicating with --domain-critical-only we fail dbcheck on this database diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 20114c9..5988b83 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -559,11 +559,8 @@ sub provision_raw_step1($$) warn("can't open $ctx->{smb_conf}$?"); return undef; } - my $acl = "false"; - $acl = "true" if (defined $ENV{WITH_ACL}); print CONFFILE " [global] - acl:search = $acl netbios name = $ctx->{netbiosname} posix:eadb = $ctx->{statedir}/eadb.tdb workgroup = $ctx->{domain} diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c index 50af3b2..2cc028f 100644 --- a/source4/dsdb/samdb/ldb_modules/acl.c +++ b/source4/dsdb/samdb/ldb_modules/acl.c @@ -101,7 +101,7 @@ static int acl_module_init(struct ldb_module *module) } data->acl_search = lpcfg_parm_bool(ldb_get_opaque(ldb, "loadparm"), - NULL, "acl", "search", false); + NULL, "acl", "search", true); ldb_module_set_private(module, data); mem_ctx = talloc_new(module); diff --git a/source4/dsdb/samdb/ldb_modules/acl_read.c b/source4/dsdb/samdb/ldb_modules/acl_read.c index 60b0d87..92744f2 100644 --- a/source4/dsdb/samdb/ldb_modules/acl_read.c +++ b/source4/dsdb/samdb/ldb_modules/acl_read.c @@ -397,7 +397,7 @@ static int aclread_init(struct ldb_module *module) if (p == NULL) { return ldb_module_oom(module); } - p->enabled = lpcfg_parm_bool(ldb_get_opaque(ldb, "loadparm"), NULL, "acl", "search", false); + p->enabled = lpcfg_parm_bool(ldb_get_opaque(ldb, "loadparm"), NULL, "acl", "search", true); ldb_module_set_private(module, p); return ldb_next_init(module); } -- 1.7.9.5