2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Guenther Deschner 2007
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "../libgpo/gpo_ini.h"
22 #include "../libgpo/gpo.h"
23 #include "libgpo/gpo_proto.h"
26 #define GP_EXT_NAME "scripts"
28 #define KEY_GP_SCRIPTS "Software\\Policies\\Microsoft\\Windows\\System\\Scripts"
30 #define GP_SCRIPTS_INI "Scripts/scripts.ini"
32 #define GP_SCRIPTS_INI_STARTUP "Startup"
33 #define GP_SCRIPTS_INI_SHUTDOWN "Shutdown"
34 #define GP_SCRIPTS_INI_LOGON "Logon"
35 #define GP_SCRIPTS_INI_LOGOFF "Logoff"
37 #define GP_SCRIPTS_SECTION_CMDLINE "cmdline"
38 #define GP_SCRIPTS_SECTION_PARAMETERS "parameters"
40 #define GP_SCRIPTS_REG_VAL_SCRIPT "Script"
41 #define GP_SCRIPTS_REG_VAL_PARAMETERS "Parameters"
42 #define GP_SCRIPTS_REG_VAL_EXECTIME "ExecTime"
44 static TALLOC_CTX *ctx = NULL;
46 /****************************************************************
47 ****************************************************************/
49 static NTSTATUS scripts_get_reg_config(TALLOC_CTX *mem_ctx,
50 struct gp_extension_reg_info **reg_info)
53 struct gp_extension_reg_info *info = NULL;
55 struct gp_extension_reg_table table[] = {
56 { "ProcessGroupPolicy", REG_SZ, "scripts_process_group_policy" },
57 { "NoGPOListChanges", REG_DWORD, "1" },
58 { "NoSlowLink", REG_DWORD, "1" },
59 { "NotifyLinkTransition", REG_DWORD, "1" },
60 { NULL, REG_NONE, NULL },
63 info = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info);
64 NT_STATUS_HAVE_NO_MEMORY(info);
66 status = gp_ext_info_add_entry(mem_ctx, GP_EXT_NAME,
69 NT_STATUS_NOT_OK_RETURN(status);
76 /****************************************************************
77 ****************************************************************/
79 static NTSTATUS generate_gp_registry_entry(TALLOC_CTX *mem_ctx,
84 enum gp_reg_action action,
85 struct gp_registry_entry **entry_out)
87 struct gp_registry_entry *entry = NULL;
88 struct registry_value *data = NULL;
90 entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry);
91 NT_STATUS_HAVE_NO_MEMORY(entry);
93 data = TALLOC_ZERO_P(mem_ctx, struct registry_value);
94 NT_STATUS_HAVE_NO_MEMORY(data);
96 data->type = data_type;
99 data->data = data_blob_talloc(mem_ctx, NULL, 8);
100 SBVAL(data->data.data, 0, *(uint64_t *)data_p);
103 if (!push_reg_sz(mem_ctx, &data->data, (char *)data_p)) {
104 return NT_STATUS_NO_MEMORY;
108 return NT_STATUS_NOT_SUPPORTED;
113 entry->action = action;
114 entry->value = talloc_strdup(mem_ctx, value);
115 NT_STATUS_HAVE_NO_MEMORY(entry->value);
122 /****************************************************************
123 ****************************************************************/
125 static NTSTATUS scripts_parse_ini_section(struct gp_inifile_context *ini_ctx,
128 struct gp_registry_entry **entries,
131 NTSTATUS status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
137 const char *key = NULL;
139 const char *count = NULL;
140 char *parameters = NULL;
142 count = talloc_asprintf(ini_ctx->mem_ctx, "%d", i);
143 NT_STATUS_HAVE_NO_MEMORY(count);
145 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
147 GP_SCRIPTS_SECTION_CMDLINE);
148 NT_STATUS_HAVE_NO_MEMORY(key);
150 result = gp_inifile_getstring(ini_ctx, key, &script);
151 if (!NT_STATUS_IS_OK(result)) {
155 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
157 GP_SCRIPTS_SECTION_PARAMETERS);
158 NT_STATUS_HAVE_NO_MEMORY(key);
160 result = gp_inifile_getstring(ini_ctx, key, ¶meters);
161 if (!NT_STATUS_IS_OK(result)) {
166 struct gp_registry_entry *entry = NULL;
167 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
169 GP_SCRIPTS_REG_VAL_SCRIPT,
172 GP_REG_ACTION_ADD_VALUE,
174 NT_STATUS_NOT_OK_RETURN(status);
175 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
179 return NT_STATUS_NO_MEMORY;
183 struct gp_registry_entry *entry = NULL;
184 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
186 GP_SCRIPTS_REG_VAL_PARAMETERS,
189 GP_REG_ACTION_ADD_VALUE,
191 NT_STATUS_NOT_OK_RETURN(status);
192 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
196 return NT_STATUS_NO_MEMORY;
200 struct gp_registry_entry *entry = NULL;
201 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
203 GP_SCRIPTS_REG_VAL_EXECTIME,
206 GP_REG_ACTION_ADD_VALUE,
208 NT_STATUS_NOT_OK_RETURN(status);
209 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
213 return NT_STATUS_NO_MEMORY;
216 status = NT_STATUS_OK;
223 /****************************************************************
224 ****************************************************************/
226 static WERROR scripts_store_reg_gpovals(TALLOC_CTX *mem_ctx,
227 struct registry_key *key,
228 struct GROUP_POLICY_OBJECT *gpo)
233 return WERR_INVALID_PARAM;
236 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
238 W_ERROR_NOT_OK_RETURN(werr);
240 werr = gp_store_reg_val_sz(mem_ctx, key, "FileSysPath",
242 W_ERROR_NOT_OK_RETURN(werr);
244 werr = gp_store_reg_val_sz(mem_ctx, key, "GPO-ID",
246 W_ERROR_NOT_OK_RETURN(werr);
248 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOName",
250 W_ERROR_NOT_OK_RETURN(werr);
252 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM-ID",
254 W_ERROR_NOT_OK_RETURN(werr);
259 /****************************************************************
260 ****************************************************************/
262 static WERROR scripts_apply(TALLOC_CTX *mem_ctx,
263 const struct nt_user_token *token,
264 struct registry_key *root_key,
267 struct GROUP_POLICY_OBJECT *gpo,
268 struct gp_registry_entry *entries,
271 struct gp_registry_context *reg_ctx = NULL;
274 const char *keystr = NULL;
277 if (num_entries == 0) {
282 if (flags & GPO_INFO_FLAG_MACHINE) {
283 struct nt_user_token *tmp_token;
285 tmp_token = registry_create_system_token(mem_ctx);
286 W_ERROR_HAVE_NO_MEMORY(tmp_token);
288 werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE,
292 werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE,
296 W_ERROR_NOT_OK_RETURN(werr);
299 keystr = talloc_asprintf(mem_ctx, "%s\\%s\\%d", KEY_GP_SCRIPTS,
301 W_ERROR_HAVE_NO_MEMORY(keystr);
303 reg_deletekey_recursive(mem_ctx, root_key, keystr);
305 werr = gp_store_reg_subkey(mem_ctx, keystr,
306 root_key, &root_key);
307 if (!W_ERROR_IS_OK(werr)) {
311 werr = scripts_store_reg_gpovals(mem_ctx, root_key, gpo);
312 if (!W_ERROR_IS_OK(werr)) {
316 for (i=0; i<num_entries; i++) {
318 werr = reg_apply_registry_entry(mem_ctx, root_key, reg_ctx,
321 if (!W_ERROR_IS_OK(werr)) {
322 DEBUG(0,("failed to apply registry: %s\n",
329 gp_free_reg_ctx(reg_ctx);
333 /****************************************************************
334 ****************************************************************/
336 static NTSTATUS scripts_process_group_policy(ADS_STRUCT *ads,
339 struct registry_key *root_key,
340 const struct nt_user_token *token,
341 struct GROUP_POLICY_OBJECT *gpo,
342 const char *extension_guid,
343 const char *snapin_guid)
348 char *unix_path = NULL;
349 struct gp_inifile_context *ini_ctx = NULL;
350 struct gp_registry_entry *entries = NULL;
351 size_t num_entries = 0;
352 const char *list[] = {
353 GP_SCRIPTS_INI_STARTUP,
354 GP_SCRIPTS_INI_SHUTDOWN,
355 GP_SCRIPTS_INI_LOGON,
356 GP_SCRIPTS_INI_LOGOFF
359 debug_gpext_header(0, "scripts_process_group_policy", flags, gpo,
360 extension_guid, snapin_guid);
362 status = gpo_get_unix_path(mem_ctx, cache_path(GPO_CACHE_DIR), gpo, &unix_path);
363 NT_STATUS_NOT_OK_RETURN(status);
365 status = gp_inifile_init_context(mem_ctx, flags, unix_path,
366 GP_SCRIPTS_INI, &ini_ctx);
367 NT_STATUS_NOT_OK_RETURN(status);
369 for (i = 0; i < ARRAY_SIZE(list); i++) {
371 TALLOC_FREE(entries);
374 status = scripts_parse_ini_section(ini_ctx, flags, list[i],
375 &entries, &num_entries);
376 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
380 if (!NT_STATUS_IS_OK(status)) {
384 dump_reg_entries(flags, "READ", entries, num_entries);
386 werr = scripts_apply(ini_ctx->mem_ctx, token, root_key,
387 flags, list[i], gpo, entries, num_entries);
388 if (!W_ERROR_IS_OK(werr)) {
389 continue; /* FIXME: finally fix storing emtpy strings and REG_QWORD! */
390 TALLOC_FREE(ini_ctx);
391 return werror_to_ntstatus(werr);
395 TALLOC_FREE(ini_ctx);
399 /****************************************************************
400 ****************************************************************/
402 static NTSTATUS scripts_initialize(TALLOC_CTX *mem_ctx)
407 /****************************************************************
408 ****************************************************************/
410 static NTSTATUS scripts_shutdown(void)
414 status = unregister_gp_extension(GP_EXT_NAME);
415 if (NT_STATUS_IS_OK(status)) {
424 /****************************************************************
425 ****************************************************************/
427 static struct gp_extension_methods scripts_methods = {
428 .initialize = scripts_initialize,
429 .process_group_policy = scripts_process_group_policy,
430 .get_reg_config = scripts_get_reg_config,
431 .shutdown = scripts_shutdown
434 /****************************************************************
435 ****************************************************************/
437 NTSTATUS gpext_scripts_init(void)
441 ctx = talloc_init("gpext_scripts_init");
442 NT_STATUS_HAVE_NO_MEMORY(ctx);
444 status = register_gp_extension(ctx, SMB_GPEXT_INTERFACE_VERSION,
445 GP_EXT_NAME, GP_EXT_GUID_SCRIPTS,
447 if (!NT_STATUS_IS_OK(status)) {