s3-torture: replace cli_errstr() with nt_errstr()
[Samba/bb.git] / source3 / libgpo / gpo_reg.c
blob5142e919cc981e500bda634ab7af4d804b86ec56
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"
29 #include "../libcli/registry/util_reg.h"
32 /****************************************************************
33 ****************************************************************/
35 struct security_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
37 struct security_token *token = NULL;
39 token = talloc_zero(mem_ctx, struct security_token);
40 if (!token) {
41 DEBUG(1,("talloc failed\n"));
42 return NULL;
45 token->privilege_mask = SE_ALL_PRIVS;
47 if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
48 &token->sids, &token->num_sids))) {
49 DEBUG(1,("Error adding nt-authority system sid to token\n"));
50 return NULL;
53 return token;
56 /****************************************************************
57 ****************************************************************/
59 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
60 const char *initial_path,
61 uint32_t desired_access,
62 const struct security_token *token,
63 struct gp_registry_context **reg_ctx)
65 struct gp_registry_context *tmp_ctx;
66 WERROR werr;
68 if (!reg_ctx) {
69 return WERR_INVALID_PARAM;
72 werr = registry_init_basic();
73 if (!W_ERROR_IS_OK(werr)) {
74 return werr;
77 tmp_ctx = talloc_zero(mem_ctx, struct gp_registry_context);
78 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
80 if (token) {
81 tmp_ctx->token = token;
82 } else {
83 tmp_ctx->token = registry_create_system_token(mem_ctx);
85 if (!tmp_ctx->token) {
86 TALLOC_FREE(tmp_ctx);
87 return WERR_NOMEM;
90 werr = regdb_open();
91 if (!W_ERROR_IS_OK(werr)) {
92 return werr;
95 if (initial_path) {
96 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
97 if (!tmp_ctx->path) {
98 TALLOC_FREE(tmp_ctx);
99 return WERR_NOMEM;
102 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
103 tmp_ctx->token, &tmp_ctx->curr_key);
104 if (!W_ERROR_IS_OK(werr)) {
105 TALLOC_FREE(tmp_ctx);
106 return werr;
110 *reg_ctx = tmp_ctx;
112 return WERR_OK;
115 /****************************************************************
116 ****************************************************************/
118 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
120 TALLOC_FREE(reg_ctx);
123 /****************************************************************
124 ****************************************************************/
126 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
127 const char *subkeyname,
128 struct registry_key *curr_key,
129 struct registry_key **new_key)
131 enum winreg_CreateAction action = REG_ACTION_NONE;
132 WERROR werr;
134 werr = reg_createkey(mem_ctx, curr_key, subkeyname,
135 REG_KEY_WRITE, new_key, &action);
136 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
137 return WERR_OK;
140 return werr;
143 /****************************************************************
144 ****************************************************************/
146 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
147 struct gp_registry_context *reg_ctx,
148 const char *subkeyname,
149 struct registry_key **key)
151 const char *tmp = NULL;
153 if (!reg_ctx || !subkeyname || !key) {
154 return WERR_INVALID_PARAM;
157 tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
158 W_ERROR_HAVE_NO_MEMORY(tmp);
160 return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
161 reg_ctx->token, key);
164 /****************************************************************
165 ****************************************************************/
167 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
168 struct registry_key *key,
169 const char *val_name,
170 const char *val)
172 struct registry_value reg_val;
174 reg_val.type = REG_SZ;
175 if (!push_reg_sz(mem_ctx, &reg_val.data, val)) {
176 return WERR_NOMEM;
179 return reg_setvalue(key, val_name, &reg_val);
182 /****************************************************************
183 ****************************************************************/
185 static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
186 struct registry_key *key,
187 const char *val_name,
188 uint32_t val)
190 struct registry_value reg_val;
192 reg_val.type = REG_DWORD;
193 reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
194 SIVAL(reg_val.data.data, 0, val);
196 return reg_setvalue(key, val_name, &reg_val);
199 /****************************************************************
200 ****************************************************************/
202 WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
203 struct registry_key *key,
204 const char *val_name,
205 const char **val)
207 WERROR werr;
208 struct registry_value *reg_val = NULL;
210 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
211 W_ERROR_NOT_OK_RETURN(werr);
213 if (reg_val->type != REG_SZ) {
214 return WERR_INVALID_DATATYPE;
217 if (!pull_reg_sz(mem_ctx, &reg_val->data, val)) {
218 return WERR_NOMEM;
221 return WERR_OK;
224 /****************************************************************
225 ****************************************************************/
227 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
228 struct registry_key *key,
229 const char *val_name,
230 uint32_t *val)
232 WERROR werr;
233 struct registry_value *reg_val = NULL;
235 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
236 W_ERROR_NOT_OK_RETURN(werr);
238 if (reg_val->type != REG_DWORD) {
239 return WERR_INVALID_DATATYPE;
242 if (reg_val->data.length < 4) {
243 return WERR_INSUFFICIENT_BUFFER;
245 *val = IVAL(reg_val->data.data, 0);
247 return WERR_OK;
250 /****************************************************************
251 ****************************************************************/
253 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
254 struct registry_key *key,
255 struct GROUP_POLICY_OBJECT *gpo)
257 WERROR werr;
259 if (!key || !gpo) {
260 return WERR_INVALID_PARAM;
263 werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
264 gpo->version);
265 W_ERROR_NOT_OK_RETURN(werr);
267 werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
268 true); /* fake */
269 W_ERROR_NOT_OK_RETURN(werr);
271 werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
272 false); /* fake */
273 W_ERROR_NOT_OK_RETURN(werr);
275 werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
276 (gpo->options & GPO_FLAG_DISABLE));
277 W_ERROR_NOT_OK_RETURN(werr);
279 werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
280 gpo->options);
281 W_ERROR_NOT_OK_RETURN(werr);
283 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
284 gpo->name);
285 W_ERROR_NOT_OK_RETURN(werr);
287 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
288 gpo->link);
289 W_ERROR_NOT_OK_RETURN(werr);
291 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
292 gpo->display_name);
293 W_ERROR_NOT_OK_RETURN(werr);
295 werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
296 NULL);
297 W_ERROR_NOT_OK_RETURN(werr);
299 return werr;
302 /****************************************************************
303 ****************************************************************/
305 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
306 const struct dom_sid *sid,
307 uint32_t flags)
309 if (flags & GPO_LIST_FLAG_MACHINE) {
310 return "GroupMembership";
313 return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
314 "GroupMembership");
317 /****************************************************************
318 ****************************************************************/
320 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)
325 const char *path = NULL;
327 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
328 flags);
329 W_ERROR_HAVE_NO_MEMORY(path);
331 return reg_deletekey_recursive(key, path);
335 /****************************************************************
336 ****************************************************************/
338 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)
343 struct registry_key *key = NULL;
344 WERROR werr;
345 int i = 0;
346 const char *valname = NULL;
347 const char *path = NULL;
348 const char *val = NULL;
349 int count = 0;
351 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
352 flags);
353 W_ERROR_HAVE_NO_MEMORY(path);
355 gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
357 werr = gp_store_reg_subkey(mem_ctx, path,
358 reg_ctx->curr_key, &key);
359 W_ERROR_NOT_OK_RETURN(werr);
361 for (i=0; i<token->num_sids; i++) {
363 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
364 W_ERROR_HAVE_NO_MEMORY(valname);
366 val = sid_string_talloc(mem_ctx, &token->sids[i]);
367 W_ERROR_HAVE_NO_MEMORY(val);
368 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
369 W_ERROR_NOT_OK_RETURN(werr);
372 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
373 W_ERROR_NOT_OK_RETURN(werr);
375 return WERR_OK;
378 /****************************************************************
379 ****************************************************************/
380 #if 0
381 /* not used yet */
382 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
383 struct gp_registry_context *reg_ctx,
384 const struct dom_sid *object_sid,
385 struct security_token **token,
386 uint32_t flags)
388 struct registry_key *key = NULL;
389 WERROR werr;
390 int i = 0;
391 const char *valname = NULL;
392 const char *val = NULL;
393 const char *path = NULL;
394 uint32_t count = 0;
395 int num_token_sids = 0;
396 struct security_token *tmp_token = NULL;
398 tmp_token = talloc_zero(mem_ctx, struct security_token);
399 W_ERROR_HAVE_NO_MEMORY(tmp_token);
401 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
402 W_ERROR_HAVE_NO_MEMORY(path);
404 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
405 W_ERROR_NOT_OK_RETURN(werr);
407 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
408 W_ERROR_NOT_OK_RETURN(werr);
410 for (i=0; i<count; i++) {
412 valname = talloc_asprintf(mem_ctx, "Group%d", i);
413 W_ERROR_HAVE_NO_MEMORY(valname);
415 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
416 W_ERROR_NOT_OK_RETURN(werr);
418 if (!string_to_sid(&tmp_token->sids[num_token_sids++],
419 val)) {
420 return WERR_INSUFFICIENT_BUFFER;
424 tmp_token->num_sids = num_token_sids;
426 *token = tmp_token;
428 return WERR_OK;
430 #endif
431 /****************************************************************
432 ****************************************************************/
434 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
435 const struct dom_sid *sid,
436 uint32_t flags)
438 if (flags & GPO_LIST_FLAG_MACHINE) {
439 return GPO_REG_STATE_MACHINE;
442 return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid));
445 /****************************************************************
446 ****************************************************************/
448 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
449 struct registry_key *key,
450 const char *path)
452 return reg_deletesubkeys_recursive(key, path);
455 /****************************************************************
456 ****************************************************************/
458 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
459 uint32_t flags,
460 const char *dn,
461 const struct security_token *token,
462 struct GROUP_POLICY_OBJECT *gpo_list)
464 struct gp_registry_context *reg_ctx = NULL;
465 WERROR werr = WERR_GENERAL_FAILURE;
466 const char *subkeyname = NULL;
467 struct GROUP_POLICY_OBJECT *gpo;
468 int count = 0;
469 struct registry_key *key;
471 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
472 token, &reg_ctx);
473 W_ERROR_NOT_OK_RETURN(werr);
475 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
476 &token->sids[0]);
477 if (!W_ERROR_IS_OK(werr)) {
478 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
479 goto done;
482 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
483 if (!W_ERROR_IS_OK(werr)) {
484 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
485 goto done;
488 subkeyname = gp_req_state_path(mem_ctx, &token->sids[0], flags);
489 if (!subkeyname) {
490 werr = WERR_NOMEM;
491 goto done;
494 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
495 if (!W_ERROR_IS_OK(werr)) {
496 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
497 /* goto done; */
500 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
501 reg_ctx->curr_key, &reg_ctx->curr_key);
502 if (!W_ERROR_IS_OK(werr)) {
503 goto done;
506 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
507 "Distinguished-Name", dn);
508 if (!W_ERROR_IS_OK(werr)) {
509 goto done;
512 /* store link list */
514 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
515 reg_ctx->curr_key, &key);
516 if (!W_ERROR_IS_OK(werr)) {
517 goto done;
520 /* store gpo list */
522 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
523 reg_ctx->curr_key, &reg_ctx->curr_key);
524 if (!W_ERROR_IS_OK(werr)) {
525 goto done;
528 for (gpo = gpo_list; gpo; gpo = gpo->next) {
530 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
531 if (!subkeyname) {
532 werr = WERR_NOMEM;
533 goto done;
536 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
537 reg_ctx->curr_key, &key);
538 if (!W_ERROR_IS_OK(werr)) {
539 goto done;
542 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
543 if (!W_ERROR_IS_OK(werr)) {
544 DEBUG(0,("gp_reg_state_store: "
545 "gpo_store_reg_gpovals failed for %s: %s\n",
546 gpo->display_name, win_errstr(werr)));
547 goto done;
550 done:
551 gp_free_reg_ctx(reg_ctx);
552 return werr;
555 /****************************************************************
556 ****************************************************************/
558 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
559 struct registry_key *key,
560 struct GROUP_POLICY_OBJECT *gpo)
562 WERROR werr;
564 if (!key || !gpo) {
565 return WERR_INVALID_PARAM;
568 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
569 &gpo->version);
570 W_ERROR_NOT_OK_RETURN(werr);
572 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
573 &gpo->options);
574 W_ERROR_NOT_OK_RETURN(werr);
576 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
577 &gpo->name);
578 W_ERROR_NOT_OK_RETURN(werr);
580 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
581 &gpo->link);
582 W_ERROR_NOT_OK_RETURN(werr);
584 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
585 &gpo->display_name);
586 W_ERROR_NOT_OK_RETURN(werr);
588 return werr;
591 /****************************************************************
592 ****************************************************************/
594 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
595 struct registry_key *key,
596 struct GROUP_POLICY_OBJECT **gpo_ret)
598 struct GROUP_POLICY_OBJECT *gpo = NULL;
599 WERROR werr;
601 if (!gpo_ret || !key) {
602 return WERR_INVALID_PARAM;
605 gpo = talloc_zero(mem_ctx, struct GROUP_POLICY_OBJECT);
606 W_ERROR_HAVE_NO_MEMORY(gpo);
608 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
609 W_ERROR_NOT_OK_RETURN(werr);
611 *gpo_ret = gpo;
613 return werr;
616 /****************************************************************
617 ****************************************************************/
619 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
620 uint32_t flags,
621 const struct dom_sid *sid,
622 struct GROUP_POLICY_OBJECT **gpo_list)
624 struct gp_registry_context *reg_ctx = NULL;
625 WERROR werr = WERR_GENERAL_FAILURE;
626 const char *subkeyname = NULL;
627 struct GROUP_POLICY_OBJECT *gpo = NULL;
628 int count = 0;
629 struct registry_key *key = NULL;
630 const char *path = NULL;
631 const char *gp_state_path = NULL;
633 if (!gpo_list) {
634 return WERR_INVALID_PARAM;
637 ZERO_STRUCTP(gpo_list);
639 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
640 if (!gp_state_path) {
641 werr = WERR_NOMEM;
642 goto done;
645 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
646 KEY_GROUP_POLICY,
647 gp_state_path,
648 "GPO-List");
649 if (!path) {
650 werr = WERR_NOMEM;
651 goto done;
654 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
655 if (!W_ERROR_IS_OK(werr)) {
656 goto done;
659 while (1) {
661 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
662 if (!subkeyname) {
663 werr = WERR_NOMEM;
664 goto done;
667 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
668 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
669 werr = WERR_OK;
670 break;
672 if (!W_ERROR_IS_OK(werr)) {
673 DEBUG(0,("gp_reg_state_read: "
674 "gp_read_reg_subkey gave: %s\n",
675 win_errstr(werr)));
676 goto done;
679 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
680 if (!W_ERROR_IS_OK(werr)) {
681 goto done;
684 DLIST_ADD(*gpo_list, gpo);
687 done:
688 gp_free_reg_ctx(reg_ctx);
689 return werr;
692 /****************************************************************
693 ****************************************************************/
695 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
696 const struct dom_sid *sid,
697 struct security_descriptor **sd,
698 size_t *sd_size)
700 struct security_ace ace[6];
701 uint32_t mask;
703 struct security_acl *theacl = NULL;
705 uint8_t inherit_flags;
707 mask = REG_KEY_ALL;
708 init_sec_ace(&ace[0],
709 &global_sid_System,
710 SEC_ACE_TYPE_ACCESS_ALLOWED,
711 mask, 0);
713 mask = REG_KEY_ALL;
714 init_sec_ace(&ace[1],
715 &global_sid_Builtin_Administrators,
716 SEC_ACE_TYPE_ACCESS_ALLOWED,
717 mask, 0);
719 mask = REG_KEY_READ;
720 init_sec_ace(&ace[2],
721 sid ? sid : &global_sid_Authenticated_Users,
722 SEC_ACE_TYPE_ACCESS_ALLOWED,
723 mask, 0);
725 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
726 SEC_ACE_FLAG_CONTAINER_INHERIT |
727 SEC_ACE_FLAG_INHERIT_ONLY;
729 mask = REG_KEY_ALL;
730 init_sec_ace(&ace[3],
731 &global_sid_System,
732 SEC_ACE_TYPE_ACCESS_ALLOWED,
733 mask, inherit_flags);
735 mask = REG_KEY_ALL;
736 init_sec_ace(&ace[4],
737 &global_sid_Builtin_Administrators,
738 SEC_ACE_TYPE_ACCESS_ALLOWED,
739 mask, inherit_flags);
741 mask = REG_KEY_READ;
742 init_sec_ace(&ace[5],
743 sid ? sid : &global_sid_Authenticated_Users,
744 SEC_ACE_TYPE_ACCESS_ALLOWED,
745 mask, inherit_flags);
747 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
748 W_ERROR_HAVE_NO_MEMORY(theacl);
750 *sd = make_sec_desc(mem_ctx, SD_REVISION,
751 SEC_DESC_SELF_RELATIVE |
752 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
753 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
754 NULL, NULL, NULL,
755 theacl, sd_size);
756 W_ERROR_HAVE_NO_MEMORY(*sd);
758 return WERR_OK;
761 /****************************************************************
762 ****************************************************************/
764 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
765 uint32_t flags,
766 struct registry_key *key,
767 const struct dom_sid *sid)
769 struct security_descriptor *sd = NULL;
770 size_t sd_size = 0;
771 const struct dom_sid *sd_sid = NULL;
772 WERROR werr;
774 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
775 sd_sid = sid;
778 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
779 W_ERROR_NOT_OK_RETURN(werr);
781 return reg_setkeysecurity(key, sd);
784 /****************************************************************
785 ****************************************************************/
787 void dump_reg_val(int lvl, const char *direction,
788 const char *key, const char *subkey,
789 struct registry_value *val)
791 int i = 0;
792 const char *type_str = NULL;
794 if (!val) {
795 DEBUG(lvl,("no val!\n"));
796 return;
799 type_str = str_regtype(val->type);
801 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
802 direction, key, subkey, type_str));
804 switch (val->type) {
805 case REG_DWORD: {
806 uint32_t v;
807 if (val->data.length < 4) {
808 break;
810 v = IVAL(val->data.data, 0);
811 DEBUG(lvl,("%d (0x%08x)\n",
812 (int)v, v));
813 break;
815 case REG_QWORD: {
816 uint64_t v;
817 if (val->data.length < 8) {
818 break;
820 v = BVAL(val->data.data, 0);
821 DEBUG(lvl,("%d (0x%016llx)\n",
822 (int)v,
823 (unsigned long long)v));
824 break;
826 case REG_SZ: {
827 const char *s;
828 if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
829 break;
831 DEBUG(lvl,("%s (length: %d)\n",
832 s, (int)strlen_m(s)));
833 break;
835 case REG_MULTI_SZ: {
836 const char **a;
837 if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
838 break;
840 for (i=0; a[i] != NULL; i++) {
843 DEBUG(lvl,("(num_strings: %d)\n", i));
844 for (i=0; a[i] != NULL; i++) {
845 DEBUGADD(lvl,("\t%s\n", a[i]));
847 break;
849 case REG_NONE:
850 DEBUG(lvl,("\n"));
851 break;
852 case REG_BINARY:
853 dump_data(lvl, val->data.data,
854 val->data.length);
855 break;
856 default:
857 DEBUG(lvl,("unsupported type: %d\n", val->type));
858 break;
862 /****************************************************************
863 ****************************************************************/
865 void dump_reg_entry(uint32_t flags,
866 const char *dir,
867 struct gp_registry_entry *entry)
869 if (!(flags & GPO_INFO_FLAG_VERBOSE))
870 return;
872 dump_reg_val(1, dir,
873 entry->key,
874 entry->value,
875 entry->data);
878 /****************************************************************
879 ****************************************************************/
881 void dump_reg_entries(uint32_t flags,
882 const char *dir,
883 struct gp_registry_entry *entries,
884 size_t num_entries)
886 size_t i;
888 if (!(flags & GPO_INFO_FLAG_VERBOSE))
889 return;
891 for (i=0; i < num_entries; i++) {
892 dump_reg_entry(flags, dir, &entries[i]);
896 /****************************************************************
897 ****************************************************************/
899 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
900 struct gp_registry_entry *entry,
901 struct gp_registry_entry **entries,
902 size_t *num)
904 *entries = talloc_realloc(mem_ctx, *entries,
905 struct gp_registry_entry,
906 (*num)+1);
908 if (*entries == NULL) {
909 *num = 0;
910 return false;
913 (*entries)[*num].action = entry->action;
914 (*entries)[*num].key = entry->key;
915 (*entries)[*num].value = entry->value;
916 (*entries)[*num].data = entry->data;
918 *num += 1;
919 return true;
922 /****************************************************************
923 ****************************************************************/
925 static const char *gp_reg_action_str(enum gp_reg_action action)
927 switch (action) {
928 case GP_REG_ACTION_NONE:
929 return "GP_REG_ACTION_NONE";
930 case GP_REG_ACTION_ADD_VALUE:
931 return "GP_REG_ACTION_ADD_VALUE";
932 case GP_REG_ACTION_ADD_KEY:
933 return "GP_REG_ACTION_ADD_KEY";
934 case GP_REG_ACTION_DEL_VALUES:
935 return "GP_REG_ACTION_DEL_VALUES";
936 case GP_REG_ACTION_DEL_VALUE:
937 return "GP_REG_ACTION_DEL_VALUE";
938 case GP_REG_ACTION_DEL_ALL_VALUES:
939 return "GP_REG_ACTION_DEL_ALL_VALUES";
940 case GP_REG_ACTION_DEL_KEYS:
941 return "GP_REG_ACTION_DEL_KEYS";
942 case GP_REG_ACTION_SEC_KEY_SET:
943 return "GP_REG_ACTION_SEC_KEY_SET";
944 case GP_REG_ACTION_SEC_KEY_RESET:
945 return "GP_REG_ACTION_SEC_KEY_RESET";
946 default:
947 return "unknown";
951 /****************************************************************
952 ****************************************************************/
954 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
955 struct registry_key *root_key,
956 struct gp_registry_context *reg_ctx,
957 struct gp_registry_entry *entry,
958 const struct security_token *token,
959 uint32_t flags)
961 WERROR werr;
962 struct registry_key *key = NULL;
964 if (flags & GPO_INFO_FLAG_VERBOSE) {
965 printf("about to store key: [%s]\n", entry->key);
966 printf(" value: [%s]\n", entry->value);
967 printf(" data: [%s]\n", str_regtype(entry->data->type));
968 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
971 werr = gp_store_reg_subkey(mem_ctx, entry->key,
972 root_key, &key);
973 /* reg_ctx->curr_key, &key); */
974 if (!W_ERROR_IS_OK(werr)) {
975 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
976 return werr;
979 switch (entry->action) {
980 case GP_REG_ACTION_NONE:
981 case GP_REG_ACTION_ADD_KEY:
982 return WERR_OK;
984 case GP_REG_ACTION_SEC_KEY_SET:
985 werr = gp_secure_key(mem_ctx, flags,
986 key,
987 &token->sids[0]);
988 if (!W_ERROR_IS_OK(werr)) {
989 DEBUG(0,("reg_apply_registry_entry: "
990 "gp_secure_key failed: %s\n",
991 win_errstr(werr)));
992 return werr;
994 break;
995 case GP_REG_ACTION_ADD_VALUE:
996 werr = reg_setvalue(key, entry->value, entry->data);
997 if (!W_ERROR_IS_OK(werr)) {
998 DEBUG(0,("reg_apply_registry_entry: "
999 "reg_setvalue failed: %s\n",
1000 win_errstr(werr)));
1001 dump_reg_entry(flags, "STORE", entry);
1002 return werr;
1004 break;
1005 case GP_REG_ACTION_DEL_VALUE:
1006 werr = reg_deletevalue(key, entry->value);
1007 if (!W_ERROR_IS_OK(werr)) {
1008 DEBUG(0,("reg_apply_registry_entry: "
1009 "reg_deletevalue failed: %s\n",
1010 win_errstr(werr)));
1011 dump_reg_entry(flags, "STORE", entry);
1012 return werr;
1014 break;
1015 case GP_REG_ACTION_DEL_ALL_VALUES:
1016 werr = reg_deleteallvalues(key);
1017 if (!W_ERROR_IS_OK(werr)) {
1018 DEBUG(0,("reg_apply_registry_entry: "
1019 "reg_deleteallvalues failed: %s\n",
1020 win_errstr(werr)));
1021 dump_reg_entry(flags, "STORE", entry);
1022 return werr;
1024 break;
1025 case GP_REG_ACTION_DEL_VALUES:
1026 case GP_REG_ACTION_DEL_KEYS:
1027 case GP_REG_ACTION_SEC_KEY_RESET:
1028 DEBUG(0,("reg_apply_registry_entry: "
1029 "not yet supported: %s (%d)\n",
1030 gp_reg_action_str(entry->action),
1031 entry->action));
1032 return WERR_NOT_SUPPORTED;
1033 default:
1034 DEBUG(0,("invalid action: %d\n", entry->action));
1035 return WERR_INVALID_PARAM;
1038 return werr;