From e8bd75ec73a804375753be9eb15d7fc5d9bc18c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Mar 2008 21:30:34 +0100 Subject: Bind Group Policy processing closer to the samba registry. Guenther (This used to be commit e9c56250eb7a2dc4e69962c5b48875834941ccfc) --- source3/libgpo/gpo_ldap.c | 2 +- source3/libgpo/gpo_util.c | 202 +++++++++++++++++++++++++++++++++------------- 2 files changed, 145 insertions(+), 59 deletions(-) (limited to 'source3/libgpo') diff --git a/source3/libgpo/gpo_ldap.c b/source3/libgpo/gpo_ldap.c index 477832abc5..0e77f0a856 100644 --- a/source3/libgpo/gpo_ldap.c +++ b/source3/libgpo/gpo_ldap.c @@ -725,7 +725,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, /* (L)ocal */ status = add_local_policy_to_gpo_list(mem_ctx, gpo_list, - GP_LINK_UNKOWN); + GP_LINK_LOCAL); if (!ADS_ERR_OK(status)) { return status; } diff --git a/source3/libgpo/gpo_util.c b/source3/libgpo/gpo_util.c index f41bbc1817..7105b21de8 100644 --- a/source3/libgpo/gpo_util.c +++ b/source3/libgpo/gpo_util.c @@ -400,21 +400,34 @@ void dump_gplink(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct GP_LINK *gp_link) /**************************************************************** ****************************************************************/ -NTSTATUS process_extension(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - uint32_t flags, - const struct nt_user_token *token, - struct GROUP_POLICY_OBJECT *gpo, - const char *extension_guid, - const char *snapin_guid) +static bool gpo_get_gp_ext_from_gpo(TALLOC_CTX *mem_ctx, + uint32_t flags, + struct GROUP_POLICY_OBJECT *gpo, + struct GP_EXT **gp_ext) { - DEBUG(0,("process_extension: no extension available for:\n")); - DEBUGADD(0,("%s (%s) (snapin: %s)\n", - extension_guid, - cse_gpo_guid_string_to_name(extension_guid), - snapin_guid)); + ZERO_STRUCTP(*gp_ext); + + if (flags & GPO_INFO_FLAG_MACHINE) { + + if (gpo->machine_extensions) { + + if (!ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, + gp_ext)) { + return false; + } + } + } else { - return NT_STATUS_OK; + if (gpo->user_extensions) { + + if (!ads_parse_gp_ext(mem_ctx, gpo->user_extensions, + gp_ext)) { + return false; + } + } + } + + return true; } /**************************************************************** @@ -423,6 +436,7 @@ NTSTATUS process_extension(ADS_STRUCT *ads, ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const struct nt_user_token *token, + struct registry_key *root_key, struct GROUP_POLICY_OBJECT *gpo, const char *extension_guid_filter, uint32_t flags) @@ -433,36 +447,22 @@ ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, DEBUG(10,("gpo_process_a_gpo: processing gpo %s (%s)\n", gpo->name, gpo->display_name)); if (extension_guid_filter) { - DEBUGADD(10,("gpo_process_a_gpo: using filter %s\n", - extension_guid_filter)); + DEBUGADD(10,("gpo_process_a_gpo: using filter %s (%s)\n", + extension_guid_filter, + cse_gpo_guid_string_to_name(extension_guid_filter))); } - if (flags & GPO_LIST_FLAG_MACHINE) { - - if (gpo->machine_extensions) { - - if (!ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, - &gp_ext)) { - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } + if (!gpo_get_gp_ext_from_gpo(mem_ctx, flags, gpo, &gp_ext)) { + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } - } else { - /* nothing to apply */ - return ADS_SUCCESS; - } - - } else { - - if (gpo->user_extensions) { - - if (!ads_parse_gp_ext(mem_ctx, gpo->user_extensions, - &gp_ext)) { - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - } else { - /* nothing to apply */ - return ADS_SUCCESS; + if (!gp_ext || !gp_ext->num_exts) { + if (flags & GPO_INFO_FLAG_VERBOSE) { + DEBUG(0,("gpo_process_a_gpo: " + "no policies in %s (%s) for this extension\n", + gpo->name, gpo->display_name)); } + return ADS_SUCCESS; } for (i=0; inum_exts; i++) { @@ -475,10 +475,10 @@ ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, continue; } - ntstatus = process_extension(ads, mem_ctx, - flags, token, gpo, - gp_ext->extensions_guid[i], - gp_ext->snapins_guid[i]); + ntstatus = gpext_process_extension(ads, mem_ctx, + flags, token, root_key, gpo, + gp_ext->extensions_guid[i], + gp_ext->snapins_guid[i]); if (!NT_STATUS_IS_OK(ntstatus)) { ADS_ERROR_NT(ntstatus); } @@ -490,37 +490,122 @@ ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads, /**************************************************************** ****************************************************************/ -ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const struct nt_user_token *token, - struct GROUP_POLICY_OBJECT *gpo_list, - const char *extensions_guid, - uint32_t flags) +static ADS_STATUS gpo_process_gpo_list_by_ext(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const struct nt_user_token *token, + struct registry_key *root_key, + struct GROUP_POLICY_OBJECT *gpo_list, + const char *extensions_guid, + uint32_t flags) { ADS_STATUS status; struct GROUP_POLICY_OBJECT *gpo; - /* FIXME: ok, this is wrong, windows does process the extensions and - * hands the list of gpos to each extension and not process each gpo - * with all extensions (this is how the extension can store the list - * gplist in the registry) */ - for (gpo = gpo_list; gpo; gpo = gpo->next) { - status = gpo_process_a_gpo(ads, mem_ctx, token, gpo, - extensions_guid, flags); + if (gpo->link_type == GP_LINK_LOCAL) { + continue; + } + + + /* FIXME: we need to pass down the *list* down to the + * extension, otherwise we cannot store the e.g. the *list* of + * logon-scripts correctly (for more then one GPO) */ + + status = gpo_process_a_gpo(ads, mem_ctx, token, root_key, + gpo, extensions_guid, flags); if (!ADS_ERR_OK(status)) { - DEBUG(0,("failed to process gpo: %s\n", + DEBUG(0,("failed to process gpo by ext: %s\n", ads_errstr(status))); return status; } - } return ADS_SUCCESS; } +/**************************************************************** +****************************************************************/ + +ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo_list, + const char *extensions_guid_filter, + uint32_t flags) +{ + ADS_STATUS status = ADS_SUCCESS; + struct gp_extension *gp_ext_list = NULL; + struct gp_extension *gp_ext = NULL; + struct registry_key *root_key = NULL; + struct gp_registry_context *reg_ctx = NULL; + WERROR werr; + + status = ADS_ERROR_NT(init_gp_extensions(mem_ctx)); + if (!ADS_ERR_OK(status)) { + return status; + } + + gp_ext_list = get_gp_extension_list(); + if (!gp_ext_list) { + return ADS_ERROR_NT(NT_STATUS_DLL_INIT_FAILED); + } + + /* get the key here */ + if (flags & GPO_LIST_FLAG_MACHINE) { + werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE, + get_system_token(), + ®_ctx); + } else { + werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE, + token, + ®_ctx); + } + if (!W_ERROR_IS_OK(werr)) { + gp_free_reg_ctx(reg_ctx); + return ADS_ERROR_NT(werror_to_ntstatus(werr)); + } + + root_key = reg_ctx->curr_key; + + for (gp_ext = gp_ext_list; gp_ext; gp_ext = gp_ext->next) { + + const char *guid_str = NULL; + + guid_str = GUID_string(mem_ctx, gp_ext->guid); + if (!guid_str) { + status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + goto done; + } + + if (extensions_guid_filter && + (!strequal(guid_str, extensions_guid_filter))) { + continue; + } + + DEBUG(0,("-------------------------------------------------\n")); + DEBUG(0,("gpo_process_gpo_list: processing ext: %s {%s}\n", + gp_ext->name, guid_str)); + + + status = gpo_process_gpo_list_by_ext(ads, mem_ctx, token, + root_key, gpo_list, + guid_str, flags); + if (!ADS_ERR_OK(status)) { + goto done; + } + } + + done: + gp_free_reg_ctx(reg_ctx); + TALLOC_FREE(root_key); + free_gp_extensions(); + + return status; +} + + /**************************************************************** check wether the version number in a GROUP_POLICY_OBJECT match those of the locally stored version. If not, fetch the required policy via CIFS @@ -621,6 +706,7 @@ NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, gpo->version, GPO_VERSION_USER(gpo->version), GPO_VERSION_MACHINE(gpo->version))); + DEBUGADD(10,("LDAP GPO link:\t\t%s\n", gpo->link)); result = NT_STATUS_OK; -- cgit