Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * Group Policy Object Support
4 : * Copyright (C) Guenther Deschner 2007-2008
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.h"
22 : #include "libgpo/gpo_proto.h"
23 : #include "registry.h"
24 : #include "registry/reg_api.h"
25 : #include "registry/reg_backend_db.h"
26 : #include "registry/reg_api_util.h"
27 : #include "registry/reg_init_basic.h"
28 : #include "../libcli/security/security.h"
29 : #include "libcli/security/dom_sid.h"
30 : #include "../libcli/registry/util_reg.h"
31 :
32 :
33 : /****************************************************************
34 : ****************************************************************/
35 :
36 0 : struct security_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
37 : {
38 0 : const struct security_token *system_token = get_system_token();
39 :
40 0 : struct security_token *dup_token
41 0 : = security_token_duplicate(mem_ctx, system_token);
42 :
43 0 : if (dup_token == NULL) {
44 0 : DBG_WARNING("security_token_duplicate() failed\n");
45 0 : return NULL;
46 : }
47 :
48 0 : return dup_token;
49 : }
50 :
51 : /****************************************************************
52 : ****************************************************************/
53 :
54 0 : WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
55 : const char *initial_path,
56 : uint32_t desired_access,
57 : const struct security_token *token,
58 : struct gp_registry_context **reg_ctx)
59 : {
60 0 : struct gp_registry_context *tmp_ctx;
61 0 : WERROR werr;
62 :
63 0 : if (!reg_ctx) {
64 0 : return WERR_INVALID_PARAMETER;
65 : }
66 :
67 0 : werr = registry_init_basic();
68 0 : if (!W_ERROR_IS_OK(werr)) {
69 0 : return werr;
70 : }
71 :
72 0 : tmp_ctx = talloc_zero(mem_ctx, struct gp_registry_context);
73 0 : W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
74 :
75 0 : if (token) {
76 0 : tmp_ctx->token = token;
77 : } else {
78 0 : tmp_ctx->token = registry_create_system_token(mem_ctx);
79 : }
80 0 : if (!tmp_ctx->token) {
81 0 : TALLOC_FREE(tmp_ctx);
82 0 : return WERR_NOT_ENOUGH_MEMORY;
83 : }
84 :
85 0 : werr = regdb_open();
86 0 : if (!W_ERROR_IS_OK(werr)) {
87 0 : return werr;
88 : }
89 :
90 0 : if (initial_path) {
91 0 : tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
92 0 : if (!tmp_ctx->path) {
93 0 : TALLOC_FREE(tmp_ctx);
94 0 : return WERR_NOT_ENOUGH_MEMORY;
95 : }
96 :
97 0 : werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
98 : tmp_ctx->token, &tmp_ctx->curr_key);
99 0 : if (!W_ERROR_IS_OK(werr)) {
100 0 : TALLOC_FREE(tmp_ctx);
101 0 : return werr;
102 : }
103 : }
104 :
105 0 : *reg_ctx = tmp_ctx;
106 :
107 0 : return WERR_OK;
108 : }
109 :
110 : /****************************************************************
111 : ****************************************************************/
112 :
113 0 : void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
114 : {
115 0 : TALLOC_FREE(reg_ctx);
116 0 : }
117 :
118 : /****************************************************************
119 : ****************************************************************/
120 :
121 0 : WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
122 : const char *subkeyname,
123 : struct registry_key *curr_key,
124 : struct registry_key **new_key)
125 : {
126 0 : enum winreg_CreateAction action = REG_ACTION_NONE;
127 0 : WERROR werr;
128 :
129 0 : werr = reg_createkey(mem_ctx, curr_key, subkeyname,
130 : REG_KEY_WRITE, new_key, &action);
131 0 : if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
132 0 : return WERR_OK;
133 : }
134 :
135 0 : return werr;
136 : }
137 :
138 : /****************************************************************
139 : ****************************************************************/
140 :
141 0 : WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
142 : struct gp_registry_context *reg_ctx,
143 : const char *subkeyname,
144 : struct registry_key **key)
145 : {
146 0 : const char *tmp = NULL;
147 :
148 0 : if (!reg_ctx || !subkeyname || !key) {
149 0 : return WERR_INVALID_PARAMETER;
150 : }
151 :
152 0 : tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
153 0 : W_ERROR_HAVE_NO_MEMORY(tmp);
154 :
155 0 : return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
156 : reg_ctx->token, key);
157 : }
158 :
159 : /****************************************************************
160 : ****************************************************************/
161 :
162 0 : WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
163 : struct registry_key *key,
164 : const char *val_name,
165 : const char *val)
166 : {
167 0 : struct registry_value reg_val;
168 :
169 0 : reg_val.type = REG_SZ;
170 0 : if (!push_reg_sz(mem_ctx, ®_val.data, val)) {
171 0 : return WERR_NOT_ENOUGH_MEMORY;
172 : }
173 :
174 0 : return reg_setvalue(key, val_name, ®_val);
175 : }
176 :
177 : /****************************************************************
178 : ****************************************************************/
179 :
180 0 : static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
181 : struct registry_key *key,
182 : const char *val_name,
183 : uint32_t val)
184 : {
185 0 : struct registry_value reg_val;
186 :
187 0 : reg_val.type = REG_DWORD;
188 0 : reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
189 0 : SIVAL(reg_val.data.data, 0, val);
190 :
191 0 : return reg_setvalue(key, val_name, ®_val);
192 : }
193 :
194 : /****************************************************************
195 : ****************************************************************/
196 :
197 0 : WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
198 : struct registry_key *key,
199 : const char *val_name,
200 : const char **val)
201 : {
202 0 : WERROR werr;
203 0 : struct registry_value *reg_val = NULL;
204 :
205 0 : werr = reg_queryvalue(mem_ctx, key, val_name, ®_val);
206 0 : W_ERROR_NOT_OK_RETURN(werr);
207 :
208 0 : if (reg_val->type != REG_SZ) {
209 0 : return WERR_INVALID_DATATYPE;
210 : }
211 :
212 0 : if (!pull_reg_sz(mem_ctx, ®_val->data, val)) {
213 0 : return WERR_NOT_ENOUGH_MEMORY;
214 : }
215 :
216 0 : return WERR_OK;
217 : }
218 :
219 : /****************************************************************
220 : ****************************************************************/
221 :
222 0 : static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
223 : struct registry_key *key,
224 : const char *val_name,
225 : uint32_t *val)
226 : {
227 0 : WERROR werr;
228 0 : struct registry_value *reg_val = NULL;
229 :
230 0 : werr = reg_queryvalue(mem_ctx, key, val_name, ®_val);
231 0 : W_ERROR_NOT_OK_RETURN(werr);
232 :
233 0 : if (reg_val->type != REG_DWORD) {
234 0 : return WERR_INVALID_DATATYPE;
235 : }
236 :
237 0 : if (reg_val->data.length < 4) {
238 0 : return WERR_INSUFFICIENT_BUFFER;
239 : }
240 0 : *val = IVAL(reg_val->data.data, 0);
241 :
242 0 : return WERR_OK;
243 : }
244 :
245 : /****************************************************************
246 : ****************************************************************/
247 :
248 0 : static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
249 : struct registry_key *key,
250 : struct GROUP_POLICY_OBJECT *gpo)
251 : {
252 0 : WERROR werr;
253 :
254 0 : if (!key || !gpo) {
255 0 : return WERR_INVALID_PARAMETER;
256 : }
257 :
258 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
259 : gpo->version);
260 0 : W_ERROR_NOT_OK_RETURN(werr);
261 :
262 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
263 : true); /* fake */
264 0 : W_ERROR_NOT_OK_RETURN(werr);
265 :
266 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
267 : false); /* fake */
268 0 : W_ERROR_NOT_OK_RETURN(werr);
269 :
270 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
271 0 : (gpo->options & GPO_FLAG_DISABLE));
272 0 : W_ERROR_NOT_OK_RETURN(werr);
273 :
274 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
275 : gpo->options);
276 0 : W_ERROR_NOT_OK_RETURN(werr);
277 :
278 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
279 : gpo->name);
280 0 : W_ERROR_NOT_OK_RETURN(werr);
281 :
282 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
283 0 : gpo->link ? gpo->link : "");
284 0 : W_ERROR_NOT_OK_RETURN(werr);
285 :
286 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
287 : gpo->display_name);
288 0 : W_ERROR_NOT_OK_RETURN(werr);
289 :
290 0 : werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
291 : "");
292 0 : W_ERROR_NOT_OK_RETURN(werr);
293 :
294 0 : return werr;
295 : }
296 :
297 : /****************************************************************
298 : ****************************************************************/
299 :
300 0 : static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
301 : const struct dom_sid *sid,
302 : uint32_t flags)
303 : {
304 0 : struct dom_sid_buf sidbuf;
305 :
306 0 : if (flags & GPO_LIST_FLAG_MACHINE) {
307 0 : return "GroupMembership";
308 : }
309 :
310 0 : return talloc_asprintf(
311 : mem_ctx,
312 : "%s\\%s",
313 : dom_sid_str_buf(sid, &sidbuf),
314 : "GroupMembership");
315 : }
316 :
317 : /****************************************************************
318 : ****************************************************************/
319 :
320 0 : static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
321 : struct registry_key *key,
322 : const struct security_token *token,
323 : uint32_t flags)
324 : {
325 0 : const char *path = NULL;
326 :
327 0 : path = gp_reg_groupmembership_path(mem_ctx, &token->sids[PRIMARY_USER_SID_INDEX],
328 : flags);
329 0 : W_ERROR_HAVE_NO_MEMORY(path);
330 :
331 0 : return reg_deletekey_recursive(key, path);
332 :
333 : }
334 :
335 : /****************************************************************
336 : ****************************************************************/
337 :
338 0 : static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
339 : struct gp_registry_context *reg_ctx,
340 : const struct security_token *token,
341 : uint32_t flags)
342 : {
343 0 : struct registry_key *key = NULL;
344 0 : WERROR werr;
345 0 : uint32_t i = 0;
346 0 : const char *valname = NULL;
347 0 : const char *path = NULL;
348 0 : int count = 0;
349 :
350 0 : path = gp_reg_groupmembership_path(mem_ctx, &token->sids[PRIMARY_USER_SID_INDEX],
351 : flags);
352 0 : W_ERROR_HAVE_NO_MEMORY(path);
353 :
354 0 : gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
355 :
356 0 : werr = gp_store_reg_subkey(mem_ctx, path,
357 : reg_ctx->curr_key, &key);
358 0 : W_ERROR_NOT_OK_RETURN(werr);
359 :
360 0 : for (i=0; i<token->num_sids; i++) {
361 0 : struct dom_sid_buf buf;
362 :
363 0 : valname = talloc_asprintf(mem_ctx, "Group%d", count++);
364 0 : W_ERROR_HAVE_NO_MEMORY(valname);
365 :
366 0 : werr = gp_store_reg_val_sz(
367 : mem_ctx,
368 : key,
369 : valname,
370 0 : dom_sid_str_buf(&token->sids[i], &buf));
371 0 : W_ERROR_NOT_OK_RETURN(werr);
372 : }
373 :
374 0 : werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
375 0 : W_ERROR_NOT_OK_RETURN(werr);
376 :
377 0 : return WERR_OK;
378 : }
379 :
380 : /****************************************************************
381 : ****************************************************************/
382 : #if 0
383 : /* not used yet */
384 : static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
385 : struct gp_registry_context *reg_ctx,
386 : const struct dom_sid *object_sid,
387 : struct security_token **token,
388 : uint32_t flags)
389 : {
390 : struct registry_key *key = NULL;
391 : WERROR werr;
392 : int i = 0;
393 : const char *valname = NULL;
394 : const char *val = NULL;
395 : const char *path = NULL;
396 : uint32_t count = 0;
397 : int num_token_sids = 0;
398 : struct security_token *tmp_token = NULL;
399 :
400 : tmp_token = talloc_zero(mem_ctx, struct security_token);
401 : W_ERROR_HAVE_NO_MEMORY(tmp_token);
402 :
403 : path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
404 : W_ERROR_HAVE_NO_MEMORY(path);
405 :
406 : werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
407 : W_ERROR_NOT_OK_RETURN(werr);
408 :
409 : werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
410 : W_ERROR_NOT_OK_RETURN(werr);
411 :
412 : for (i=0; i<count; i++) {
413 :
414 : valname = talloc_asprintf(mem_ctx, "Group%d", i);
415 : W_ERROR_HAVE_NO_MEMORY(valname);
416 :
417 : werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
418 : W_ERROR_NOT_OK_RETURN(werr);
419 :
420 : if (!string_to_sid(&tmp_token->sids[num_token_sids++],
421 : val)) {
422 : return WERR_INSUFFICIENT_BUFFER;
423 : }
424 : }
425 :
426 : tmp_token->num_sids = num_token_sids;
427 :
428 : *token = tmp_token;
429 :
430 : return WERR_OK;
431 : }
432 : #endif
433 : /****************************************************************
434 : ****************************************************************/
435 :
436 0 : static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
437 : const struct dom_sid *sid,
438 : uint32_t flags)
439 : {
440 0 : struct dom_sid_buf sidbuf;
441 :
442 0 : if (flags & GPO_LIST_FLAG_MACHINE) {
443 0 : return GPO_REG_STATE_MACHINE;
444 : }
445 :
446 0 : return talloc_asprintf(
447 : mem_ctx,
448 : "%s\\%s",
449 : "State",
450 : dom_sid_str_buf(sid, &sidbuf));
451 : }
452 :
453 : /****************************************************************
454 : ****************************************************************/
455 :
456 0 : static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
457 : struct registry_key *key,
458 : const char *path)
459 : {
460 0 : return reg_deletesubkeys_recursive(key, path);
461 : }
462 :
463 : /****************************************************************
464 : ****************************************************************/
465 :
466 0 : WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
467 : uint32_t flags,
468 : const char *dn,
469 : const struct security_token *token,
470 : struct GROUP_POLICY_OBJECT *gpo_list)
471 : {
472 0 : struct gp_registry_context *reg_ctx = NULL;
473 0 : WERROR werr = WERR_GEN_FAILURE;
474 0 : const char *subkeyname = NULL;
475 0 : struct GROUP_POLICY_OBJECT *gpo;
476 0 : int count = 0;
477 0 : struct registry_key *key;
478 :
479 0 : werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
480 : token, ®_ctx);
481 0 : W_ERROR_NOT_OK_RETURN(werr);
482 :
483 0 : werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
484 0 : &token->sids[PRIMARY_USER_SID_INDEX]);
485 0 : if (!W_ERROR_IS_OK(werr)) {
486 0 : DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
487 0 : goto done;
488 : }
489 :
490 0 : werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
491 0 : if (!W_ERROR_IS_OK(werr)) {
492 0 : DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
493 0 : goto done;
494 : }
495 :
496 0 : subkeyname = gp_req_state_path(mem_ctx, &token->sids[PRIMARY_USER_SID_INDEX], flags);
497 0 : if (!subkeyname) {
498 0 : werr = WERR_NOT_ENOUGH_MEMORY;
499 0 : goto done;
500 : }
501 :
502 0 : werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
503 0 : if (!W_ERROR_IS_OK(werr)) {
504 0 : DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
505 : /* goto done; */
506 : }
507 :
508 0 : werr = gp_store_reg_subkey(mem_ctx, subkeyname,
509 0 : reg_ctx->curr_key, ®_ctx->curr_key);
510 0 : if (!W_ERROR_IS_OK(werr)) {
511 0 : goto done;
512 : }
513 :
514 0 : werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
515 : "Distinguished-Name", dn);
516 0 : if (!W_ERROR_IS_OK(werr)) {
517 0 : goto done;
518 : }
519 :
520 : /* store link list */
521 :
522 0 : werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
523 0 : reg_ctx->curr_key, &key);
524 0 : if (!W_ERROR_IS_OK(werr)) {
525 0 : goto done;
526 : }
527 :
528 : /* store gpo list */
529 :
530 0 : werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
531 0 : reg_ctx->curr_key, ®_ctx->curr_key);
532 0 : if (!W_ERROR_IS_OK(werr)) {
533 0 : goto done;
534 : }
535 :
536 0 : for (gpo = gpo_list; gpo; gpo = gpo->next) {
537 :
538 0 : subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
539 0 : if (!subkeyname) {
540 0 : werr = WERR_NOT_ENOUGH_MEMORY;
541 0 : goto done;
542 : }
543 :
544 0 : werr = gp_store_reg_subkey(mem_ctx, subkeyname,
545 0 : reg_ctx->curr_key, &key);
546 0 : if (!W_ERROR_IS_OK(werr)) {
547 0 : goto done;
548 : }
549 :
550 0 : werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
551 0 : if (!W_ERROR_IS_OK(werr)) {
552 0 : DEBUG(0,("gp_reg_state_store: "
553 : "gp_store_reg_gpovals failed for %s: %s\n",
554 : gpo->display_name, win_errstr(werr)));
555 0 : goto done;
556 : }
557 : }
558 0 : done:
559 0 : gp_free_reg_ctx(reg_ctx);
560 0 : return werr;
561 : }
562 :
563 : /****************************************************************
564 : ****************************************************************/
565 :
566 0 : static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
567 : struct registry_key *key,
568 : struct GROUP_POLICY_OBJECT *gpo)
569 : {
570 0 : WERROR werr;
571 :
572 0 : if (!key || !gpo) {
573 0 : return WERR_INVALID_PARAMETER;
574 : }
575 :
576 0 : werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
577 : &gpo->version);
578 0 : W_ERROR_NOT_OK_RETURN(werr);
579 :
580 0 : werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
581 : &gpo->options);
582 0 : W_ERROR_NOT_OK_RETURN(werr);
583 :
584 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
585 : &gpo->name);
586 0 : W_ERROR_NOT_OK_RETURN(werr);
587 :
588 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
589 : &gpo->link);
590 0 : W_ERROR_NOT_OK_RETURN(werr);
591 :
592 0 : werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
593 : &gpo->display_name);
594 0 : W_ERROR_NOT_OK_RETURN(werr);
595 :
596 0 : return werr;
597 : }
598 :
599 : /****************************************************************
600 : ****************************************************************/
601 :
602 0 : static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
603 : struct registry_key *key,
604 : struct GROUP_POLICY_OBJECT **gpo_ret)
605 : {
606 0 : struct GROUP_POLICY_OBJECT *gpo = NULL;
607 0 : WERROR werr;
608 :
609 0 : if (!gpo_ret || !key) {
610 0 : return WERR_INVALID_PARAMETER;
611 : }
612 :
613 0 : gpo = talloc_zero(mem_ctx, struct GROUP_POLICY_OBJECT);
614 0 : W_ERROR_HAVE_NO_MEMORY(gpo);
615 :
616 0 : werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
617 0 : W_ERROR_NOT_OK_RETURN(werr);
618 :
619 0 : *gpo_ret = gpo;
620 :
621 0 : return werr;
622 : }
623 :
624 : /****************************************************************
625 : ****************************************************************/
626 :
627 0 : WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
628 : uint32_t flags,
629 : const struct dom_sid *sid,
630 : struct GROUP_POLICY_OBJECT **gpo_list)
631 : {
632 0 : struct gp_registry_context *reg_ctx = NULL;
633 0 : WERROR werr = WERR_GEN_FAILURE;
634 0 : const char *subkeyname = NULL;
635 0 : struct GROUP_POLICY_OBJECT *gpo = NULL;
636 0 : int count = 0;
637 0 : struct registry_key *key = NULL;
638 0 : const char *path = NULL;
639 0 : const char *gp_state_path = NULL;
640 :
641 0 : if (!gpo_list) {
642 0 : return WERR_INVALID_PARAMETER;
643 : }
644 :
645 0 : ZERO_STRUCTP(gpo_list);
646 :
647 0 : gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
648 0 : if (!gp_state_path) {
649 0 : werr = WERR_NOT_ENOUGH_MEMORY;
650 0 : goto done;
651 : }
652 :
653 0 : path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
654 : KEY_GROUP_POLICY,
655 : gp_state_path,
656 : "GPO-List");
657 0 : if (!path) {
658 0 : werr = WERR_NOT_ENOUGH_MEMORY;
659 0 : goto done;
660 : }
661 :
662 0 : werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, ®_ctx);
663 0 : if (!W_ERROR_IS_OK(werr)) {
664 0 : goto done;
665 : }
666 :
667 0 : while (1) {
668 :
669 0 : subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
670 0 : if (!subkeyname) {
671 0 : werr = WERR_NOT_ENOUGH_MEMORY;
672 0 : goto done;
673 : }
674 :
675 0 : werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
676 0 : if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
677 0 : werr = WERR_OK;
678 0 : break;
679 : }
680 0 : if (!W_ERROR_IS_OK(werr)) {
681 0 : DEBUG(0,("gp_reg_state_read: "
682 : "gp_read_reg_subkey gave: %s\n",
683 : win_errstr(werr)));
684 0 : goto done;
685 : }
686 :
687 0 : werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
688 0 : if (!W_ERROR_IS_OK(werr)) {
689 0 : goto done;
690 : }
691 :
692 0 : DLIST_ADD(*gpo_list, gpo);
693 : }
694 :
695 0 : done:
696 0 : gp_free_reg_ctx(reg_ctx);
697 0 : return werr;
698 : }
699 :
700 : /****************************************************************
701 : ****************************************************************/
702 :
703 0 : static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
704 : const struct dom_sid *sid,
705 : struct security_descriptor **sd,
706 : size_t *sd_size)
707 : {
708 0 : struct security_ace ace[6];
709 0 : uint32_t mask;
710 :
711 0 : struct security_acl *theacl = NULL;
712 :
713 0 : uint8_t inherit_flags;
714 :
715 0 : mask = REG_KEY_ALL;
716 0 : init_sec_ace(&ace[0],
717 : &global_sid_System,
718 : SEC_ACE_TYPE_ACCESS_ALLOWED,
719 : mask, 0);
720 :
721 0 : mask = REG_KEY_ALL;
722 0 : init_sec_ace(&ace[1],
723 : &global_sid_Builtin_Administrators,
724 : SEC_ACE_TYPE_ACCESS_ALLOWED,
725 : mask, 0);
726 :
727 0 : mask = REG_KEY_READ;
728 0 : init_sec_ace(&ace[2],
729 : sid ? sid : &global_sid_Authenticated_Users,
730 : SEC_ACE_TYPE_ACCESS_ALLOWED,
731 : mask, 0);
732 :
733 0 : inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
734 : SEC_ACE_FLAG_CONTAINER_INHERIT |
735 : SEC_ACE_FLAG_INHERIT_ONLY;
736 :
737 0 : mask = REG_KEY_ALL;
738 0 : init_sec_ace(&ace[3],
739 : &global_sid_System,
740 : SEC_ACE_TYPE_ACCESS_ALLOWED,
741 : mask, inherit_flags);
742 :
743 0 : mask = REG_KEY_ALL;
744 0 : init_sec_ace(&ace[4],
745 : &global_sid_Builtin_Administrators,
746 : SEC_ACE_TYPE_ACCESS_ALLOWED,
747 : mask, inherit_flags);
748 :
749 0 : mask = REG_KEY_READ;
750 0 : init_sec_ace(&ace[5],
751 : sid ? sid : &global_sid_Authenticated_Users,
752 : SEC_ACE_TYPE_ACCESS_ALLOWED,
753 : mask, inherit_flags);
754 :
755 0 : theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
756 0 : W_ERROR_HAVE_NO_MEMORY(theacl);
757 :
758 0 : *sd = make_sec_desc(mem_ctx, SD_REVISION,
759 : SEC_DESC_SELF_RELATIVE |
760 : SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
761 : SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
762 : NULL, NULL, NULL,
763 : theacl, sd_size);
764 0 : W_ERROR_HAVE_NO_MEMORY(*sd);
765 :
766 0 : return WERR_OK;
767 : }
768 :
769 : /****************************************************************
770 : ****************************************************************/
771 :
772 0 : WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
773 : uint32_t flags,
774 : struct registry_key *key,
775 : const struct dom_sid *sid)
776 : {
777 0 : struct security_descriptor *sd = NULL;
778 0 : size_t sd_size = 0;
779 0 : const struct dom_sid *sd_sid = NULL;
780 0 : WERROR werr;
781 :
782 0 : if (!(flags & GPO_LIST_FLAG_MACHINE)) {
783 0 : sd_sid = sid;
784 : }
785 :
786 0 : werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
787 0 : W_ERROR_NOT_OK_RETURN(werr);
788 :
789 0 : return reg_setkeysecurity(key, sd);
790 : }
791 :
792 : /****************************************************************
793 : ****************************************************************/
794 :
795 0 : void dump_reg_val(int lvl, const char *direction,
796 : const char *key, const char *subkey,
797 : struct registry_value *val)
798 : {
799 0 : int i = 0;
800 0 : const char *type_str = NULL;
801 :
802 0 : if (!val) {
803 0 : DEBUG(lvl,("no val!\n"));
804 0 : return;
805 : }
806 :
807 0 : type_str = str_regtype(val->type);
808 :
809 0 : DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
810 : direction, key, subkey, type_str));
811 :
812 0 : switch (val->type) {
813 0 : case REG_DWORD: {
814 0 : uint32_t v;
815 0 : if (val->data.length < 4) {
816 0 : break;
817 : }
818 0 : v = IVAL(val->data.data, 0);
819 0 : DEBUG(lvl,("%d (0x%08x)\n",
820 : (int)v, v));
821 0 : break;
822 : }
823 0 : case REG_QWORD: {
824 0 : uint64_t v;
825 0 : if (val->data.length < 8) {
826 0 : break;
827 : }
828 0 : v = BVAL(val->data.data, 0);
829 0 : DEBUG(lvl,("%d (0x%016llx)\n",
830 : (int)v,
831 : (unsigned long long)v));
832 0 : break;
833 : }
834 0 : case REG_SZ: {
835 0 : const char *s;
836 0 : if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
837 0 : break;
838 : }
839 0 : DEBUG(lvl,("%s (length: %d)\n",
840 : s, (int)strlen_m(s)));
841 0 : break;
842 : }
843 0 : case REG_MULTI_SZ: {
844 0 : const char **a;
845 0 : if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
846 0 : break;
847 : }
848 0 : for (i=0; a[i] != NULL; i++) {
849 : ;;
850 : }
851 0 : DEBUG(lvl,("(num_strings: %d)\n", i));
852 0 : for (i=0; a[i] != NULL; i++) {
853 0 : DEBUGADD(lvl,("\t%s\n", a[i]));
854 : }
855 0 : break;
856 : }
857 0 : case REG_NONE:
858 0 : DEBUG(lvl,("\n"));
859 0 : break;
860 0 : case REG_BINARY:
861 0 : dump_data(lvl, val->data.data,
862 0 : val->data.length);
863 0 : break;
864 0 : default:
865 0 : DEBUG(lvl,("unsupported type: %d\n", val->type));
866 0 : break;
867 : }
868 : }
869 :
870 : /****************************************************************
871 : ****************************************************************/
872 :
873 0 : void dump_reg_entry(uint32_t flags,
874 : const char *dir,
875 : struct gp_registry_entry *entry)
876 : {
877 0 : if (!(flags & GPO_INFO_FLAG_VERBOSE))
878 0 : return;
879 :
880 0 : dump_reg_val(1, dir,
881 : entry->key,
882 : entry->value,
883 : entry->data);
884 : }
885 :
886 : /****************************************************************
887 : ****************************************************************/
888 :
889 0 : void dump_reg_entries(uint32_t flags,
890 : const char *dir,
891 : struct gp_registry_entry *entries,
892 : size_t num_entries)
893 : {
894 0 : size_t i;
895 :
896 0 : if (!(flags & GPO_INFO_FLAG_VERBOSE))
897 0 : return;
898 :
899 0 : for (i=0; i < num_entries; i++) {
900 0 : dump_reg_entry(flags, dir, &entries[i]);
901 : }
902 : }
903 :
904 : /****************************************************************
905 : ****************************************************************/
906 :
907 0 : bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
908 : struct gp_registry_entry *entry,
909 : struct gp_registry_entry **entries,
910 : size_t *num)
911 : {
912 0 : *entries = talloc_realloc(mem_ctx, *entries,
913 : struct gp_registry_entry,
914 : (*num)+1);
915 :
916 0 : if (*entries == NULL) {
917 0 : *num = 0;
918 0 : return false;
919 : }
920 :
921 0 : (*entries)[*num].action = entry->action;
922 0 : (*entries)[*num].key = entry->key;
923 0 : (*entries)[*num].value = entry->value;
924 0 : (*entries)[*num].data = entry->data;
925 :
926 0 : *num += 1;
927 0 : return true;
928 : }
929 :
930 : /****************************************************************
931 : ****************************************************************/
932 :
933 0 : static const char *gp_reg_action_str(enum gp_reg_action action)
934 : {
935 0 : switch (action) {
936 0 : case GP_REG_ACTION_NONE:
937 0 : return "GP_REG_ACTION_NONE";
938 0 : case GP_REG_ACTION_ADD_VALUE:
939 0 : return "GP_REG_ACTION_ADD_VALUE";
940 0 : case GP_REG_ACTION_ADD_KEY:
941 0 : return "GP_REG_ACTION_ADD_KEY";
942 0 : case GP_REG_ACTION_DEL_VALUES:
943 0 : return "GP_REG_ACTION_DEL_VALUES";
944 0 : case GP_REG_ACTION_DEL_VALUE:
945 0 : return "GP_REG_ACTION_DEL_VALUE";
946 0 : case GP_REG_ACTION_DEL_ALL_VALUES:
947 0 : return "GP_REG_ACTION_DEL_ALL_VALUES";
948 0 : case GP_REG_ACTION_DEL_KEYS:
949 0 : return "GP_REG_ACTION_DEL_KEYS";
950 0 : case GP_REG_ACTION_SEC_KEY_SET:
951 0 : return "GP_REG_ACTION_SEC_KEY_SET";
952 0 : case GP_REG_ACTION_SEC_KEY_RESET:
953 0 : return "GP_REG_ACTION_SEC_KEY_RESET";
954 0 : default:
955 0 : return "unknown";
956 : }
957 : }
958 :
959 : /****************************************************************
960 : ****************************************************************/
961 :
962 0 : WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
963 : struct registry_key *root_key,
964 : struct gp_registry_context *reg_ctx,
965 : struct gp_registry_entry *entry,
966 : const struct security_token *token,
967 : uint32_t flags)
968 : {
969 0 : WERROR werr;
970 0 : struct registry_key *key = NULL;
971 :
972 0 : if (flags & GPO_INFO_FLAG_VERBOSE) {
973 0 : printf("about to store key: [%s]\n", entry->key);
974 0 : printf(" value: [%s]\n", entry->value);
975 0 : printf(" data: [%s]\n", str_regtype(entry->data->type));
976 0 : printf(" action: [%s]\n", gp_reg_action_str(entry->action));
977 : }
978 :
979 0 : werr = gp_store_reg_subkey(mem_ctx, entry->key,
980 : root_key, &key);
981 : /* reg_ctx->curr_key, &key); */
982 0 : if (!W_ERROR_IS_OK(werr)) {
983 0 : DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
984 0 : return werr;
985 : }
986 :
987 0 : switch (entry->action) {
988 0 : case GP_REG_ACTION_NONE:
989 : case GP_REG_ACTION_ADD_KEY:
990 0 : return WERR_OK;
991 :
992 0 : case GP_REG_ACTION_SEC_KEY_SET:
993 0 : werr = gp_secure_key(mem_ctx, flags,
994 : key,
995 0 : &token->sids[PRIMARY_USER_SID_INDEX]);
996 0 : if (!W_ERROR_IS_OK(werr)) {
997 0 : DEBUG(0,("reg_apply_registry_entry: "
998 : "gp_secure_key failed: %s\n",
999 : win_errstr(werr)));
1000 0 : return werr;
1001 : }
1002 0 : break;
1003 0 : case GP_REG_ACTION_ADD_VALUE:
1004 0 : werr = reg_setvalue(key, entry->value, entry->data);
1005 0 : if (!W_ERROR_IS_OK(werr)) {
1006 0 : DEBUG(0,("reg_apply_registry_entry: "
1007 : "reg_setvalue failed: %s\n",
1008 : win_errstr(werr)));
1009 0 : dump_reg_entry(flags, "STORE", entry);
1010 0 : return werr;
1011 : }
1012 0 : break;
1013 0 : case GP_REG_ACTION_DEL_VALUE:
1014 0 : werr = reg_deletevalue(key, entry->value);
1015 0 : if (!W_ERROR_IS_OK(werr)) {
1016 0 : DEBUG(0,("reg_apply_registry_entry: "
1017 : "reg_deletevalue failed: %s\n",
1018 : win_errstr(werr)));
1019 0 : dump_reg_entry(flags, "STORE", entry);
1020 0 : return werr;
1021 : }
1022 0 : break;
1023 0 : case GP_REG_ACTION_DEL_ALL_VALUES:
1024 0 : werr = reg_deleteallvalues(key);
1025 0 : if (!W_ERROR_IS_OK(werr)) {
1026 0 : DEBUG(0,("reg_apply_registry_entry: "
1027 : "reg_deleteallvalues failed: %s\n",
1028 : win_errstr(werr)));
1029 0 : dump_reg_entry(flags, "STORE", entry);
1030 0 : return werr;
1031 : }
1032 0 : break;
1033 0 : case GP_REG_ACTION_DEL_VALUES:
1034 : case GP_REG_ACTION_DEL_KEYS:
1035 : case GP_REG_ACTION_SEC_KEY_RESET:
1036 0 : DEBUG(0,("reg_apply_registry_entry: "
1037 : "not yet supported: %s (%d)\n",
1038 : gp_reg_action_str(entry->action),
1039 : entry->action));
1040 0 : return WERR_NOT_SUPPORTED;
1041 0 : default:
1042 0 : DEBUG(0,("invalid action: %d\n", entry->action));
1043 0 : return WERR_INVALID_PARAMETER;
1044 : }
1045 :
1046 0 : return werr;
1047 : }
|