net_usershare: Use dom_sid_str_buf
[Samba.git] / libgpo / gpo_reg.c
blob644b4d36d6244ab4035e207033f27b613aa96753
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/security/dom_sid.h"
30 #include "../libcli/registry/util_reg.h"
33 /****************************************************************
34 ****************************************************************/
36 struct security_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
38 struct security_token *token = NULL;
40 token = talloc_zero(mem_ctx, struct security_token);
41 if (!token) {
42 DEBUG(1,("talloc failed\n"));
43 return NULL;
46 token->privilege_mask = SE_ALL_PRIVS;
48 if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
49 &token->sids, &token->num_sids))) {
50 DEBUG(1,("Error adding nt-authority system sid to token\n"));
51 return NULL;
54 return token;
57 /****************************************************************
58 ****************************************************************/
60 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
61 const char *initial_path,
62 uint32_t desired_access,
63 const struct security_token *token,
64 struct gp_registry_context **reg_ctx)
66 struct gp_registry_context *tmp_ctx;
67 WERROR werr;
69 if (!reg_ctx) {
70 return WERR_INVALID_PARAMETER;
73 werr = registry_init_basic();
74 if (!W_ERROR_IS_OK(werr)) {
75 return werr;
78 tmp_ctx = talloc_zero(mem_ctx, struct gp_registry_context);
79 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
81 if (token) {
82 tmp_ctx->token = token;
83 } else {
84 tmp_ctx->token = registry_create_system_token(mem_ctx);
86 if (!tmp_ctx->token) {
87 TALLOC_FREE(tmp_ctx);
88 return WERR_NOT_ENOUGH_MEMORY;
91 werr = regdb_open();
92 if (!W_ERROR_IS_OK(werr)) {
93 return werr;
96 if (initial_path) {
97 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
98 if (!tmp_ctx->path) {
99 TALLOC_FREE(tmp_ctx);
100 return WERR_NOT_ENOUGH_MEMORY;
103 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
104 tmp_ctx->token, &tmp_ctx->curr_key);
105 if (!W_ERROR_IS_OK(werr)) {
106 TALLOC_FREE(tmp_ctx);
107 return werr;
111 *reg_ctx = tmp_ctx;
113 return WERR_OK;
116 /****************************************************************
117 ****************************************************************/
119 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
121 TALLOC_FREE(reg_ctx);
124 /****************************************************************
125 ****************************************************************/
127 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
128 const char *subkeyname,
129 struct registry_key *curr_key,
130 struct registry_key **new_key)
132 enum winreg_CreateAction action = REG_ACTION_NONE;
133 WERROR werr;
135 werr = reg_createkey(mem_ctx, curr_key, subkeyname,
136 REG_KEY_WRITE, new_key, &action);
137 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
138 return WERR_OK;
141 return werr;
144 /****************************************************************
145 ****************************************************************/
147 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
148 struct gp_registry_context *reg_ctx,
149 const char *subkeyname,
150 struct registry_key **key)
152 const char *tmp = NULL;
154 if (!reg_ctx || !subkeyname || !key) {
155 return WERR_INVALID_PARAMETER;
158 tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
159 W_ERROR_HAVE_NO_MEMORY(tmp);
161 return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
162 reg_ctx->token, key);
165 /****************************************************************
166 ****************************************************************/
168 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
169 struct registry_key *key,
170 const char *val_name,
171 const char *val)
173 struct registry_value reg_val;
175 reg_val.type = REG_SZ;
176 if (!push_reg_sz(mem_ctx, &reg_val.data, val)) {
177 return WERR_NOT_ENOUGH_MEMORY;
180 return reg_setvalue(key, val_name, &reg_val);
183 /****************************************************************
184 ****************************************************************/
186 static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx,
187 struct registry_key *key,
188 const char *val_name,
189 uint32_t val)
191 struct registry_value reg_val;
193 reg_val.type = REG_DWORD;
194 reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
195 SIVAL(reg_val.data.data, 0, val);
197 return reg_setvalue(key, val_name, &reg_val);
200 /****************************************************************
201 ****************************************************************/
203 WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx,
204 struct registry_key *key,
205 const char *val_name,
206 const char **val)
208 WERROR werr;
209 struct registry_value *reg_val = NULL;
211 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
212 W_ERROR_NOT_OK_RETURN(werr);
214 if (reg_val->type != REG_SZ) {
215 return WERR_INVALID_DATATYPE;
218 if (!pull_reg_sz(mem_ctx, &reg_val->data, val)) {
219 return WERR_NOT_ENOUGH_MEMORY;
222 return WERR_OK;
225 /****************************************************************
226 ****************************************************************/
228 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
229 struct registry_key *key,
230 const char *val_name,
231 uint32_t *val)
233 WERROR werr;
234 struct registry_value *reg_val = NULL;
236 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
237 W_ERROR_NOT_OK_RETURN(werr);
239 if (reg_val->type != REG_DWORD) {
240 return WERR_INVALID_DATATYPE;
243 if (reg_val->data.length < 4) {
244 return WERR_INSUFFICIENT_BUFFER;
246 *val = IVAL(reg_val->data.data, 0);
248 return WERR_OK;
251 /****************************************************************
252 ****************************************************************/
254 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
255 struct registry_key *key,
256 struct GROUP_POLICY_OBJECT *gpo)
258 WERROR werr;
260 if (!key || !gpo) {
261 return WERR_INVALID_PARAMETER;
264 werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
265 gpo->version);
266 W_ERROR_NOT_OK_RETURN(werr);
268 werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
269 true); /* fake */
270 W_ERROR_NOT_OK_RETURN(werr);
272 werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
273 false); /* fake */
274 W_ERROR_NOT_OK_RETURN(werr);
276 werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
277 (gpo->options & GPO_FLAG_DISABLE));
278 W_ERROR_NOT_OK_RETURN(werr);
280 werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
281 gpo->options);
282 W_ERROR_NOT_OK_RETURN(werr);
284 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
285 gpo->name);
286 W_ERROR_NOT_OK_RETURN(werr);
288 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
289 gpo->link ? gpo->link : "");
290 W_ERROR_NOT_OK_RETURN(werr);
292 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
293 gpo->display_name);
294 W_ERROR_NOT_OK_RETURN(werr);
296 werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
297 "");
298 W_ERROR_NOT_OK_RETURN(werr);
300 return werr;
303 /****************************************************************
304 ****************************************************************/
306 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
307 const struct dom_sid *sid,
308 uint32_t flags)
310 struct dom_sid_buf sidbuf;
312 if (flags & GPO_LIST_FLAG_MACHINE) {
313 return "GroupMembership";
316 return talloc_asprintf(
317 mem_ctx,
318 "%s\\%s",
319 dom_sid_str_buf(sid, &sidbuf),
320 "GroupMembership");
323 /****************************************************************
324 ****************************************************************/
326 static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
327 struct registry_key *key,
328 const struct security_token *token,
329 uint32_t flags)
331 const char *path = NULL;
333 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
334 flags);
335 W_ERROR_HAVE_NO_MEMORY(path);
337 return reg_deletekey_recursive(key, path);
341 /****************************************************************
342 ****************************************************************/
344 static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
345 struct gp_registry_context *reg_ctx,
346 const struct security_token *token,
347 uint32_t flags)
349 struct registry_key *key = NULL;
350 WERROR werr;
351 uint32_t i = 0;
352 const char *valname = NULL;
353 const char *path = NULL;
354 const char *val = NULL;
355 int count = 0;
357 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[0],
358 flags);
359 W_ERROR_HAVE_NO_MEMORY(path);
361 gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
363 werr = gp_store_reg_subkey(mem_ctx, path,
364 reg_ctx->curr_key, &key);
365 W_ERROR_NOT_OK_RETURN(werr);
367 for (i=0; i<token->num_sids; i++) {
369 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
370 W_ERROR_HAVE_NO_MEMORY(valname);
372 val = sid_string_talloc(mem_ctx, &token->sids[i]);
373 W_ERROR_HAVE_NO_MEMORY(val);
374 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
375 W_ERROR_NOT_OK_RETURN(werr);
378 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
379 W_ERROR_NOT_OK_RETURN(werr);
381 return WERR_OK;
384 /****************************************************************
385 ****************************************************************/
386 #if 0
387 /* not used yet */
388 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
389 struct gp_registry_context *reg_ctx,
390 const struct dom_sid *object_sid,
391 struct security_token **token,
392 uint32_t flags)
394 struct registry_key *key = NULL;
395 WERROR werr;
396 int i = 0;
397 const char *valname = NULL;
398 const char *val = NULL;
399 const char *path = NULL;
400 uint32_t count = 0;
401 int num_token_sids = 0;
402 struct security_token *tmp_token = NULL;
404 tmp_token = talloc_zero(mem_ctx, struct security_token);
405 W_ERROR_HAVE_NO_MEMORY(tmp_token);
407 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
408 W_ERROR_HAVE_NO_MEMORY(path);
410 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
411 W_ERROR_NOT_OK_RETURN(werr);
413 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
414 W_ERROR_NOT_OK_RETURN(werr);
416 for (i=0; i<count; i++) {
418 valname = talloc_asprintf(mem_ctx, "Group%d", i);
419 W_ERROR_HAVE_NO_MEMORY(valname);
421 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
422 W_ERROR_NOT_OK_RETURN(werr);
424 if (!string_to_sid(&tmp_token->sids[num_token_sids++],
425 val)) {
426 return WERR_INSUFFICIENT_BUFFER;
430 tmp_token->num_sids = num_token_sids;
432 *token = tmp_token;
434 return WERR_OK;
436 #endif
437 /****************************************************************
438 ****************************************************************/
440 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
441 const struct dom_sid *sid,
442 uint32_t flags)
444 struct dom_sid_buf sidbuf;
446 if (flags & GPO_LIST_FLAG_MACHINE) {
447 return GPO_REG_STATE_MACHINE;
450 return talloc_asprintf(
451 mem_ctx,
452 "%s\\%s",
453 "State",
454 dom_sid_str_buf(sid, &sidbuf));
457 /****************************************************************
458 ****************************************************************/
460 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
461 struct registry_key *key,
462 const char *path)
464 return reg_deletesubkeys_recursive(key, path);
467 /****************************************************************
468 ****************************************************************/
470 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
471 uint32_t flags,
472 const char *dn,
473 const struct security_token *token,
474 struct GROUP_POLICY_OBJECT *gpo_list)
476 struct gp_registry_context *reg_ctx = NULL;
477 WERROR werr = WERR_GEN_FAILURE;
478 const char *subkeyname = NULL;
479 struct GROUP_POLICY_OBJECT *gpo;
480 int count = 0;
481 struct registry_key *key;
483 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
484 token, &reg_ctx);
485 W_ERROR_NOT_OK_RETURN(werr);
487 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
488 &token->sids[0]);
489 if (!W_ERROR_IS_OK(werr)) {
490 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
491 goto done;
494 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
495 if (!W_ERROR_IS_OK(werr)) {
496 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
497 goto done;
500 subkeyname = gp_req_state_path(mem_ctx, &token->sids[0], flags);
501 if (!subkeyname) {
502 werr = WERR_NOT_ENOUGH_MEMORY;
503 goto done;
506 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
507 if (!W_ERROR_IS_OK(werr)) {
508 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
509 /* goto done; */
512 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
513 reg_ctx->curr_key, &reg_ctx->curr_key);
514 if (!W_ERROR_IS_OK(werr)) {
515 goto done;
518 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
519 "Distinguished-Name", dn);
520 if (!W_ERROR_IS_OK(werr)) {
521 goto done;
524 /* store link list */
526 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
527 reg_ctx->curr_key, &key);
528 if (!W_ERROR_IS_OK(werr)) {
529 goto done;
532 /* store gpo list */
534 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
535 reg_ctx->curr_key, &reg_ctx->curr_key);
536 if (!W_ERROR_IS_OK(werr)) {
537 goto done;
540 for (gpo = gpo_list; gpo; gpo = gpo->next) {
542 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
543 if (!subkeyname) {
544 werr = WERR_NOT_ENOUGH_MEMORY;
545 goto done;
548 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
549 reg_ctx->curr_key, &key);
550 if (!W_ERROR_IS_OK(werr)) {
551 goto done;
554 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
555 if (!W_ERROR_IS_OK(werr)) {
556 DEBUG(0,("gp_reg_state_store: "
557 "gp_store_reg_gpovals failed for %s: %s\n",
558 gpo->display_name, win_errstr(werr)));
559 goto done;
562 done:
563 gp_free_reg_ctx(reg_ctx);
564 return werr;
567 /****************************************************************
568 ****************************************************************/
570 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
571 struct registry_key *key,
572 struct GROUP_POLICY_OBJECT *gpo)
574 WERROR werr;
576 if (!key || !gpo) {
577 return WERR_INVALID_PARAMETER;
580 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
581 &gpo->version);
582 W_ERROR_NOT_OK_RETURN(werr);
584 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
585 &gpo->options);
586 W_ERROR_NOT_OK_RETURN(werr);
588 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
589 &gpo->name);
590 W_ERROR_NOT_OK_RETURN(werr);
592 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
593 &gpo->link);
594 W_ERROR_NOT_OK_RETURN(werr);
596 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
597 &gpo->display_name);
598 W_ERROR_NOT_OK_RETURN(werr);
600 return werr;
603 /****************************************************************
604 ****************************************************************/
606 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
607 struct registry_key *key,
608 struct GROUP_POLICY_OBJECT **gpo_ret)
610 struct GROUP_POLICY_OBJECT *gpo = NULL;
611 WERROR werr;
613 if (!gpo_ret || !key) {
614 return WERR_INVALID_PARAMETER;
617 gpo = talloc_zero(mem_ctx, struct GROUP_POLICY_OBJECT);
618 W_ERROR_HAVE_NO_MEMORY(gpo);
620 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
621 W_ERROR_NOT_OK_RETURN(werr);
623 *gpo_ret = gpo;
625 return werr;
628 /****************************************************************
629 ****************************************************************/
631 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
632 uint32_t flags,
633 const struct dom_sid *sid,
634 struct GROUP_POLICY_OBJECT **gpo_list)
636 struct gp_registry_context *reg_ctx = NULL;
637 WERROR werr = WERR_GEN_FAILURE;
638 const char *subkeyname = NULL;
639 struct GROUP_POLICY_OBJECT *gpo = NULL;
640 int count = 0;
641 struct registry_key *key = NULL;
642 const char *path = NULL;
643 const char *gp_state_path = NULL;
645 if (!gpo_list) {
646 return WERR_INVALID_PARAMETER;
649 ZERO_STRUCTP(gpo_list);
651 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
652 if (!gp_state_path) {
653 werr = WERR_NOT_ENOUGH_MEMORY;
654 goto done;
657 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
658 KEY_GROUP_POLICY,
659 gp_state_path,
660 "GPO-List");
661 if (!path) {
662 werr = WERR_NOT_ENOUGH_MEMORY;
663 goto done;
666 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
667 if (!W_ERROR_IS_OK(werr)) {
668 goto done;
671 while (1) {
673 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
674 if (!subkeyname) {
675 werr = WERR_NOT_ENOUGH_MEMORY;
676 goto done;
679 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
680 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
681 werr = WERR_OK;
682 break;
684 if (!W_ERROR_IS_OK(werr)) {
685 DEBUG(0,("gp_reg_state_read: "
686 "gp_read_reg_subkey gave: %s\n",
687 win_errstr(werr)));
688 goto done;
691 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
692 if (!W_ERROR_IS_OK(werr)) {
693 goto done;
696 DLIST_ADD(*gpo_list, gpo);
699 done:
700 gp_free_reg_ctx(reg_ctx);
701 return werr;
704 /****************************************************************
705 ****************************************************************/
707 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
708 const struct dom_sid *sid,
709 struct security_descriptor **sd,
710 size_t *sd_size)
712 struct security_ace ace[6];
713 uint32_t mask;
715 struct security_acl *theacl = NULL;
717 uint8_t inherit_flags;
719 mask = REG_KEY_ALL;
720 init_sec_ace(&ace[0],
721 &global_sid_System,
722 SEC_ACE_TYPE_ACCESS_ALLOWED,
723 mask, 0);
725 mask = REG_KEY_ALL;
726 init_sec_ace(&ace[1],
727 &global_sid_Builtin_Administrators,
728 SEC_ACE_TYPE_ACCESS_ALLOWED,
729 mask, 0);
731 mask = REG_KEY_READ;
732 init_sec_ace(&ace[2],
733 sid ? sid : &global_sid_Authenticated_Users,
734 SEC_ACE_TYPE_ACCESS_ALLOWED,
735 mask, 0);
737 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
738 SEC_ACE_FLAG_CONTAINER_INHERIT |
739 SEC_ACE_FLAG_INHERIT_ONLY;
741 mask = REG_KEY_ALL;
742 init_sec_ace(&ace[3],
743 &global_sid_System,
744 SEC_ACE_TYPE_ACCESS_ALLOWED,
745 mask, inherit_flags);
747 mask = REG_KEY_ALL;
748 init_sec_ace(&ace[4],
749 &global_sid_Builtin_Administrators,
750 SEC_ACE_TYPE_ACCESS_ALLOWED,
751 mask, inherit_flags);
753 mask = REG_KEY_READ;
754 init_sec_ace(&ace[5],
755 sid ? sid : &global_sid_Authenticated_Users,
756 SEC_ACE_TYPE_ACCESS_ALLOWED,
757 mask, inherit_flags);
759 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
760 W_ERROR_HAVE_NO_MEMORY(theacl);
762 *sd = make_sec_desc(mem_ctx, SD_REVISION,
763 SEC_DESC_SELF_RELATIVE |
764 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
765 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
766 NULL, NULL, NULL,
767 theacl, sd_size);
768 W_ERROR_HAVE_NO_MEMORY(*sd);
770 return WERR_OK;
773 /****************************************************************
774 ****************************************************************/
776 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
777 uint32_t flags,
778 struct registry_key *key,
779 const struct dom_sid *sid)
781 struct security_descriptor *sd = NULL;
782 size_t sd_size = 0;
783 const struct dom_sid *sd_sid = NULL;
784 WERROR werr;
786 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
787 sd_sid = sid;
790 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
791 W_ERROR_NOT_OK_RETURN(werr);
793 return reg_setkeysecurity(key, sd);
796 /****************************************************************
797 ****************************************************************/
799 void dump_reg_val(int lvl, const char *direction,
800 const char *key, const char *subkey,
801 struct registry_value *val)
803 int i = 0;
804 const char *type_str = NULL;
806 if (!val) {
807 DEBUG(lvl,("no val!\n"));
808 return;
811 type_str = str_regtype(val->type);
813 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
814 direction, key, subkey, type_str));
816 switch (val->type) {
817 case REG_DWORD: {
818 uint32_t v;
819 if (val->data.length < 4) {
820 break;
822 v = IVAL(val->data.data, 0);
823 DEBUG(lvl,("%d (0x%08x)\n",
824 (int)v, v));
825 break;
827 case REG_QWORD: {
828 uint64_t v;
829 if (val->data.length < 8) {
830 break;
832 v = BVAL(val->data.data, 0);
833 DEBUG(lvl,("%d (0x%016llx)\n",
834 (int)v,
835 (unsigned long long)v));
836 break;
838 case REG_SZ: {
839 const char *s;
840 if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
841 break;
843 DEBUG(lvl,("%s (length: %d)\n",
844 s, (int)strlen_m(s)));
845 break;
847 case REG_MULTI_SZ: {
848 const char **a;
849 if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
850 break;
852 for (i=0; a[i] != NULL; i++) {
855 DEBUG(lvl,("(num_strings: %d)\n", i));
856 for (i=0; a[i] != NULL; i++) {
857 DEBUGADD(lvl,("\t%s\n", a[i]));
859 break;
861 case REG_NONE:
862 DEBUG(lvl,("\n"));
863 break;
864 case REG_BINARY:
865 dump_data(lvl, val->data.data,
866 val->data.length);
867 break;
868 default:
869 DEBUG(lvl,("unsupported type: %d\n", val->type));
870 break;
874 /****************************************************************
875 ****************************************************************/
877 void dump_reg_entry(uint32_t flags,
878 const char *dir,
879 struct gp_registry_entry *entry)
881 if (!(flags & GPO_INFO_FLAG_VERBOSE))
882 return;
884 dump_reg_val(1, dir,
885 entry->key,
886 entry->value,
887 entry->data);
890 /****************************************************************
891 ****************************************************************/
893 void dump_reg_entries(uint32_t flags,
894 const char *dir,
895 struct gp_registry_entry *entries,
896 size_t num_entries)
898 size_t i;
900 if (!(flags & GPO_INFO_FLAG_VERBOSE))
901 return;
903 for (i=0; i < num_entries; i++) {
904 dump_reg_entry(flags, dir, &entries[i]);
908 /****************************************************************
909 ****************************************************************/
911 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
912 struct gp_registry_entry *entry,
913 struct gp_registry_entry **entries,
914 size_t *num)
916 *entries = talloc_realloc(mem_ctx, *entries,
917 struct gp_registry_entry,
918 (*num)+1);
920 if (*entries == NULL) {
921 *num = 0;
922 return false;
925 (*entries)[*num].action = entry->action;
926 (*entries)[*num].key = entry->key;
927 (*entries)[*num].value = entry->value;
928 (*entries)[*num].data = entry->data;
930 *num += 1;
931 return true;
934 /****************************************************************
935 ****************************************************************/
937 static const char *gp_reg_action_str(enum gp_reg_action action)
939 switch (action) {
940 case GP_REG_ACTION_NONE:
941 return "GP_REG_ACTION_NONE";
942 case GP_REG_ACTION_ADD_VALUE:
943 return "GP_REG_ACTION_ADD_VALUE";
944 case GP_REG_ACTION_ADD_KEY:
945 return "GP_REG_ACTION_ADD_KEY";
946 case GP_REG_ACTION_DEL_VALUES:
947 return "GP_REG_ACTION_DEL_VALUES";
948 case GP_REG_ACTION_DEL_VALUE:
949 return "GP_REG_ACTION_DEL_VALUE";
950 case GP_REG_ACTION_DEL_ALL_VALUES:
951 return "GP_REG_ACTION_DEL_ALL_VALUES";
952 case GP_REG_ACTION_DEL_KEYS:
953 return "GP_REG_ACTION_DEL_KEYS";
954 case GP_REG_ACTION_SEC_KEY_SET:
955 return "GP_REG_ACTION_SEC_KEY_SET";
956 case GP_REG_ACTION_SEC_KEY_RESET:
957 return "GP_REG_ACTION_SEC_KEY_RESET";
958 default:
959 return "unknown";
963 /****************************************************************
964 ****************************************************************/
966 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
967 struct registry_key *root_key,
968 struct gp_registry_context *reg_ctx,
969 struct gp_registry_entry *entry,
970 const struct security_token *token,
971 uint32_t flags)
973 WERROR werr;
974 struct registry_key *key = NULL;
976 if (flags & GPO_INFO_FLAG_VERBOSE) {
977 printf("about to store key: [%s]\n", entry->key);
978 printf(" value: [%s]\n", entry->value);
979 printf(" data: [%s]\n", str_regtype(entry->data->type));
980 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
983 werr = gp_store_reg_subkey(mem_ctx, entry->key,
984 root_key, &key);
985 /* reg_ctx->curr_key, &key); */
986 if (!W_ERROR_IS_OK(werr)) {
987 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
988 return werr;
991 switch (entry->action) {
992 case GP_REG_ACTION_NONE:
993 case GP_REG_ACTION_ADD_KEY:
994 return WERR_OK;
996 case GP_REG_ACTION_SEC_KEY_SET:
997 werr = gp_secure_key(mem_ctx, flags,
998 key,
999 &token->sids[0]);
1000 if (!W_ERROR_IS_OK(werr)) {
1001 DEBUG(0,("reg_apply_registry_entry: "
1002 "gp_secure_key failed: %s\n",
1003 win_errstr(werr)));
1004 return werr;
1006 break;
1007 case GP_REG_ACTION_ADD_VALUE:
1008 werr = reg_setvalue(key, entry->value, entry->data);
1009 if (!W_ERROR_IS_OK(werr)) {
1010 DEBUG(0,("reg_apply_registry_entry: "
1011 "reg_setvalue failed: %s\n",
1012 win_errstr(werr)));
1013 dump_reg_entry(flags, "STORE", entry);
1014 return werr;
1016 break;
1017 case GP_REG_ACTION_DEL_VALUE:
1018 werr = reg_deletevalue(key, entry->value);
1019 if (!W_ERROR_IS_OK(werr)) {
1020 DEBUG(0,("reg_apply_registry_entry: "
1021 "reg_deletevalue failed: %s\n",
1022 win_errstr(werr)));
1023 dump_reg_entry(flags, "STORE", entry);
1024 return werr;
1026 break;
1027 case GP_REG_ACTION_DEL_ALL_VALUES:
1028 werr = reg_deleteallvalues(key);
1029 if (!W_ERROR_IS_OK(werr)) {
1030 DEBUG(0,("reg_apply_registry_entry: "
1031 "reg_deleteallvalues failed: %s\n",
1032 win_errstr(werr)));
1033 dump_reg_entry(flags, "STORE", entry);
1034 return werr;
1036 break;
1037 case GP_REG_ACTION_DEL_VALUES:
1038 case GP_REG_ACTION_DEL_KEYS:
1039 case GP_REG_ACTION_SEC_KEY_RESET:
1040 DEBUG(0,("reg_apply_registry_entry: "
1041 "not yet supported: %s (%d)\n",
1042 gp_reg_action_str(entry->action),
1043 entry->action));
1044 return WERR_NOT_SUPPORTED;
1045 default:
1046 DEBUG(0,("invalid action: %d\n", entry->action));
1047 return WERR_INVALID_PARAMETER;
1050 return werr;