s3:nmbd: s/struct event_context/struct tevent_context
[Samba/gebeck_regimport.git] / source3 / libgpo / gpext / scripts.c
blob0b6748507a7c820a9ce81584b17816e526429f68
1 /*
2 * Unix SMB/CIFS implementation.
3 * Group Policy Support
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/>.
20 #include "includes.h"
21 #include "../libgpo/gpo_ini.h"
22 #include "../libgpo/gpo.h"
23 #include "libgpo/gpo_proto.h"
24 #include "registry.h"
25 #include "registry/reg_api.h"
26 #include "../libcli/registry/util_reg.h"
28 #define GP_EXT_NAME "scripts"
30 #define KEY_GP_SCRIPTS "Software\\Policies\\Microsoft\\Windows\\System\\Scripts"
32 #define GP_SCRIPTS_INI "Scripts/scripts.ini"
34 #define GP_SCRIPTS_INI_STARTUP "Startup"
35 #define GP_SCRIPTS_INI_SHUTDOWN "Shutdown"
36 #define GP_SCRIPTS_INI_LOGON "Logon"
37 #define GP_SCRIPTS_INI_LOGOFF "Logoff"
39 #define GP_SCRIPTS_SECTION_CMDLINE "cmdline"
40 #define GP_SCRIPTS_SECTION_PARAMETERS "parameters"
42 #define GP_SCRIPTS_REG_VAL_SCRIPT "Script"
43 #define GP_SCRIPTS_REG_VAL_PARAMETERS "Parameters"
44 #define GP_SCRIPTS_REG_VAL_EXECTIME "ExecTime"
46 static TALLOC_CTX *ctx = NULL;
48 /****************************************************************
49 ****************************************************************/
51 static NTSTATUS scripts_get_reg_config(TALLOC_CTX *mem_ctx,
52 struct gp_extension_reg_info **reg_info)
54 NTSTATUS status;
55 struct gp_extension_reg_info *info = NULL;
57 struct gp_extension_reg_table table[] = {
58 { "ProcessGroupPolicy", REG_SZ, "scripts_process_group_policy" },
59 { "NoGPOListChanges", REG_DWORD, "1" },
60 { "NoSlowLink", REG_DWORD, "1" },
61 { "NotifyLinkTransition", REG_DWORD, "1" },
62 { NULL, REG_NONE, NULL },
65 info = talloc_zero(mem_ctx, struct gp_extension_reg_info);
66 NT_STATUS_HAVE_NO_MEMORY(info);
68 status = gp_ext_info_add_entry(mem_ctx, GP_EXT_NAME,
69 GP_EXT_GUID_SCRIPTS,
70 table, info);
71 NT_STATUS_NOT_OK_RETURN(status);
73 *reg_info = info;
75 return NT_STATUS_OK;
78 /****************************************************************
79 ****************************************************************/
81 static NTSTATUS generate_gp_registry_entry(TALLOC_CTX *mem_ctx,
82 const char *key,
83 const char *value,
84 uint32_t data_type,
85 const void *data_p,
86 enum gp_reg_action action,
87 struct gp_registry_entry **entry_out)
89 struct gp_registry_entry *entry = NULL;
90 struct registry_value *data = NULL;
92 entry = talloc_zero(mem_ctx, struct gp_registry_entry);
93 NT_STATUS_HAVE_NO_MEMORY(entry);
95 data = talloc_zero(mem_ctx, struct registry_value);
96 NT_STATUS_HAVE_NO_MEMORY(data);
98 data->type = data_type;
99 switch (data->type) {
100 case REG_QWORD:
101 data->data = data_blob_talloc(mem_ctx, NULL, 8);
102 SBVAL(data->data.data, 0, *(uint64_t *)data_p);
103 break;
104 case REG_SZ:
105 if (!push_reg_sz(mem_ctx, &data->data, (char *)data_p)) {
106 return NT_STATUS_NO_MEMORY;
108 break;
109 default:
110 return NT_STATUS_NOT_SUPPORTED;
113 entry->key = key;
114 entry->data = data;
115 entry->action = action;
116 entry->value = talloc_strdup(mem_ctx, value);
117 NT_STATUS_HAVE_NO_MEMORY(entry->value);
119 *entry_out = entry;
121 return NT_STATUS_OK;
124 /****************************************************************
125 ****************************************************************/
127 static NTSTATUS scripts_parse_ini_section(struct gp_inifile_context *ini_ctx,
128 uint32_t flags,
129 const char *section,
130 struct gp_registry_entry **entries,
131 size_t *num_entries)
133 NTSTATUS status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
134 NTSTATUS result;
135 int i = 0;
137 while (1) {
139 const char *key = NULL;
140 char *script = NULL;
141 const char *count = NULL;
142 char *parameters = NULL;
144 count = talloc_asprintf(ini_ctx->mem_ctx, "%d", i);
145 NT_STATUS_HAVE_NO_MEMORY(count);
147 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
148 section, count,
149 GP_SCRIPTS_SECTION_CMDLINE);
150 NT_STATUS_HAVE_NO_MEMORY(key);
152 result = gp_inifile_getstring(ini_ctx, key, &script);
153 if (!NT_STATUS_IS_OK(result)) {
154 break;
157 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
158 section, count,
159 GP_SCRIPTS_SECTION_PARAMETERS);
160 NT_STATUS_HAVE_NO_MEMORY(key);
162 result = gp_inifile_getstring(ini_ctx, key, &parameters);
163 if (!NT_STATUS_IS_OK(result)) {
164 break;
168 struct gp_registry_entry *entry = NULL;
169 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
170 count,
171 GP_SCRIPTS_REG_VAL_SCRIPT,
172 REG_SZ,
173 script,
174 GP_REG_ACTION_ADD_VALUE,
175 &entry);
176 NT_STATUS_NOT_OK_RETURN(status);
177 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
178 entry,
179 entries,
180 num_entries)) {
181 return NT_STATUS_NO_MEMORY;
185 struct gp_registry_entry *entry = NULL;
186 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
187 count,
188 GP_SCRIPTS_REG_VAL_PARAMETERS,
189 REG_SZ,
190 parameters,
191 GP_REG_ACTION_ADD_VALUE,
192 &entry);
193 NT_STATUS_NOT_OK_RETURN(status);
194 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
195 entry,
196 entries,
197 num_entries)) {
198 return NT_STATUS_NO_MEMORY;
202 struct gp_registry_entry *entry = NULL;
203 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
204 count,
205 GP_SCRIPTS_REG_VAL_EXECTIME,
206 REG_QWORD,
208 GP_REG_ACTION_ADD_VALUE,
209 &entry);
210 NT_STATUS_NOT_OK_RETURN(status);
211 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
212 entry,
213 entries,
214 num_entries)) {
215 return NT_STATUS_NO_MEMORY;
218 status = NT_STATUS_OK;
219 i++;
222 return status;
225 /****************************************************************
226 ****************************************************************/
228 static WERROR scripts_store_reg_gpovals(TALLOC_CTX *mem_ctx,
229 struct registry_key *key,
230 struct GROUP_POLICY_OBJECT *gpo)
232 WERROR werr;
234 if (!key || !gpo) {
235 return WERR_INVALID_PARAM;
238 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
239 gpo->display_name);
240 W_ERROR_NOT_OK_RETURN(werr);
242 werr = gp_store_reg_val_sz(mem_ctx, key, "FileSysPath",
243 gpo->file_sys_path);
244 W_ERROR_NOT_OK_RETURN(werr);
246 werr = gp_store_reg_val_sz(mem_ctx, key, "GPO-ID",
247 gpo->ds_path);
248 W_ERROR_NOT_OK_RETURN(werr);
250 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOName",
251 gpo->name);
252 W_ERROR_NOT_OK_RETURN(werr);
254 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM-ID",
255 gpo->link);
256 W_ERROR_NOT_OK_RETURN(werr);
258 return werr;
261 /****************************************************************
262 ****************************************************************/
264 static WERROR scripts_apply(TALLOC_CTX *mem_ctx,
265 const struct security_token *token,
266 struct registry_key *root_key,
267 uint32_t flags,
268 const char *section,
269 struct GROUP_POLICY_OBJECT *gpo,
270 struct gp_registry_entry *entries,
271 size_t num_entries)
273 struct gp_registry_context *reg_ctx = NULL;
274 WERROR werr;
275 size_t i;
276 const char *keystr = NULL;
277 int count = 0;
279 if (num_entries == 0) {
280 return WERR_OK;
283 #if 0
284 if (flags & GPO_INFO_FLAG_MACHINE) {
285 struct security_token *tmp_token;
287 tmp_token = registry_create_system_token(mem_ctx);
288 W_ERROR_HAVE_NO_MEMORY(tmp_token);
290 werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE,
291 tmp_token,
292 &reg_ctx);
293 } else {
294 werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE,
295 token,
296 &reg_ctx);
298 W_ERROR_NOT_OK_RETURN(werr);
299 #endif
301 keystr = talloc_asprintf(mem_ctx, "%s\\%s\\%d", KEY_GP_SCRIPTS,
302 section, count++);
303 W_ERROR_HAVE_NO_MEMORY(keystr);
305 reg_deletekey_recursive(root_key, keystr);
307 werr = gp_store_reg_subkey(mem_ctx, keystr,
308 root_key, &root_key);
309 if (!W_ERROR_IS_OK(werr)) {
310 goto done;
313 werr = scripts_store_reg_gpovals(mem_ctx, root_key, gpo);
314 if (!W_ERROR_IS_OK(werr)) {
315 goto done;
318 for (i=0; i<num_entries; i++) {
320 werr = reg_apply_registry_entry(mem_ctx, root_key, reg_ctx,
321 &(entries)[i],
322 token, flags);
323 if (!W_ERROR_IS_OK(werr)) {
324 DEBUG(0,("failed to apply registry: %s\n",
325 win_errstr(werr)));
326 goto done;
330 done:
331 gp_free_reg_ctx(reg_ctx);
332 return werr;
335 /****************************************************************
336 ****************************************************************/
338 static NTSTATUS scripts_process_group_policy(ADS_STRUCT *ads,
339 TALLOC_CTX *mem_ctx,
340 uint32_t flags,
341 struct registry_key *root_key,
342 const struct security_token *token,
343 struct GROUP_POLICY_OBJECT *gpo,
344 const char *extension_guid,
345 const char *snapin_guid)
347 NTSTATUS status;
348 WERROR werr;
349 int i = 0;
350 char *unix_path = NULL;
351 struct gp_inifile_context *ini_ctx = NULL;
352 struct gp_registry_entry *entries = NULL;
353 size_t num_entries = 0;
354 const char *list[] = {
355 GP_SCRIPTS_INI_STARTUP,
356 GP_SCRIPTS_INI_SHUTDOWN,
357 GP_SCRIPTS_INI_LOGON,
358 GP_SCRIPTS_INI_LOGOFF
361 debug_gpext_header(0, "scripts_process_group_policy", flags, gpo,
362 extension_guid, snapin_guid);
364 status = gpo_get_unix_path(mem_ctx, cache_path(GPO_CACHE_DIR), gpo, &unix_path);
365 NT_STATUS_NOT_OK_RETURN(status);
367 status = gp_inifile_init_context(mem_ctx, flags, unix_path,
368 GP_SCRIPTS_INI, &ini_ctx);
369 NT_STATUS_NOT_OK_RETURN(status);
371 for (i = 0; i < ARRAY_SIZE(list); i++) {
373 TALLOC_FREE(entries);
374 num_entries = 0;
376 status = scripts_parse_ini_section(ini_ctx, flags, list[i],
377 &entries, &num_entries);
378 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
379 continue;
382 if (!NT_STATUS_IS_OK(status)) {
383 return status;
386 dump_reg_entries(flags, "READ", entries, num_entries);
388 werr = scripts_apply(ini_ctx->mem_ctx, token, root_key,
389 flags, list[i], gpo, entries, num_entries);
390 if (!W_ERROR_IS_OK(werr)) {
391 continue; /* FIXME: finally fix storing emtpy strings and REG_QWORD! */
392 TALLOC_FREE(ini_ctx);
393 return werror_to_ntstatus(werr);
397 TALLOC_FREE(ini_ctx);
398 return NT_STATUS_OK;
401 /****************************************************************
402 ****************************************************************/
404 static NTSTATUS scripts_initialize(TALLOC_CTX *mem_ctx)
406 return NT_STATUS_OK;
409 /****************************************************************
410 ****************************************************************/
412 static NTSTATUS scripts_shutdown(void)
414 NTSTATUS status;
416 status = unregister_gp_extension(GP_EXT_NAME);
417 if (NT_STATUS_IS_OK(status)) {
418 return status;
421 TALLOC_FREE(ctx);
423 return NT_STATUS_OK;
426 /****************************************************************
427 ****************************************************************/
429 static struct gp_extension_methods scripts_methods = {
430 .initialize = scripts_initialize,
431 .process_group_policy = scripts_process_group_policy,
432 .get_reg_config = scripts_get_reg_config,
433 .shutdown = scripts_shutdown
436 /****************************************************************
437 ****************************************************************/
439 NTSTATUS gpext_scripts_init(void)
441 NTSTATUS status;
443 ctx = talloc_init("gpext_scripts_init");
444 NT_STATUS_HAVE_NO_MEMORY(ctx);
446 status = register_gp_extension(ctx, SMB_GPEXT_INTERFACE_VERSION,
447 GP_EXT_NAME, GP_EXT_GUID_SCRIPTS,
448 &scripts_methods);
449 if (!NT_STATUS_IS_OK(status)) {
450 TALLOC_FREE(ctx);
453 return status;