build: moved libds/common/flag_mapping.c into a common subsystem
[Samba.git] / source3 / libgpo / gpo_reg.c
blob45bef570b2b47e7e4425ff50906dbb4a1fb74cd0
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"
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"
31 /****************************************************************
32 ****************************************************************/
34 struct security_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
36 struct security_token *token = NULL;
38 token = TALLOC_ZERO_P(mem_ctx, struct security_token);
39 if (!token) {
40 DEBUG(1,("talloc failed\n"));
41 return NULL;
44 token->privilege_mask = SE_ALL_PRIVS;
46 if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
47 &token->sids, &token->num_sids))) {
48 DEBUG(1,("Error adding nt-authority system sid to token\n"));
49 return NULL;
52 return token;
55 /****************************************************************
56 ****************************************************************/
58 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
59 const char *initial_path,
60 uint32_t desired_access,
61 const struct security_token *token,
62 struct gp_registry_context **reg_ctx)
64 struct gp_registry_context *tmp_ctx;
65 WERROR werr;
67 if (!reg_ctx) {
68 return WERR_INVALID_PARAM;
71 werr = registry_init_basic();
72 if (!W_ERROR_IS_OK(werr)) {
73 return werr;
76 tmp_ctx = TALLOC_ZERO_P(mem_ctx, struct gp_registry_context);
77 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
79 if (token) {
80 tmp_ctx->token = token;
81 } else {
82 tmp_ctx->token = registry_create_system_token(mem_ctx);
84 if (!tmp_ctx->token) {
85 TALLOC_FREE(tmp_ctx);
86 return WERR_NOMEM;
89 werr = regdb_open();
90 if (!W_ERROR_IS_OK(werr)) {
91 return werr;
94 if (initial_path) {
95 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
96 if (!tmp_ctx->path) {
97 TALLOC_FREE(tmp_ctx);
98 return WERR_NOMEM;
101 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
102 tmp_ctx->token, &tmp_ctx->curr_key);
103 if (!W_ERROR_IS_OK(werr)) {
104 TALLOC_FREE(tmp_ctx);
105 return werr;
109 *reg_ctx = tmp_ctx;
111 return WERR_OK;
114 /****************************************************************
115 ****************************************************************/
117 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
119 TALLOC_FREE(reg_ctx);
122 /****************************************************************
123 ****************************************************************/
125 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
126 const char *subkeyname,
127 struct registry_key *curr_key,
128 struct registry_key **new_key)
130 enum winreg_CreateAction action = REG_ACTION_NONE;
131 WERROR werr;
133 werr = reg_createkey(mem_ctx, curr_key, subkeyname,
134 REG_KEY_WRITE, new_key, &action);
135 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
136 return WERR_OK;
139 return werr;
142 /****************************************************************
143 ****************************************************************/
145 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
146 struct gp_registry_context *reg_ctx,
147 const char *subkeyname,
148 struct registry_key **key)
150 const char *tmp = NULL;
152 if (!reg_ctx || !subkeyname || !key) {
153 return WERR_INVALID_PARAM;
156 tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
157 W_ERROR_HAVE_NO_MEMORY(tmp);
159 return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
160 reg_ctx->token, key);
163 /****************************************************************
164 ****************************************************************/
166 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
167 struct registry_key *key,
168 const char *val_name,
169 const char *val)
171 struct registry_value reg_val;
173 reg_val.type = REG_SZ;
174 if (!push_reg_sz(mem_ctx, &reg_val.data, val)) {
175 return WERR_NOMEM;
178 return reg_setvalue(key, val_name, &reg_val);
181 /****************************************************************
182 ****************************************************************/
184 static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
185 struct registry_key *key,
186 const char *val_name,
187 uint32_t val)
189 struct registry_value reg_val;
191 reg_val.type = REG_DWORD;
192 reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
193 SIVAL(reg_val.data.data, 0, val);
195 return reg_setvalue(key, val_name, &reg_val);
198 /****************************************************************
199 ****************************************************************/
201 WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
202 struct registry_key *key,
203 const char *val_name,
204 const char **val)
206 WERROR werr;
207 struct registry_value *reg_val = NULL;
209 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
210 W_ERROR_NOT_OK_RETURN(werr);
212 if (reg_val->type != REG_SZ) {
213 return WERR_INVALID_DATATYPE;
216 if (!pull_reg_sz(mem_ctx, &reg_val->data, val)) {
217 return WERR_NOMEM;
220 return WERR_OK;
223 /****************************************************************
224 ****************************************************************/
226 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
227 struct registry_key *key,
228 const char *val_name,
229 uint32_t *val)
231 WERROR werr;
232 struct registry_value *reg_val = NULL;
234 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
235 W_ERROR_NOT_OK_RETURN(werr);
237 if (reg_val->type != REG_DWORD) {
238 return WERR_INVALID_DATATYPE;
241 if (reg_val->data.length < 4) {
242 return WERR_INSUFFICIENT_BUFFER;
244 *val = IVAL(reg_val->data.data, 0);
246 return WERR_OK;
249 /****************************************************************
250 ****************************************************************/
252 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
253 struct registry_key *key,
254 struct GROUP_POLICY_OBJECT *gpo)
256 WERROR werr;
258 if (!key || !gpo) {
259 return WERR_INVALID_PARAM;
262 werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
263 gpo->version);
264 W_ERROR_NOT_OK_RETURN(werr);
266 werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
267 true); /* fake */
268 W_ERROR_NOT_OK_RETURN(werr);
270 werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
271 false); /* fake */
272 W_ERROR_NOT_OK_RETURN(werr);
274 werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
275 (gpo->options & GPO_FLAG_DISABLE));
276 W_ERROR_NOT_OK_RETURN(werr);
278 werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
279 gpo->options);
280 W_ERROR_NOT_OK_RETURN(werr);
282 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
283 gpo->name);
284 W_ERROR_NOT_OK_RETURN(werr);
286 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
287 gpo->link);
288 W_ERROR_NOT_OK_RETURN(werr);
290 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
291 gpo->display_name);
292 W_ERROR_NOT_OK_RETURN(werr);
294 werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
295 NULL);
296 W_ERROR_NOT_OK_RETURN(werr);
298 return werr;
301 /****************************************************************
302 ****************************************************************/
304 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
305 const struct dom_sid *sid,
306 uint32_t flags)
308 if (flags & GPO_LIST_FLAG_MACHINE) {
309 return "GroupMembership";
312 return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
313 "GroupMembership");
316 /****************************************************************
317 ****************************************************************/
319 static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
320 struct registry_key *key,
321 const struct security_token *token,
322 uint32_t flags)
324 const char *path = NULL;
326 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
327 flags);
328 W_ERROR_HAVE_NO_MEMORY(path);
330 return reg_deletekey_recursive(key, path);
334 /****************************************************************
335 ****************************************************************/
337 static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
338 struct gp_registry_context *reg_ctx,
339 const struct security_token *token,
340 uint32_t flags)
342 struct registry_key *key = NULL;
343 WERROR werr;
344 int i = 0;
345 const char *valname = NULL;
346 const char *path = NULL;
347 const char *val = NULL;
348 int count = 0;
350 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
351 flags);
352 W_ERROR_HAVE_NO_MEMORY(path);
354 gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
356 werr = gp_store_reg_subkey(mem_ctx, path,
357 reg_ctx->curr_key, &key);
358 W_ERROR_NOT_OK_RETURN(werr);
360 for (i=0; i<token->num_sids; i++) {
362 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
363 W_ERROR_HAVE_NO_MEMORY(valname);
365 val = sid_string_talloc(mem_ctx, &token->sids[i]);
366 W_ERROR_HAVE_NO_MEMORY(val);
367 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
368 W_ERROR_NOT_OK_RETURN(werr);
371 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
372 W_ERROR_NOT_OK_RETURN(werr);
374 return WERR_OK;
377 /****************************************************************
378 ****************************************************************/
379 #if 0
380 /* not used yet */
381 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
382 struct gp_registry_context *reg_ctx,
383 const struct dom_sid *object_sid,
384 struct security_token **token,
385 uint32_t flags)
387 struct registry_key *key = NULL;
388 WERROR werr;
389 int i = 0;
390 const char *valname = NULL;
391 const char *val = NULL;
392 const char *path = NULL;
393 uint32_t count = 0;
394 int num_token_sids = 0;
395 struct security_token *tmp_token = NULL;
397 tmp_token = TALLOC_ZERO_P(mem_ctx, struct security_token);
398 W_ERROR_HAVE_NO_MEMORY(tmp_token);
400 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
401 W_ERROR_HAVE_NO_MEMORY(path);
403 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
404 W_ERROR_NOT_OK_RETURN(werr);
406 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
407 W_ERROR_NOT_OK_RETURN(werr);
409 for (i=0; i<count; i++) {
411 valname = talloc_asprintf(mem_ctx, "Group%d", i);
412 W_ERROR_HAVE_NO_MEMORY(valname);
414 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
415 W_ERROR_NOT_OK_RETURN(werr);
417 if (!string_to_sid(&tmp_token->sids[num_token_sids++],
418 val)) {
419 return WERR_INSUFFICIENT_BUFFER;
423 tmp_token->num_sids = num_token_sids;
425 *token = tmp_token;
427 return WERR_OK;
429 #endif
430 /****************************************************************
431 ****************************************************************/
433 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
434 const struct dom_sid *sid,
435 uint32_t flags)
437 if (flags & GPO_LIST_FLAG_MACHINE) {
438 return GPO_REG_STATE_MACHINE;
441 return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid));
444 /****************************************************************
445 ****************************************************************/
447 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
448 struct registry_key *key,
449 const char *path)
451 return reg_deletesubkeys_recursive(key, path);
454 /****************************************************************
455 ****************************************************************/
457 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
458 uint32_t flags,
459 const char *dn,
460 const struct security_token *token,
461 struct GROUP_POLICY_OBJECT *gpo_list)
463 struct gp_registry_context *reg_ctx = NULL;
464 WERROR werr = WERR_GENERAL_FAILURE;
465 const char *subkeyname = NULL;
466 struct GROUP_POLICY_OBJECT *gpo;
467 int count = 0;
468 struct registry_key *key;
470 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
471 token, &reg_ctx);
472 W_ERROR_NOT_OK_RETURN(werr);
474 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
475 &token->sids[0]);
476 if (!W_ERROR_IS_OK(werr)) {
477 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
478 goto done;
481 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
482 if (!W_ERROR_IS_OK(werr)) {
483 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
484 goto done;
487 subkeyname = gp_req_state_path(mem_ctx, &token->sids[0], flags);
488 if (!subkeyname) {
489 werr = WERR_NOMEM;
490 goto done;
493 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
494 if (!W_ERROR_IS_OK(werr)) {
495 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
496 /* goto done; */
499 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
500 reg_ctx->curr_key, &reg_ctx->curr_key);
501 if (!W_ERROR_IS_OK(werr)) {
502 goto done;
505 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
506 "Distinguished-Name", dn);
507 if (!W_ERROR_IS_OK(werr)) {
508 goto done;
511 /* store link list */
513 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
514 reg_ctx->curr_key, &key);
515 if (!W_ERROR_IS_OK(werr)) {
516 goto done;
519 /* store gpo list */
521 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
522 reg_ctx->curr_key, &reg_ctx->curr_key);
523 if (!W_ERROR_IS_OK(werr)) {
524 goto done;
527 for (gpo = gpo_list; gpo; gpo = gpo->next) {
529 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
530 if (!subkeyname) {
531 werr = WERR_NOMEM;
532 goto done;
535 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
536 reg_ctx->curr_key, &key);
537 if (!W_ERROR_IS_OK(werr)) {
538 goto done;
541 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
542 if (!W_ERROR_IS_OK(werr)) {
543 DEBUG(0,("gp_reg_state_store: "
544 "gpo_store_reg_gpovals failed for %s: %s\n",
545 gpo->display_name, win_errstr(werr)));
546 goto done;
549 done:
550 gp_free_reg_ctx(reg_ctx);
551 return werr;
554 /****************************************************************
555 ****************************************************************/
557 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
558 struct registry_key *key,
559 struct GROUP_POLICY_OBJECT *gpo)
561 WERROR werr;
563 if (!key || !gpo) {
564 return WERR_INVALID_PARAM;
567 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
568 &gpo->version);
569 W_ERROR_NOT_OK_RETURN(werr);
571 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
572 &gpo->options);
573 W_ERROR_NOT_OK_RETURN(werr);
575 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
576 &gpo->name);
577 W_ERROR_NOT_OK_RETURN(werr);
579 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
580 &gpo->link);
581 W_ERROR_NOT_OK_RETURN(werr);
583 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
584 &gpo->display_name);
585 W_ERROR_NOT_OK_RETURN(werr);
587 return werr;
590 /****************************************************************
591 ****************************************************************/
593 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
594 struct registry_key *key,
595 struct GROUP_POLICY_OBJECT **gpo_ret)
597 struct GROUP_POLICY_OBJECT *gpo = NULL;
598 WERROR werr;
600 if (!gpo_ret || !key) {
601 return WERR_INVALID_PARAM;
604 gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
605 W_ERROR_HAVE_NO_MEMORY(gpo);
607 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
608 W_ERROR_NOT_OK_RETURN(werr);
610 *gpo_ret = gpo;
612 return werr;
615 /****************************************************************
616 ****************************************************************/
618 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
619 uint32_t flags,
620 const struct dom_sid *sid,
621 struct GROUP_POLICY_OBJECT **gpo_list)
623 struct gp_registry_context *reg_ctx = NULL;
624 WERROR werr = WERR_GENERAL_FAILURE;
625 const char *subkeyname = NULL;
626 struct GROUP_POLICY_OBJECT *gpo = NULL;
627 int count = 0;
628 struct registry_key *key = NULL;
629 const char *path = NULL;
630 const char *gp_state_path = NULL;
632 if (!gpo_list) {
633 return WERR_INVALID_PARAM;
636 ZERO_STRUCTP(gpo_list);
638 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
639 if (!gp_state_path) {
640 werr = WERR_NOMEM;
641 goto done;
644 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
645 KEY_GROUP_POLICY,
646 gp_state_path,
647 "GPO-List");
648 if (!path) {
649 werr = WERR_NOMEM;
650 goto done;
653 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
654 if (!W_ERROR_IS_OK(werr)) {
655 goto done;
658 while (1) {
660 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
661 if (!subkeyname) {
662 werr = WERR_NOMEM;
663 goto done;
666 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
667 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
668 werr = WERR_OK;
669 break;
671 if (!W_ERROR_IS_OK(werr)) {
672 DEBUG(0,("gp_reg_state_read: "
673 "gp_read_reg_subkey gave: %s\n",
674 win_errstr(werr)));
675 goto done;
678 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
679 if (!W_ERROR_IS_OK(werr)) {
680 goto done;
683 DLIST_ADD(*gpo_list, gpo);
686 done:
687 gp_free_reg_ctx(reg_ctx);
688 return werr;
691 /****************************************************************
692 ****************************************************************/
694 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
695 const struct dom_sid *sid,
696 struct security_descriptor **sd,
697 size_t *sd_size)
699 struct security_ace ace[6];
700 uint32_t mask;
702 struct security_acl *theacl = NULL;
704 uint8_t inherit_flags;
706 mask = REG_KEY_ALL;
707 init_sec_ace(&ace[0],
708 &global_sid_System,
709 SEC_ACE_TYPE_ACCESS_ALLOWED,
710 mask, 0);
712 mask = REG_KEY_ALL;
713 init_sec_ace(&ace[1],
714 &global_sid_Builtin_Administrators,
715 SEC_ACE_TYPE_ACCESS_ALLOWED,
716 mask, 0);
718 mask = REG_KEY_READ;
719 init_sec_ace(&ace[2],
720 sid ? sid : &global_sid_Authenticated_Users,
721 SEC_ACE_TYPE_ACCESS_ALLOWED,
722 mask, 0);
724 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
725 SEC_ACE_FLAG_CONTAINER_INHERIT |
726 SEC_ACE_FLAG_INHERIT_ONLY;
728 mask = REG_KEY_ALL;
729 init_sec_ace(&ace[3],
730 &global_sid_System,
731 SEC_ACE_TYPE_ACCESS_ALLOWED,
732 mask, inherit_flags);
734 mask = REG_KEY_ALL;
735 init_sec_ace(&ace[4],
736 &global_sid_Builtin_Administrators,
737 SEC_ACE_TYPE_ACCESS_ALLOWED,
738 mask, inherit_flags);
740 mask = REG_KEY_READ;
741 init_sec_ace(&ace[5],
742 sid ? sid : &global_sid_Authenticated_Users,
743 SEC_ACE_TYPE_ACCESS_ALLOWED,
744 mask, inherit_flags);
746 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
747 W_ERROR_HAVE_NO_MEMORY(theacl);
749 *sd = make_sec_desc(mem_ctx, SD_REVISION,
750 SEC_DESC_SELF_RELATIVE |
751 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
752 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
753 NULL, NULL, NULL,
754 theacl, sd_size);
755 W_ERROR_HAVE_NO_MEMORY(*sd);
757 return WERR_OK;
760 /****************************************************************
761 ****************************************************************/
763 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
764 uint32_t flags,
765 struct registry_key *key,
766 const struct dom_sid *sid)
768 struct security_descriptor *sd = NULL;
769 size_t sd_size = 0;
770 const struct dom_sid *sd_sid = NULL;
771 WERROR werr;
773 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
774 sd_sid = sid;
777 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
778 W_ERROR_NOT_OK_RETURN(werr);
780 return reg_setkeysecurity(key, sd);
783 /****************************************************************
784 ****************************************************************/
786 void dump_reg_val(int lvl, const char *direction,
787 const char *key, const char *subkey,
788 struct registry_value *val)
790 int i = 0;
791 const char *type_str = NULL;
793 if (!val) {
794 DEBUG(lvl,("no val!\n"));
795 return;
798 type_str = str_regtype(val->type);
800 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
801 direction, key, subkey, type_str));
803 switch (val->type) {
804 case REG_DWORD: {
805 uint32_t v;
806 if (val->data.length < 4) {
807 break;
809 v = IVAL(val->data.data, 0);
810 DEBUG(lvl,("%d (0x%08x)\n",
811 (int)v, v));
812 break;
814 case REG_QWORD: {
815 uint64_t v;
816 if (val->data.length < 8) {
817 break;
819 v = BVAL(val->data.data, 0);
820 DEBUG(lvl,("%d (0x%016llx)\n",
821 (int)v,
822 (unsigned long long)v));
823 break;
825 case REG_SZ: {
826 const char *s;
827 if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
828 break;
830 DEBUG(lvl,("%s (length: %d)\n",
831 s, (int)strlen_m(s)));
832 break;
834 case REG_MULTI_SZ: {
835 const char **a;
836 if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
837 break;
839 for (i=0; a[i] != NULL; i++) {
842 DEBUG(lvl,("(num_strings: %d)\n", i));
843 for (i=0; a[i] != NULL; i++) {
844 DEBUGADD(lvl,("\t%s\n", a[i]));
846 break;
848 case REG_NONE:
849 DEBUG(lvl,("\n"));
850 break;
851 case REG_BINARY:
852 dump_data(lvl, val->data.data,
853 val->data.length);
854 break;
855 default:
856 DEBUG(lvl,("unsupported type: %d\n", val->type));
857 break;
861 /****************************************************************
862 ****************************************************************/
864 void dump_reg_entry(uint32_t flags,
865 const char *dir,
866 struct gp_registry_entry *entry)
868 if (!(flags & GPO_INFO_FLAG_VERBOSE))
869 return;
871 dump_reg_val(1, dir,
872 entry->key,
873 entry->value,
874 entry->data);
877 /****************************************************************
878 ****************************************************************/
880 void dump_reg_entries(uint32_t flags,
881 const char *dir,
882 struct gp_registry_entry *entries,
883 size_t num_entries)
885 size_t i;
887 if (!(flags & GPO_INFO_FLAG_VERBOSE))
888 return;
890 for (i=0; i < num_entries; i++) {
891 dump_reg_entry(flags, dir, &entries[i]);
895 /****************************************************************
896 ****************************************************************/
898 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
899 struct gp_registry_entry *entry,
900 struct gp_registry_entry **entries,
901 size_t *num)
903 *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
904 struct gp_registry_entry,
905 (*num)+1);
907 if (*entries == NULL) {
908 *num = 0;
909 return false;
912 (*entries)[*num].action = entry->action;
913 (*entries)[*num].key = entry->key;
914 (*entries)[*num].value = entry->value;
915 (*entries)[*num].data = entry->data;
917 *num += 1;
918 return true;
921 /****************************************************************
922 ****************************************************************/
924 static const char *gp_reg_action_str(enum gp_reg_action action)
926 switch (action) {
927 case GP_REG_ACTION_NONE:
928 return "GP_REG_ACTION_NONE";
929 case GP_REG_ACTION_ADD_VALUE:
930 return "GP_REG_ACTION_ADD_VALUE";
931 case GP_REG_ACTION_ADD_KEY:
932 return "GP_REG_ACTION_ADD_KEY";
933 case GP_REG_ACTION_DEL_VALUES:
934 return "GP_REG_ACTION_DEL_VALUES";
935 case GP_REG_ACTION_DEL_VALUE:
936 return "GP_REG_ACTION_DEL_VALUE";
937 case GP_REG_ACTION_DEL_ALL_VALUES:
938 return "GP_REG_ACTION_DEL_ALL_VALUES";
939 case GP_REG_ACTION_DEL_KEYS:
940 return "GP_REG_ACTION_DEL_KEYS";
941 case GP_REG_ACTION_SEC_KEY_SET:
942 return "GP_REG_ACTION_SEC_KEY_SET";
943 case GP_REG_ACTION_SEC_KEY_RESET:
944 return "GP_REG_ACTION_SEC_KEY_RESET";
945 default:
946 return "unknown";
950 /****************************************************************
951 ****************************************************************/
953 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
954 struct registry_key *root_key,
955 struct gp_registry_context *reg_ctx,
956 struct gp_registry_entry *entry,
957 const struct security_token *token,
958 uint32_t flags)
960 WERROR werr;
961 struct registry_key *key = NULL;
963 if (flags & GPO_INFO_FLAG_VERBOSE) {
964 printf("about to store key: [%s]\n", entry->key);
965 printf(" value: [%s]\n", entry->value);
966 printf(" data: [%s]\n", str_regtype(entry->data->type));
967 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
970 werr = gp_store_reg_subkey(mem_ctx, entry->key,
971 root_key, &key);
972 /* reg_ctx->curr_key, &key); */
973 if (!W_ERROR_IS_OK(werr)) {
974 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
975 return werr;
978 switch (entry->action) {
979 case GP_REG_ACTION_NONE:
980 case GP_REG_ACTION_ADD_KEY:
981 return WERR_OK;
983 case GP_REG_ACTION_SEC_KEY_SET:
984 werr = gp_secure_key(mem_ctx, flags,
985 key,
986 &token->sids[0]);
987 if (!W_ERROR_IS_OK(werr)) {
988 DEBUG(0,("reg_apply_registry_entry: "
989 "gp_secure_key failed: %s\n",
990 win_errstr(werr)));
991 return werr;
993 break;
994 case GP_REG_ACTION_ADD_VALUE:
995 werr = reg_setvalue(key, entry->value, entry->data);
996 if (!W_ERROR_IS_OK(werr)) {
997 DEBUG(0,("reg_apply_registry_entry: "
998 "reg_setvalue failed: %s\n",
999 win_errstr(werr)));
1000 dump_reg_entry(flags, "STORE", entry);
1001 return werr;
1003 break;
1004 case GP_REG_ACTION_DEL_VALUE:
1005 werr = reg_deletevalue(key, entry->value);
1006 if (!W_ERROR_IS_OK(werr)) {
1007 DEBUG(0,("reg_apply_registry_entry: "
1008 "reg_deletevalue failed: %s\n",
1009 win_errstr(werr)));
1010 dump_reg_entry(flags, "STORE", entry);
1011 return werr;
1013 break;
1014 case GP_REG_ACTION_DEL_ALL_VALUES:
1015 werr = reg_deleteallvalues(key);
1016 if (!W_ERROR_IS_OK(werr)) {
1017 DEBUG(0,("reg_apply_registry_entry: "
1018 "reg_deleteallvalues failed: %s\n",
1019 win_errstr(werr)));
1020 dump_reg_entry(flags, "STORE", entry);
1021 return werr;
1023 break;
1024 case GP_REG_ACTION_DEL_VALUES:
1025 case GP_REG_ACTION_DEL_KEYS:
1026 case GP_REG_ACTION_SEC_KEY_RESET:
1027 DEBUG(0,("reg_apply_registry_entry: "
1028 "not yet supported: %s (%d)\n",
1029 gp_reg_action_str(entry->action),
1030 entry->action));
1031 return WERR_NOT_SUPPORTED;
1032 default:
1033 DEBUG(0,("invalid action: %d\n", entry->action));
1034 return WERR_INVALID_PARAM;
1037 return werr;