source: branches/samba-3.5.x/source3/libgpo/gpext/scripts.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

File size: 11.5 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 * Group Policy Support
4 * Copyright (C) Guenther Deschner 2007
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20#include "includes.h"
21#include "libgpo/gpo_ini.h"
22
23#define GP_EXT_NAME "scripts"
24
25#define KEY_GP_SCRIPTS "Software\\Policies\\Microsoft\\Windows\\System\\Scripts"
26
27#define GP_SCRIPTS_INI "Scripts/scripts.ini"
28
29#define GP_SCRIPTS_INI_STARTUP "Startup"
30#define GP_SCRIPTS_INI_SHUTDOWN "Shutdown"
31#define GP_SCRIPTS_INI_LOGON "Logon"
32#define GP_SCRIPTS_INI_LOGOFF "Logoff"
33
34#define GP_SCRIPTS_SECTION_CMDLINE "cmdline"
35#define GP_SCRIPTS_SECTION_PARAMETERS "parameters"
36
37#define GP_SCRIPTS_REG_VAL_SCRIPT "Script"
38#define GP_SCRIPTS_REG_VAL_PARAMETERS "Parameters"
39#define GP_SCRIPTS_REG_VAL_EXECTIME "ExecTime"
40
41static TALLOC_CTX *ctx = NULL;
42
43/****************************************************************
44****************************************************************/
45
46static NTSTATUS scripts_get_reg_config(TALLOC_CTX *mem_ctx,
47 struct gp_extension_reg_info **reg_info)
48{
49 NTSTATUS status;
50 struct gp_extension_reg_info *info = NULL;
51
52 struct gp_extension_reg_table table[] = {
53 { "ProcessGroupPolicy", REG_SZ, "scripts_process_group_policy" },
54 { "NoGPOListChanges", REG_DWORD, "1" },
55 { "NoSlowLink", REG_DWORD, "1" },
56 { "NotifyLinkTransition", REG_DWORD, "1" },
57 { NULL, REG_NONE, NULL },
58 };
59
60 info = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info);
61 NT_STATUS_HAVE_NO_MEMORY(info);
62
63 status = gp_ext_info_add_entry(mem_ctx, GP_EXT_NAME,
64 GP_EXT_GUID_SCRIPTS,
65 table, info);
66 NT_STATUS_NOT_OK_RETURN(status);
67
68 *reg_info = info;
69
70 return NT_STATUS_OK;
71}
72
73/****************************************************************
74****************************************************************/
75
76static NTSTATUS generate_gp_registry_entry(TALLOC_CTX *mem_ctx,
77 const char *key,
78 const char *value,
79 uint32_t data_type,
80 const void *data_p,
81 enum gp_reg_action action,
82 struct gp_registry_entry **entry_out)
83{
84 struct gp_registry_entry *entry = NULL;
85 struct registry_value *data = NULL;
86
87 entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry);
88 NT_STATUS_HAVE_NO_MEMORY(entry);
89
90 data = TALLOC_ZERO_P(mem_ctx, struct registry_value);
91 NT_STATUS_HAVE_NO_MEMORY(data);
92
93 data->type = data_type;
94 switch (data->type) {
95 case REG_QWORD:
96 data->v.qword = *(uint64_t *)data_p;
97 break;
98 case REG_SZ:
99 data->v.sz.str = talloc_strdup(mem_ctx, (char *)data_p);
100 data->v.sz.len = strlen(data->v.sz.str);
101 break;
102 default:
103 return NT_STATUS_NOT_SUPPORTED;
104 }
105
106 entry->key = key;
107 entry->data = data;
108 entry->action = action;
109 entry->value = talloc_strdup(mem_ctx, value);
110 NT_STATUS_HAVE_NO_MEMORY(entry->value);
111
112 *entry_out = entry;
113
114 return NT_STATUS_OK;
115}
116
117/****************************************************************
118****************************************************************/
119
120static NTSTATUS scripts_parse_ini_section(struct gp_inifile_context *ini_ctx,
121 uint32_t flags,
122 const char *section,
123 struct gp_registry_entry **entries,
124 size_t *num_entries)
125{
126 NTSTATUS status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
127 NTSTATUS result;
128 int i = 0;
129
130 while (1) {
131
132 const char *key = NULL;
133 char *script = NULL;
134 const char *count = NULL;
135 char *parameters = NULL;
136
137 count = talloc_asprintf(ini_ctx->mem_ctx, "%d", i);
138 NT_STATUS_HAVE_NO_MEMORY(count);
139
140 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
141 section, count,
142 GP_SCRIPTS_SECTION_CMDLINE);
143 NT_STATUS_HAVE_NO_MEMORY(key);
144
145 result = gp_inifile_getstring(ini_ctx, key, &script);
146 if (!NT_STATUS_IS_OK(result)) {
147 break;
148 }
149
150 key = talloc_asprintf(ini_ctx->mem_ctx, "%s:%s%s",
151 section, count,
152 GP_SCRIPTS_SECTION_PARAMETERS);
153 NT_STATUS_HAVE_NO_MEMORY(key);
154
155 result = gp_inifile_getstring(ini_ctx, key, &parameters);
156 if (!NT_STATUS_IS_OK(result)) {
157 break;
158 }
159
160 {
161 struct gp_registry_entry *entry = NULL;
162 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
163 count,
164 GP_SCRIPTS_REG_VAL_SCRIPT,
165 REG_SZ,
166 script,
167 GP_REG_ACTION_ADD_VALUE,
168 &entry);
169 NT_STATUS_NOT_OK_RETURN(status);
170 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
171 entry,
172 entries,
173 num_entries)) {
174 return NT_STATUS_NO_MEMORY;
175 }
176 }
177 {
178 struct gp_registry_entry *entry = NULL;
179 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
180 count,
181 GP_SCRIPTS_REG_VAL_PARAMETERS,
182 REG_SZ,
183 parameters,
184 GP_REG_ACTION_ADD_VALUE,
185 &entry);
186 NT_STATUS_NOT_OK_RETURN(status);
187 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
188 entry,
189 entries,
190 num_entries)) {
191 return NT_STATUS_NO_MEMORY;
192 }
193 }
194 {
195 struct gp_registry_entry *entry = NULL;
196 status = generate_gp_registry_entry(ini_ctx->mem_ctx,
197 count,
198 GP_SCRIPTS_REG_VAL_EXECTIME,
199 REG_QWORD,
200 0,
201 GP_REG_ACTION_ADD_VALUE,
202 &entry);
203 NT_STATUS_NOT_OK_RETURN(status);
204 if (!add_gp_registry_entry_to_array(ini_ctx->mem_ctx,
205 entry,
206 entries,
207 num_entries)) {
208 return NT_STATUS_NO_MEMORY;
209 }
210 }
211 status = NT_STATUS_OK;
212 i++;
213 }
214
215 return status;
216}
217
218/****************************************************************
219****************************************************************/
220
221static WERROR scripts_store_reg_gpovals(TALLOC_CTX *mem_ctx,
222 struct registry_key *key,
223 struct GROUP_POLICY_OBJECT *gpo)
224{
225 WERROR werr;
226
227 if (!key || !gpo) {
228 return WERR_INVALID_PARAM;
229 }
230
231 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
232 gpo->display_name);
233 W_ERROR_NOT_OK_RETURN(werr);
234
235 werr = gp_store_reg_val_sz(mem_ctx, key, "FileSysPath",
236 gpo->file_sys_path);
237 W_ERROR_NOT_OK_RETURN(werr);
238
239 werr = gp_store_reg_val_sz(mem_ctx, key, "GPO-ID",
240 gpo->ds_path);
241 W_ERROR_NOT_OK_RETURN(werr);
242
243 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOName",
244 gpo->name);
245 W_ERROR_NOT_OK_RETURN(werr);
246
247 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM-ID",
248 gpo->link);
249 W_ERROR_NOT_OK_RETURN(werr);
250
251 return werr;
252}
253
254/****************************************************************
255****************************************************************/
256
257static WERROR scripts_apply(TALLOC_CTX *mem_ctx,
258 const struct nt_user_token *token,
259 struct registry_key *root_key,
260 uint32_t flags,
261 const char *section,
262 struct GROUP_POLICY_OBJECT *gpo,
263 struct gp_registry_entry *entries,
264 size_t num_entries)
265{
266 struct gp_registry_context *reg_ctx = NULL;
267 WERROR werr;
268 size_t i;
269 const char *keystr = NULL;
270 int count = 0;
271
272 if (num_entries == 0) {
273 return WERR_OK;
274 }
275
276#if 0
277 if (flags & GPO_INFO_FLAG_MACHINE) {
278 struct nt_user_token *tmp_token;
279
280 tmp_token = registry_create_system_token(mem_ctx);
281 W_ERROR_HAVE_NO_MEMORY(tmp_token);
282
283 werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE,
284 tmp_token,
285 &reg_ctx);
286 } else {
287 werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE,
288 token,
289 &reg_ctx);
290 }
291 W_ERROR_NOT_OK_RETURN(werr);
292#endif
293
294 keystr = talloc_asprintf(mem_ctx, "%s\\%s\\%d", KEY_GP_SCRIPTS,
295 section, count++);
296 W_ERROR_HAVE_NO_MEMORY(keystr);
297
298 reg_deletekey_recursive(mem_ctx, root_key, keystr);
299
300 werr = gp_store_reg_subkey(mem_ctx, keystr,
301 root_key, &root_key);
302 if (!W_ERROR_IS_OK(werr)) {
303 goto done;
304 }
305
306 werr = scripts_store_reg_gpovals(mem_ctx, root_key, gpo);
307 if (!W_ERROR_IS_OK(werr)) {
308 goto done;
309 }
310
311 for (i=0; i<num_entries; i++) {
312
313 werr = reg_apply_registry_entry(mem_ctx, root_key, reg_ctx,
314 &(entries)[i],
315 token, flags);
316 if (!W_ERROR_IS_OK(werr)) {
317 DEBUG(0,("failed to apply registry: %s\n",
318 win_errstr(werr)));
319 goto done;
320 }
321 }
322
323 done:
324 gp_free_reg_ctx(reg_ctx);
325 return werr;
326}
327
328/****************************************************************
329****************************************************************/
330
331static NTSTATUS scripts_process_group_policy(ADS_STRUCT *ads,
332 TALLOC_CTX *mem_ctx,
333 uint32_t flags,
334 struct registry_key *root_key,
335 const struct nt_user_token *token,
336 struct GROUP_POLICY_OBJECT *gpo,
337 const char *extension_guid,
338 const char *snapin_guid)
339{
340 NTSTATUS status;
341 WERROR werr;
342 int i = 0;
343 char *unix_path = NULL;
344 struct gp_inifile_context *ini_ctx = NULL;
345 struct gp_registry_entry *entries = NULL;
346 size_t num_entries = 0;
347 const char *list[] = {
348 GP_SCRIPTS_INI_STARTUP,
349 GP_SCRIPTS_INI_SHUTDOWN,
350 GP_SCRIPTS_INI_LOGON,
351 GP_SCRIPTS_INI_LOGOFF
352 };
353
354 debug_gpext_header(0, "scripts_process_group_policy", flags, gpo,
355 extension_guid, snapin_guid);
356
357 status = gpo_get_unix_path(mem_ctx, cache_path(GPO_CACHE_DIR), gpo, &unix_path);
358 NT_STATUS_NOT_OK_RETURN(status);
359
360 status = gp_inifile_init_context(mem_ctx, flags, unix_path,
361 GP_SCRIPTS_INI, &ini_ctx);
362 NT_STATUS_NOT_OK_RETURN(status);
363
364 for (i = 0; i < ARRAY_SIZE(list); i++) {
365
366 TALLOC_FREE(entries);
367 num_entries = 0;
368
369 status = scripts_parse_ini_section(ini_ctx, flags, list[i],
370 &entries, &num_entries);
371 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
372 continue;
373 }
374
375 if (!NT_STATUS_IS_OK(status)) {
376 return status;
377 }
378
379 dump_reg_entries(flags, "READ", entries, num_entries);
380
381 werr = scripts_apply(ini_ctx->mem_ctx, token, root_key,
382 flags, list[i], gpo, entries, num_entries);
383 if (!W_ERROR_IS_OK(werr)) {
384 continue; /* FIXME: finally fix storing emtpy strings and REG_QWORD! */
385 TALLOC_FREE(ini_ctx);
386 return werror_to_ntstatus(werr);
387 }
388 }
389
390 TALLOC_FREE(ini_ctx);
391 return NT_STATUS_OK;
392}
393
394/****************************************************************
395****************************************************************/
396
397static NTSTATUS scripts_initialize(TALLOC_CTX *mem_ctx)
398{
399 return NT_STATUS_OK;
400}
401
402/****************************************************************
403****************************************************************/
404
405static NTSTATUS scripts_shutdown(void)
406{
407 NTSTATUS status;
408
409 status = unregister_gp_extension(GP_EXT_NAME);
410 if (NT_STATUS_IS_OK(status)) {
411 return status;
412 }
413
414 TALLOC_FREE(ctx);
415
416 return NT_STATUS_OK;
417}
418
419/****************************************************************
420****************************************************************/
421
422static struct gp_extension_methods scripts_methods = {
423 .initialize = scripts_initialize,
424 .process_group_policy = scripts_process_group_policy,
425 .get_reg_config = scripts_get_reg_config,
426 .shutdown = scripts_shutdown
427};
428
429/****************************************************************
430****************************************************************/
431
432NTSTATUS gpext_scripts_init(void)
433{
434 NTSTATUS status;
435
436 ctx = talloc_init("gpext_scripts_init");
437 NT_STATUS_HAVE_NO_MEMORY(ctx);
438
439 status = register_gp_extension(ctx, SMB_GPEXT_INTERFACE_VERSION,
440 GP_EXT_NAME, GP_EXT_GUID_SCRIPTS,
441 &scripts_methods);
442 if (!NT_STATUS_IS_OK(status)) {
443 TALLOC_FREE(ctx);
444 }
445
446 return status;
447}
Note: See TracBrowser for help on using the repository browser.