Fix self granting privileges in security=ads.
[Samba.git] / source3 / libgpo / gpo_reg.c
blob9367bcae9c24b644d737dd169c32b25476fe5830
1 /*
2 * Unix SMB/CIFS implementation.
3 * Group Policy Object Support
4 * Copyright (C) Guenther Deschner 2007-2008
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"
23 /****************************************************************
24 ****************************************************************/
26 struct nt_user_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
28 struct nt_user_token *token = NULL;
30 token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
31 if (!token) {
32 DEBUG(1,("talloc failed\n"));
33 return NULL;
36 token->privileges = se_priv_all;
38 if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
39 &token->user_sids, &token->num_sids))) {
40 DEBUG(1,("Error adding nt-authority system sid to token\n"));
41 return NULL;
44 return token;
47 /****************************************************************
48 ****************************************************************/
50 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
51 const char *initial_path,
52 uint32_t desired_access,
53 const struct nt_user_token *token,
54 struct gp_registry_context **reg_ctx)
56 struct gp_registry_context *tmp_ctx;
57 WERROR werr;
59 if (!reg_ctx) {
60 return WERR_INVALID_PARAM;
63 werr = registry_init_basic();
64 if (!W_ERROR_IS_OK(werr)) {
65 return werr;
68 tmp_ctx = TALLOC_ZERO_P(mem_ctx, struct gp_registry_context);
69 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
71 if (token) {
72 tmp_ctx->token = token;
73 } else {
74 tmp_ctx->token = registry_create_system_token(mem_ctx);
76 if (!tmp_ctx->token) {
77 TALLOC_FREE(tmp_ctx);
78 return WERR_NOMEM;
81 werr = regdb_open();
82 if (!W_ERROR_IS_OK(werr)) {
83 return werr;
86 if (initial_path) {
87 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
88 if (!tmp_ctx->path) {
89 TALLOC_FREE(tmp_ctx);
90 return WERR_NOMEM;
93 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
94 tmp_ctx->token, &tmp_ctx->curr_key);
95 if (!W_ERROR_IS_OK(werr)) {
96 TALLOC_FREE(tmp_ctx);
97 return werr;
101 *reg_ctx = tmp_ctx;
103 return WERR_OK;
106 /****************************************************************
107 ****************************************************************/
109 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
111 TALLOC_FREE(reg_ctx);
114 /****************************************************************
115 ****************************************************************/
117 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
118 const char *subkeyname,
119 struct registry_key *curr_key,
120 struct registry_key **new_key)
122 enum winreg_CreateAction action = REG_ACTION_NONE;
123 WERROR werr;
125 werr = reg_createkey(mem_ctx, curr_key, subkeyname,
126 REG_KEY_WRITE, new_key, &action);
127 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
128 return WERR_OK;
131 return werr;
134 /****************************************************************
135 ****************************************************************/
137 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
138 struct gp_registry_context *reg_ctx,
139 const char *subkeyname,
140 struct registry_key **key)
142 const char *tmp = NULL;
144 if (!reg_ctx || !subkeyname || !key) {
145 return WERR_INVALID_PARAM;
148 tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
149 W_ERROR_HAVE_NO_MEMORY(tmp);
151 return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
152 reg_ctx->token, key);
155 /****************************************************************
156 ****************************************************************/
158 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
159 struct registry_key *key,
160 const char *val_name,
161 const char *val)
163 struct registry_value reg_val;
164 ZERO_STRUCT(reg_val);
166 /* FIXME: hack */
167 val = val ? val : " ";
169 reg_val.type = REG_SZ;
170 reg_val.v.sz.len = strlen(val);
171 reg_val.v.sz.str = talloc_strdup(mem_ctx, val);
172 W_ERROR_HAVE_NO_MEMORY(reg_val.v.sz.str);
174 return reg_setvalue(key, val_name, &reg_val);
177 /****************************************************************
178 ****************************************************************/
180 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)
185 struct registry_value reg_val;
186 ZERO_STRUCT(reg_val);
188 reg_val.type = REG_DWORD;
189 reg_val.v.dword = val;
191 return reg_setvalue(key, val_name, &reg_val);
194 /****************************************************************
195 ****************************************************************/
197 WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
198 struct registry_key *key,
199 const char *val_name,
200 const char **val)
202 WERROR werr;
203 struct registry_value *reg_val = NULL;
205 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
206 W_ERROR_NOT_OK_RETURN(werr);
208 if (reg_val->type != REG_SZ) {
209 return WERR_INVALID_DATATYPE;
212 *val = talloc_strdup(mem_ctx, reg_val->v.sz.str);
213 W_ERROR_HAVE_NO_MEMORY(*val);
215 return WERR_OK;
218 /****************************************************************
219 ****************************************************************/
221 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
222 struct registry_key *key,
223 const char *val_name,
224 uint32_t *val)
226 WERROR werr;
227 struct registry_value *reg_val = NULL;
229 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
230 W_ERROR_NOT_OK_RETURN(werr);
232 if (reg_val->type != REG_DWORD) {
233 return WERR_INVALID_DATATYPE;
236 *val = reg_val->v.dword;
238 return WERR_OK;
241 /****************************************************************
242 ****************************************************************/
244 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
245 struct registry_key *key,
246 struct GROUP_POLICY_OBJECT *gpo)
248 WERROR werr;
250 if (!key || !gpo) {
251 return WERR_INVALID_PARAM;
254 werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
255 gpo->version);
256 W_ERROR_NOT_OK_RETURN(werr);
258 werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
259 true); /* fake */
260 W_ERROR_NOT_OK_RETURN(werr);
262 werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
263 false); /* fake */
264 W_ERROR_NOT_OK_RETURN(werr);
266 werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
267 (gpo->options & GPO_FLAG_DISABLE));
268 W_ERROR_NOT_OK_RETURN(werr);
270 werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
271 gpo->options);
272 W_ERROR_NOT_OK_RETURN(werr);
274 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
275 gpo->name);
276 W_ERROR_NOT_OK_RETURN(werr);
278 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
279 gpo->link);
280 W_ERROR_NOT_OK_RETURN(werr);
282 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
283 gpo->display_name);
284 W_ERROR_NOT_OK_RETURN(werr);
286 werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
287 NULL);
288 W_ERROR_NOT_OK_RETURN(werr);
290 return werr;
293 /****************************************************************
294 ****************************************************************/
296 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
297 const DOM_SID *sid,
298 uint32_t flags)
300 if (flags & GPO_LIST_FLAG_MACHINE) {
301 return "GroupMembership";
304 return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
305 "GroupMembership");
308 /****************************************************************
309 ****************************************************************/
311 static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
312 struct registry_key *key,
313 const struct nt_user_token *token,
314 uint32_t flags)
316 const char *path = NULL;
318 path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
319 flags);
320 W_ERROR_HAVE_NO_MEMORY(path);
322 return reg_deletekey_recursive(mem_ctx, key, path);
326 /****************************************************************
327 ****************************************************************/
329 static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
330 struct gp_registry_context *reg_ctx,
331 const struct nt_user_token *token,
332 uint32_t flags)
334 struct registry_key *key = NULL;
335 WERROR werr;
336 int i = 0;
337 const char *valname = NULL;
338 const char *path = NULL;
339 const char *val = NULL;
340 int count = 0;
342 path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
343 flags);
344 W_ERROR_HAVE_NO_MEMORY(path);
346 gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
348 werr = gp_store_reg_subkey(mem_ctx, path,
349 reg_ctx->curr_key, &key);
350 W_ERROR_NOT_OK_RETURN(werr);
352 for (i=0; i<token->num_sids; i++) {
354 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
355 W_ERROR_HAVE_NO_MEMORY(valname);
357 val = sid_string_talloc(mem_ctx, &token->user_sids[i]);
358 W_ERROR_HAVE_NO_MEMORY(val);
359 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
360 W_ERROR_NOT_OK_RETURN(werr);
363 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
364 W_ERROR_NOT_OK_RETURN(werr);
366 return WERR_OK;
369 /****************************************************************
370 ****************************************************************/
371 #if 0
372 /* not used yet */
373 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
374 struct gp_registry_context *reg_ctx,
375 const DOM_SID *object_sid,
376 struct nt_user_token **token,
377 uint32_t flags)
379 struct registry_key *key = NULL;
380 WERROR werr;
381 int i = 0;
382 const char *valname = NULL;
383 const char *val = NULL;
384 const char *path = NULL;
385 uint32_t count = 0;
386 int num_token_sids = 0;
387 struct nt_user_token *tmp_token = NULL;
389 tmp_token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
390 W_ERROR_HAVE_NO_MEMORY(tmp_token);
392 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
393 W_ERROR_HAVE_NO_MEMORY(path);
395 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
396 W_ERROR_NOT_OK_RETURN(werr);
398 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
399 W_ERROR_NOT_OK_RETURN(werr);
401 for (i=0; i<count; i++) {
403 valname = talloc_asprintf(mem_ctx, "Group%d", i);
404 W_ERROR_HAVE_NO_MEMORY(valname);
406 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
407 W_ERROR_NOT_OK_RETURN(werr);
409 if (!string_to_sid(&tmp_token->user_sids[num_token_sids++],
410 val)) {
411 return WERR_INSUFFICIENT_BUFFER;
415 tmp_token->num_sids = num_token_sids;
417 *token = tmp_token;
419 return WERR_OK;
421 #endif
422 /****************************************************************
423 ****************************************************************/
425 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
426 const DOM_SID *sid,
427 uint32_t flags)
429 if (flags & GPO_LIST_FLAG_MACHINE) {
430 return GPO_REG_STATE_MACHINE;
433 return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid));
436 /****************************************************************
437 ****************************************************************/
439 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
440 struct registry_key *key,
441 const char *path)
443 return reg_deletesubkeys_recursive(mem_ctx, key, path);
446 /****************************************************************
447 ****************************************************************/
449 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
450 uint32_t flags,
451 const char *dn,
452 const struct nt_user_token *token,
453 struct GROUP_POLICY_OBJECT *gpo_list)
455 struct gp_registry_context *reg_ctx = NULL;
456 WERROR werr = WERR_GENERAL_FAILURE;
457 const char *subkeyname = NULL;
458 struct GROUP_POLICY_OBJECT *gpo;
459 int count = 0;
460 struct registry_key *key;
462 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
463 token, &reg_ctx);
464 W_ERROR_NOT_OK_RETURN(werr);
466 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
467 &token->user_sids[0]);
468 if (!W_ERROR_IS_OK(werr)) {
469 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
470 goto done;
473 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
474 if (!W_ERROR_IS_OK(werr)) {
475 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
476 goto done;
479 subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags);
480 if (!subkeyname) {
481 werr = WERR_NOMEM;
482 goto done;
485 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
486 if (!W_ERROR_IS_OK(werr)) {
487 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
488 /* goto done; */
491 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
492 reg_ctx->curr_key, &reg_ctx->curr_key);
493 if (!W_ERROR_IS_OK(werr)) {
494 goto done;
497 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
498 "Distinguished-Name", dn);
499 if (!W_ERROR_IS_OK(werr)) {
500 goto done;
503 /* store link list */
505 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
506 reg_ctx->curr_key, &key);
507 if (!W_ERROR_IS_OK(werr)) {
508 goto done;
511 /* store gpo list */
513 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
514 reg_ctx->curr_key, &reg_ctx->curr_key);
515 if (!W_ERROR_IS_OK(werr)) {
516 goto done;
519 for (gpo = gpo_list; gpo; gpo = gpo->next) {
521 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
522 if (!subkeyname) {
523 werr = WERR_NOMEM;
524 goto done;
527 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
528 reg_ctx->curr_key, &key);
529 if (!W_ERROR_IS_OK(werr)) {
530 goto done;
533 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
534 if (!W_ERROR_IS_OK(werr)) {
535 DEBUG(0,("gp_reg_state_store: "
536 "gpo_store_reg_gpovals failed for %s: %s\n",
537 gpo->display_name, win_errstr(werr)));
538 goto done;
541 done:
542 gp_free_reg_ctx(reg_ctx);
543 return werr;
546 /****************************************************************
547 ****************************************************************/
549 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
550 struct registry_key *key,
551 struct GROUP_POLICY_OBJECT *gpo)
553 WERROR werr;
555 if (!key || !gpo) {
556 return WERR_INVALID_PARAM;
559 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
560 &gpo->version);
561 W_ERROR_NOT_OK_RETURN(werr);
563 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
564 &gpo->options);
565 W_ERROR_NOT_OK_RETURN(werr);
567 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
568 &gpo->name);
569 W_ERROR_NOT_OK_RETURN(werr);
571 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
572 &gpo->link);
573 W_ERROR_NOT_OK_RETURN(werr);
575 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
576 &gpo->display_name);
577 W_ERROR_NOT_OK_RETURN(werr);
579 return werr;
582 /****************************************************************
583 ****************************************************************/
585 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
586 struct registry_key *key,
587 struct GROUP_POLICY_OBJECT **gpo_ret)
589 struct GROUP_POLICY_OBJECT *gpo = NULL;
590 WERROR werr;
592 if (!gpo_ret || !key) {
593 return WERR_INVALID_PARAM;
596 gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
597 W_ERROR_HAVE_NO_MEMORY(gpo);
599 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
600 W_ERROR_NOT_OK_RETURN(werr);
602 *gpo_ret = gpo;
604 return werr;
607 /****************************************************************
608 ****************************************************************/
610 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
611 uint32_t flags,
612 const DOM_SID *sid,
613 struct GROUP_POLICY_OBJECT **gpo_list)
615 struct gp_registry_context *reg_ctx = NULL;
616 WERROR werr = WERR_GENERAL_FAILURE;
617 const char *subkeyname = NULL;
618 struct GROUP_POLICY_OBJECT *gpo = NULL;
619 int count = 0;
620 struct registry_key *key = NULL;
621 const char *path = NULL;
622 const char *gp_state_path = NULL;
624 if (!gpo_list) {
625 return WERR_INVALID_PARAM;
628 ZERO_STRUCTP(gpo_list);
630 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
631 if (!gp_state_path) {
632 werr = WERR_NOMEM;
633 goto done;
636 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
637 KEY_GROUP_POLICY,
638 gp_state_path,
639 "GPO-List");
640 if (!path) {
641 werr = WERR_NOMEM;
642 goto done;
645 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
646 if (!W_ERROR_IS_OK(werr)) {
647 goto done;
650 while (1) {
652 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
653 if (!subkeyname) {
654 werr = WERR_NOMEM;
655 goto done;
658 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
659 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
660 werr = WERR_OK;
661 break;
663 if (!W_ERROR_IS_OK(werr)) {
664 DEBUG(0,("gp_reg_state_read: "
665 "gp_read_reg_subkey gave: %s\n",
666 win_errstr(werr)));
667 goto done;
670 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
671 if (!W_ERROR_IS_OK(werr)) {
672 goto done;
675 DLIST_ADD(*gpo_list, gpo);
678 done:
679 gp_free_reg_ctx(reg_ctx);
680 return werr;
683 /****************************************************************
684 ****************************************************************/
686 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
687 const DOM_SID *sid,
688 struct security_descriptor **sd,
689 size_t *sd_size)
691 SEC_ACE ace[6];
692 uint32_t mask;
694 SEC_ACL *theacl = NULL;
696 uint8_t inherit_flags;
698 mask = REG_KEY_ALL;
699 init_sec_ace(&ace[0],
700 &global_sid_System,
701 SEC_ACE_TYPE_ACCESS_ALLOWED,
702 mask, 0);
704 mask = REG_KEY_ALL;
705 init_sec_ace(&ace[1],
706 &global_sid_Builtin_Administrators,
707 SEC_ACE_TYPE_ACCESS_ALLOWED,
708 mask, 0);
710 mask = REG_KEY_READ;
711 init_sec_ace(&ace[2],
712 sid ? sid : &global_sid_Authenticated_Users,
713 SEC_ACE_TYPE_ACCESS_ALLOWED,
714 mask, 0);
716 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
717 SEC_ACE_FLAG_CONTAINER_INHERIT |
718 SEC_ACE_FLAG_INHERIT_ONLY;
720 mask = REG_KEY_ALL;
721 init_sec_ace(&ace[3],
722 &global_sid_System,
723 SEC_ACE_TYPE_ACCESS_ALLOWED,
724 mask, inherit_flags);
726 mask = REG_KEY_ALL;
727 init_sec_ace(&ace[4],
728 &global_sid_Builtin_Administrators,
729 SEC_ACE_TYPE_ACCESS_ALLOWED,
730 mask, inherit_flags);
732 mask = REG_KEY_READ;
733 init_sec_ace(&ace[5],
734 sid ? sid : &global_sid_Authenticated_Users,
735 SEC_ACE_TYPE_ACCESS_ALLOWED,
736 mask, inherit_flags);
738 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
739 W_ERROR_HAVE_NO_MEMORY(theacl);
741 *sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
742 SEC_DESC_SELF_RELATIVE |
743 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
744 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
745 NULL, NULL, NULL,
746 theacl, sd_size);
747 W_ERROR_HAVE_NO_MEMORY(*sd);
749 return WERR_OK;
752 /****************************************************************
753 ****************************************************************/
755 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
756 uint32_t flags,
757 struct registry_key *key,
758 const DOM_SID *sid)
760 struct security_descriptor *sd = NULL;
761 size_t sd_size = 0;
762 const DOM_SID *sd_sid = NULL;
763 WERROR werr;
765 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
766 sd_sid = sid;
769 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
770 W_ERROR_NOT_OK_RETURN(werr);
772 return reg_setkeysecurity(key, sd);
775 /****************************************************************
776 ****************************************************************/
778 void dump_reg_val(int lvl, const char *direction,
779 const char *key, const char *subkey,
780 struct registry_value *val)
782 int i = 0;
783 const char *type_str = NULL;
785 if (!val) {
786 DEBUG(lvl,("no val!\n"));
787 return;
790 type_str = reg_type_lookup(val->type);
792 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
793 direction, key, subkey, type_str));
795 switch (val->type) {
796 case REG_DWORD:
797 DEBUG(lvl,("%d (0x%08x)\n",
798 (int)val->v.dword, val->v.dword));
799 break;
800 case REG_QWORD:
801 DEBUG(lvl,("%d (0x%016llx)\n",
802 (int)val->v.qword,
803 (unsigned long long)val->v.qword));
804 break;
805 case REG_SZ:
806 DEBUG(lvl,("%s (length: %d)\n",
807 val->v.sz.str,
808 (int)val->v.sz.len));
809 break;
810 case REG_MULTI_SZ:
811 DEBUG(lvl,("(num_strings: %d)\n",
812 val->v.multi_sz.num_strings));
813 for (i=0; i < val->v.multi_sz.num_strings; i++) {
814 DEBUGADD(lvl,("\t%s\n",
815 val->v.multi_sz.strings[i]));
817 break;
818 case REG_NONE:
819 DEBUG(lvl,("\n"));
820 break;
821 case REG_BINARY:
822 dump_data(lvl, val->v.binary.data,
823 val->v.binary.length);
824 break;
825 default:
826 DEBUG(lvl,("unsupported type: %d\n", val->type));
827 break;
831 /****************************************************************
832 ****************************************************************/
834 void dump_reg_entry(uint32_t flags,
835 const char *dir,
836 struct gp_registry_entry *entry)
838 if (!(flags & GPO_INFO_FLAG_VERBOSE))
839 return;
841 dump_reg_val(1, dir,
842 entry->key,
843 entry->value,
844 entry->data);
847 /****************************************************************
848 ****************************************************************/
850 void dump_reg_entries(uint32_t flags,
851 const char *dir,
852 struct gp_registry_entry *entries,
853 size_t num_entries)
855 size_t i;
857 if (!(flags & GPO_INFO_FLAG_VERBOSE))
858 return;
860 for (i=0; i < num_entries; i++) {
861 dump_reg_entry(flags, dir, &entries[i]);
865 /****************************************************************
866 ****************************************************************/
868 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
869 struct gp_registry_entry *entry,
870 struct gp_registry_entry **entries,
871 size_t *num)
873 *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
874 struct gp_registry_entry,
875 (*num)+1);
877 if (*entries == NULL) {
878 *num = 0;
879 return false;
882 (*entries)[*num].action = entry->action;
883 (*entries)[*num].key = entry->key;
884 (*entries)[*num].value = entry->value;
885 (*entries)[*num].data = entry->data;
887 *num += 1;
888 return true;
891 /****************************************************************
892 ****************************************************************/
894 static const char *gp_reg_action_str(enum gp_reg_action action)
896 switch (action) {
897 case GP_REG_ACTION_NONE:
898 return "GP_REG_ACTION_NONE";
899 case GP_REG_ACTION_ADD_VALUE:
900 return "GP_REG_ACTION_ADD_VALUE";
901 case GP_REG_ACTION_ADD_KEY:
902 return "GP_REG_ACTION_ADD_KEY";
903 case GP_REG_ACTION_DEL_VALUES:
904 return "GP_REG_ACTION_DEL_VALUES";
905 case GP_REG_ACTION_DEL_VALUE:
906 return "GP_REG_ACTION_DEL_VALUE";
907 case GP_REG_ACTION_DEL_ALL_VALUES:
908 return "GP_REG_ACTION_DEL_ALL_VALUES";
909 case GP_REG_ACTION_DEL_KEYS:
910 return "GP_REG_ACTION_DEL_KEYS";
911 case GP_REG_ACTION_SEC_KEY_SET:
912 return "GP_REG_ACTION_SEC_KEY_SET";
913 case GP_REG_ACTION_SEC_KEY_RESET:
914 return "GP_REG_ACTION_SEC_KEY_RESET";
915 default:
916 return "unknown";
920 /****************************************************************
921 ****************************************************************/
923 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
924 struct registry_key *root_key,
925 struct gp_registry_context *reg_ctx,
926 struct gp_registry_entry *entry,
927 const struct nt_user_token *token,
928 uint32_t flags)
930 WERROR werr;
931 struct registry_key *key = NULL;
933 if (flags & GPO_INFO_FLAG_VERBOSE) {
934 printf("about to store key: [%s]\n", entry->key);
935 printf(" value: [%s]\n", entry->value);
936 printf(" data: [%s]\n", reg_type_lookup(entry->data->type));
937 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
940 werr = gp_store_reg_subkey(mem_ctx, entry->key,
941 root_key, &key);
942 /* reg_ctx->curr_key, &key); */
943 if (!W_ERROR_IS_OK(werr)) {
944 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
945 return werr;
948 switch (entry->action) {
949 case GP_REG_ACTION_NONE:
950 case GP_REG_ACTION_ADD_KEY:
951 return WERR_OK;
953 case GP_REG_ACTION_SEC_KEY_SET:
954 werr = gp_secure_key(mem_ctx, flags,
955 key,
956 &token->user_sids[0]);
957 if (!W_ERROR_IS_OK(werr)) {
958 DEBUG(0,("reg_apply_registry_entry: "
959 "gp_secure_key failed: %s\n",
960 win_errstr(werr)));
961 return werr;
963 break;
964 case GP_REG_ACTION_ADD_VALUE:
965 werr = reg_setvalue(key, entry->value, entry->data);
966 if (!W_ERROR_IS_OK(werr)) {
967 DEBUG(0,("reg_apply_registry_entry: "
968 "reg_setvalue failed: %s\n",
969 win_errstr(werr)));
970 dump_reg_entry(flags, "STORE", entry);
971 return werr;
973 break;
974 case GP_REG_ACTION_DEL_VALUE:
975 werr = reg_deletevalue(key, entry->value);
976 if (!W_ERROR_IS_OK(werr)) {
977 DEBUG(0,("reg_apply_registry_entry: "
978 "reg_deletevalue failed: %s\n",
979 win_errstr(werr)));
980 dump_reg_entry(flags, "STORE", entry);
981 return werr;
983 break;
984 case GP_REG_ACTION_DEL_ALL_VALUES:
985 werr = reg_deleteallvalues(key);
986 if (!W_ERROR_IS_OK(werr)) {
987 DEBUG(0,("reg_apply_registry_entry: "
988 "reg_deleteallvalues failed: %s\n",
989 win_errstr(werr)));
990 dump_reg_entry(flags, "STORE", entry);
991 return werr;
993 break;
994 case GP_REG_ACTION_DEL_VALUES:
995 case GP_REG_ACTION_DEL_KEYS:
996 case GP_REG_ACTION_SEC_KEY_RESET:
997 DEBUG(0,("reg_apply_registry_entry: "
998 "not yet supported: %s (%d)\n",
999 gp_reg_action_str(entry->action),
1000 entry->action));
1001 return WERR_NOT_SUPPORTED;
1002 default:
1003 DEBUG(0,("invalid action: %d\n", entry->action));
1004 return WERR_INVALID_PARAM;
1007 return werr;