docs-xml: add details for 'net witness'
[Samba.git] / libgpo / gpo_reg.c
bloba1a8d7d1a07dc006af7175f9a54e14e6db3d1ebc
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 const struct security_token *system_token = get_system_token();
40 struct security_token *dup_token
41 = security_token_duplicate(mem_ctx, system_token);
43 if (dup_token == NULL) {
44 DBG_WARNING("security_token_duplicate() failed\n");
45 return NULL;
48 return dup_token;
51 /****************************************************************
52 ****************************************************************/
54 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
55 const char *initial_path,
56 uint32_t desired_access,
57 const struct security_token *token,
58 struct gp_registry_context **reg_ctx)
60 struct gp_registry_context *tmp_ctx;
61 WERROR werr;
63 if (!reg_ctx) {
64 return WERR_INVALID_PARAMETER;
67 werr = registry_init_basic();
68 if (!W_ERROR_IS_OK(werr)) {
69 return werr;
72 tmp_ctx = talloc_zero(mem_ctx, struct gp_registry_context);
73 W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
75 if (token) {
76 tmp_ctx->token = token;
77 } else {
78 tmp_ctx->token = registry_create_system_token(mem_ctx);
80 if (!tmp_ctx->token) {
81 TALLOC_FREE(tmp_ctx);
82 return WERR_NOT_ENOUGH_MEMORY;
85 werr = regdb_open();
86 if (!W_ERROR_IS_OK(werr)) {
87 return werr;
90 if (initial_path) {
91 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
92 if (!tmp_ctx->path) {
93 TALLOC_FREE(tmp_ctx);
94 return WERR_NOT_ENOUGH_MEMORY;
97 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
98 tmp_ctx->token, &tmp_ctx->curr_key);
99 if (!W_ERROR_IS_OK(werr)) {
100 TALLOC_FREE(tmp_ctx);
101 return werr;
105 *reg_ctx = tmp_ctx;
107 return WERR_OK;
110 /****************************************************************
111 ****************************************************************/
113 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
115 TALLOC_FREE(reg_ctx);
118 /****************************************************************
119 ****************************************************************/
121 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
122 const char *subkeyname,
123 struct registry_key *curr_key,
124 struct registry_key **new_key)
126 enum winreg_CreateAction action = REG_ACTION_NONE;
127 WERROR werr;
129 werr = reg_createkey(mem_ctx, curr_key, subkeyname,
130 REG_KEY_WRITE, new_key, &action);
131 if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
132 return WERR_OK;
135 return werr;
138 /****************************************************************
139 ****************************************************************/
141 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
142 struct gp_registry_context *reg_ctx,
143 const char *subkeyname,
144 struct registry_key **key)
146 const char *tmp = NULL;
148 if (!reg_ctx || !subkeyname || !key) {
149 return WERR_INVALID_PARAMETER;
152 tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
153 W_ERROR_HAVE_NO_MEMORY(tmp);
155 return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
156 reg_ctx->token, key);
159 /****************************************************************
160 ****************************************************************/
162 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
163 struct registry_key *key,
164 const char *val_name,
165 const char *val)
167 struct registry_value reg_val;
169 reg_val.type = REG_SZ;
170 if (!push_reg_sz(mem_ctx, &reg_val.data, val)) {
171 return WERR_NOT_ENOUGH_MEMORY;
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;
187 reg_val.type = REG_DWORD;
188 reg_val.data = data_blob_talloc(mem_ctx, NULL, 4);
189 SIVAL(reg_val.data.data, 0, 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 if (!pull_reg_sz(mem_ctx, &reg_val->data, val)) {
213 return WERR_NOT_ENOUGH_MEMORY;
216 return WERR_OK;
219 /****************************************************************
220 ****************************************************************/
222 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
223 struct registry_key *key,
224 const char *val_name,
225 uint32_t *val)
227 WERROR werr;
228 struct registry_value *reg_val = NULL;
230 werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
231 W_ERROR_NOT_OK_RETURN(werr);
233 if (reg_val->type != REG_DWORD) {
234 return WERR_INVALID_DATATYPE;
237 if (reg_val->data.length < 4) {
238 return WERR_INSUFFICIENT_BUFFER;
240 *val = IVAL(reg_val->data.data, 0);
242 return WERR_OK;
245 /****************************************************************
246 ****************************************************************/
248 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
249 struct registry_key *key,
250 struct GROUP_POLICY_OBJECT *gpo)
252 WERROR werr;
254 if (!key || !gpo) {
255 return WERR_INVALID_PARAMETER;
258 werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
259 gpo->version);
260 W_ERROR_NOT_OK_RETURN(werr);
262 werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
263 true); /* fake */
264 W_ERROR_NOT_OK_RETURN(werr);
266 werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
267 false); /* fake */
268 W_ERROR_NOT_OK_RETURN(werr);
270 werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
271 (gpo->options & GPO_FLAG_DISABLE));
272 W_ERROR_NOT_OK_RETURN(werr);
274 werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
275 gpo->options);
276 W_ERROR_NOT_OK_RETURN(werr);
278 werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
279 gpo->name);
280 W_ERROR_NOT_OK_RETURN(werr);
282 werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
283 gpo->link ? gpo->link : "");
284 W_ERROR_NOT_OK_RETURN(werr);
286 werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
287 gpo->display_name);
288 W_ERROR_NOT_OK_RETURN(werr);
290 werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
291 "");
292 W_ERROR_NOT_OK_RETURN(werr);
294 return werr;
297 /****************************************************************
298 ****************************************************************/
300 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
301 const struct dom_sid *sid,
302 uint32_t flags)
304 struct dom_sid_buf sidbuf;
306 if (flags & GPO_LIST_FLAG_MACHINE) {
307 return "GroupMembership";
310 return talloc_asprintf(
311 mem_ctx,
312 "%s\\%s",
313 dom_sid_str_buf(sid, &sidbuf),
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[PRIMARY_USER_SID_INDEX],
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 uint32_t i = 0;
346 const char *valname = NULL;
347 const char *path = NULL;
348 int count = 0;
350 path = gp_reg_groupmembership_path(mem_ctx, &token->sids[PRIMARY_USER_SID_INDEX],
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++) {
361 struct dom_sid_buf buf;
363 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
364 W_ERROR_HAVE_NO_MEMORY(valname);
366 werr = gp_store_reg_val_sz(
367 mem_ctx,
368 key,
369 valname,
370 dom_sid_str_buf(&token->sids[i], &buf));
371 W_ERROR_NOT_OK_RETURN(werr);
374 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
375 W_ERROR_NOT_OK_RETURN(werr);
377 return WERR_OK;
380 /****************************************************************
381 ****************************************************************/
382 #if 0
383 /* not used yet */
384 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
385 struct gp_registry_context *reg_ctx,
386 const struct dom_sid *object_sid,
387 struct security_token **token,
388 uint32_t flags)
390 struct registry_key *key = NULL;
391 WERROR werr;
392 int i = 0;
393 const char *valname = NULL;
394 const char *val = NULL;
395 const char *path = NULL;
396 uint32_t count = 0;
397 int num_token_sids = 0;
398 struct security_token *tmp_token = NULL;
400 tmp_token = talloc_zero(mem_ctx, struct security_token);
401 W_ERROR_HAVE_NO_MEMORY(tmp_token);
403 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
404 W_ERROR_HAVE_NO_MEMORY(path);
406 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
407 W_ERROR_NOT_OK_RETURN(werr);
409 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
410 W_ERROR_NOT_OK_RETURN(werr);
412 for (i=0; i<count; i++) {
414 valname = talloc_asprintf(mem_ctx, "Group%d", i);
415 W_ERROR_HAVE_NO_MEMORY(valname);
417 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
418 W_ERROR_NOT_OK_RETURN(werr);
420 if (!string_to_sid(&tmp_token->sids[num_token_sids++],
421 val)) {
422 return WERR_INSUFFICIENT_BUFFER;
426 tmp_token->num_sids = num_token_sids;
428 *token = tmp_token;
430 return WERR_OK;
432 #endif
433 /****************************************************************
434 ****************************************************************/
436 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
437 const struct dom_sid *sid,
438 uint32_t flags)
440 struct dom_sid_buf sidbuf;
442 if (flags & GPO_LIST_FLAG_MACHINE) {
443 return GPO_REG_STATE_MACHINE;
446 return talloc_asprintf(
447 mem_ctx,
448 "%s\\%s",
449 "State",
450 dom_sid_str_buf(sid, &sidbuf));
453 /****************************************************************
454 ****************************************************************/
456 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
457 struct registry_key *key,
458 const char *path)
460 return reg_deletesubkeys_recursive(key, path);
463 /****************************************************************
464 ****************************************************************/
466 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
467 uint32_t flags,
468 const char *dn,
469 const struct security_token *token,
470 struct GROUP_POLICY_OBJECT *gpo_list)
472 struct gp_registry_context *reg_ctx = NULL;
473 WERROR werr = WERR_GEN_FAILURE;
474 const char *subkeyname = NULL;
475 struct GROUP_POLICY_OBJECT *gpo;
476 int count = 0;
477 struct registry_key *key;
479 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
480 token, &reg_ctx);
481 W_ERROR_NOT_OK_RETURN(werr);
483 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
484 &token->sids[PRIMARY_USER_SID_INDEX]);
485 if (!W_ERROR_IS_OK(werr)) {
486 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
487 goto done;
490 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
491 if (!W_ERROR_IS_OK(werr)) {
492 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
493 goto done;
496 subkeyname = gp_req_state_path(mem_ctx, &token->sids[PRIMARY_USER_SID_INDEX], flags);
497 if (!subkeyname) {
498 werr = WERR_NOT_ENOUGH_MEMORY;
499 goto done;
502 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
503 if (!W_ERROR_IS_OK(werr)) {
504 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
505 /* goto done; */
508 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
509 reg_ctx->curr_key, &reg_ctx->curr_key);
510 if (!W_ERROR_IS_OK(werr)) {
511 goto done;
514 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
515 "Distinguished-Name", dn);
516 if (!W_ERROR_IS_OK(werr)) {
517 goto done;
520 /* store link list */
522 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
523 reg_ctx->curr_key, &key);
524 if (!W_ERROR_IS_OK(werr)) {
525 goto done;
528 /* store gpo list */
530 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
531 reg_ctx->curr_key, &reg_ctx->curr_key);
532 if (!W_ERROR_IS_OK(werr)) {
533 goto done;
536 for (gpo = gpo_list; gpo; gpo = gpo->next) {
538 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
539 if (!subkeyname) {
540 werr = WERR_NOT_ENOUGH_MEMORY;
541 goto done;
544 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
545 reg_ctx->curr_key, &key);
546 if (!W_ERROR_IS_OK(werr)) {
547 goto done;
550 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
551 if (!W_ERROR_IS_OK(werr)) {
552 DEBUG(0,("gp_reg_state_store: "
553 "gp_store_reg_gpovals failed for %s: %s\n",
554 gpo->display_name, win_errstr(werr)));
555 goto done;
558 done:
559 gp_free_reg_ctx(reg_ctx);
560 return werr;
563 /****************************************************************
564 ****************************************************************/
566 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
567 struct registry_key *key,
568 struct GROUP_POLICY_OBJECT *gpo)
570 WERROR werr;
572 if (!key || !gpo) {
573 return WERR_INVALID_PARAMETER;
576 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
577 &gpo->version);
578 W_ERROR_NOT_OK_RETURN(werr);
580 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
581 &gpo->options);
582 W_ERROR_NOT_OK_RETURN(werr);
584 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
585 &gpo->name);
586 W_ERROR_NOT_OK_RETURN(werr);
588 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
589 &gpo->link);
590 W_ERROR_NOT_OK_RETURN(werr);
592 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
593 &gpo->display_name);
594 W_ERROR_NOT_OK_RETURN(werr);
596 return werr;
599 /****************************************************************
600 ****************************************************************/
602 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
603 struct registry_key *key,
604 struct GROUP_POLICY_OBJECT **gpo_ret)
606 struct GROUP_POLICY_OBJECT *gpo = NULL;
607 WERROR werr;
609 if (!gpo_ret || !key) {
610 return WERR_INVALID_PARAMETER;
613 gpo = talloc_zero(mem_ctx, struct GROUP_POLICY_OBJECT);
614 W_ERROR_HAVE_NO_MEMORY(gpo);
616 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
617 W_ERROR_NOT_OK_RETURN(werr);
619 *gpo_ret = gpo;
621 return werr;
624 /****************************************************************
625 ****************************************************************/
627 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
628 uint32_t flags,
629 const struct dom_sid *sid,
630 struct GROUP_POLICY_OBJECT **gpo_list)
632 struct gp_registry_context *reg_ctx = NULL;
633 WERROR werr = WERR_GEN_FAILURE;
634 const char *subkeyname = NULL;
635 struct GROUP_POLICY_OBJECT *gpo = NULL;
636 int count = 0;
637 struct registry_key *key = NULL;
638 const char *path = NULL;
639 const char *gp_state_path = NULL;
641 if (!gpo_list) {
642 return WERR_INVALID_PARAMETER;
645 ZERO_STRUCTP(gpo_list);
647 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
648 if (!gp_state_path) {
649 werr = WERR_NOT_ENOUGH_MEMORY;
650 goto done;
653 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
654 KEY_GROUP_POLICY,
655 gp_state_path,
656 "GPO-List");
657 if (!path) {
658 werr = WERR_NOT_ENOUGH_MEMORY;
659 goto done;
662 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
663 if (!W_ERROR_IS_OK(werr)) {
664 goto done;
667 while (1) {
669 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
670 if (!subkeyname) {
671 werr = WERR_NOT_ENOUGH_MEMORY;
672 goto done;
675 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
676 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
677 werr = WERR_OK;
678 break;
680 if (!W_ERROR_IS_OK(werr)) {
681 DEBUG(0,("gp_reg_state_read: "
682 "gp_read_reg_subkey gave: %s\n",
683 win_errstr(werr)));
684 goto done;
687 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
688 if (!W_ERROR_IS_OK(werr)) {
689 goto done;
692 DLIST_ADD(*gpo_list, gpo);
695 done:
696 gp_free_reg_ctx(reg_ctx);
697 return werr;
700 /****************************************************************
701 ****************************************************************/
703 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
704 const struct dom_sid *sid,
705 struct security_descriptor **sd,
706 size_t *sd_size)
708 struct security_ace ace[6];
709 uint32_t mask;
711 struct security_acl *theacl = NULL;
713 uint8_t inherit_flags;
715 mask = REG_KEY_ALL;
716 init_sec_ace(&ace[0],
717 &global_sid_System,
718 SEC_ACE_TYPE_ACCESS_ALLOWED,
719 mask, 0);
721 mask = REG_KEY_ALL;
722 init_sec_ace(&ace[1],
723 &global_sid_Builtin_Administrators,
724 SEC_ACE_TYPE_ACCESS_ALLOWED,
725 mask, 0);
727 mask = REG_KEY_READ;
728 init_sec_ace(&ace[2],
729 sid ? sid : &global_sid_Authenticated_Users,
730 SEC_ACE_TYPE_ACCESS_ALLOWED,
731 mask, 0);
733 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
734 SEC_ACE_FLAG_CONTAINER_INHERIT |
735 SEC_ACE_FLAG_INHERIT_ONLY;
737 mask = REG_KEY_ALL;
738 init_sec_ace(&ace[3],
739 &global_sid_System,
740 SEC_ACE_TYPE_ACCESS_ALLOWED,
741 mask, inherit_flags);
743 mask = REG_KEY_ALL;
744 init_sec_ace(&ace[4],
745 &global_sid_Builtin_Administrators,
746 SEC_ACE_TYPE_ACCESS_ALLOWED,
747 mask, inherit_flags);
749 mask = REG_KEY_READ;
750 init_sec_ace(&ace[5],
751 sid ? sid : &global_sid_Authenticated_Users,
752 SEC_ACE_TYPE_ACCESS_ALLOWED,
753 mask, inherit_flags);
755 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
756 W_ERROR_HAVE_NO_MEMORY(theacl);
758 *sd = make_sec_desc(mem_ctx, SD_REVISION,
759 SEC_DESC_SELF_RELATIVE |
760 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
761 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
762 NULL, NULL, NULL,
763 theacl, sd_size);
764 W_ERROR_HAVE_NO_MEMORY(*sd);
766 return WERR_OK;
769 /****************************************************************
770 ****************************************************************/
772 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
773 uint32_t flags,
774 struct registry_key *key,
775 const struct dom_sid *sid)
777 struct security_descriptor *sd = NULL;
778 size_t sd_size = 0;
779 const struct dom_sid *sd_sid = NULL;
780 WERROR werr;
782 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
783 sd_sid = sid;
786 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
787 W_ERROR_NOT_OK_RETURN(werr);
789 return reg_setkeysecurity(key, sd);
792 /****************************************************************
793 ****************************************************************/
795 void dump_reg_val(int lvl, const char *direction,
796 const char *key, const char *subkey,
797 struct registry_value *val)
799 int i = 0;
800 const char *type_str = NULL;
802 if (!val) {
803 DEBUG(lvl,("no val!\n"));
804 return;
807 type_str = str_regtype(val->type);
809 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
810 direction, key, subkey, type_str));
812 switch (val->type) {
813 case REG_DWORD: {
814 uint32_t v;
815 if (val->data.length < 4) {
816 break;
818 v = IVAL(val->data.data, 0);
819 DEBUG(lvl,("%d (0x%08x)\n",
820 (int)v, v));
821 break;
823 case REG_QWORD: {
824 uint64_t v;
825 if (val->data.length < 8) {
826 break;
828 v = BVAL(val->data.data, 0);
829 DEBUG(lvl,("%d (0x%016llx)\n",
830 (int)v,
831 (unsigned long long)v));
832 break;
834 case REG_SZ: {
835 const char *s;
836 if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
837 break;
839 DEBUG(lvl,("%s (length: %d)\n",
840 s, (int)strlen_m(s)));
841 break;
843 case REG_MULTI_SZ: {
844 const char **a;
845 if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
846 break;
848 for (i=0; a[i] != NULL; i++) {
851 DEBUG(lvl,("(num_strings: %d)\n", i));
852 for (i=0; a[i] != NULL; i++) {
853 DEBUGADD(lvl,("\t%s\n", a[i]));
855 break;
857 case REG_NONE:
858 DEBUG(lvl,("\n"));
859 break;
860 case REG_BINARY:
861 dump_data(lvl, val->data.data,
862 val->data.length);
863 break;
864 default:
865 DEBUG(lvl,("unsupported type: %d\n", val->type));
866 break;
870 /****************************************************************
871 ****************************************************************/
873 void dump_reg_entry(uint32_t flags,
874 const char *dir,
875 struct gp_registry_entry *entry)
877 if (!(flags & GPO_INFO_FLAG_VERBOSE))
878 return;
880 dump_reg_val(1, dir,
881 entry->key,
882 entry->value,
883 entry->data);
886 /****************************************************************
887 ****************************************************************/
889 void dump_reg_entries(uint32_t flags,
890 const char *dir,
891 struct gp_registry_entry *entries,
892 size_t num_entries)
894 size_t i;
896 if (!(flags & GPO_INFO_FLAG_VERBOSE))
897 return;
899 for (i=0; i < num_entries; i++) {
900 dump_reg_entry(flags, dir, &entries[i]);
904 /****************************************************************
905 ****************************************************************/
907 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
908 struct gp_registry_entry *entry,
909 struct gp_registry_entry **entries,
910 size_t *num)
912 *entries = talloc_realloc(mem_ctx, *entries,
913 struct gp_registry_entry,
914 (*num)+1);
916 if (*entries == NULL) {
917 *num = 0;
918 return false;
921 (*entries)[*num].action = entry->action;
922 (*entries)[*num].key = entry->key;
923 (*entries)[*num].value = entry->value;
924 (*entries)[*num].data = entry->data;
926 *num += 1;
927 return true;
930 /****************************************************************
931 ****************************************************************/
933 static const char *gp_reg_action_str(enum gp_reg_action action)
935 switch (action) {
936 case GP_REG_ACTION_NONE:
937 return "GP_REG_ACTION_NONE";
938 case GP_REG_ACTION_ADD_VALUE:
939 return "GP_REG_ACTION_ADD_VALUE";
940 case GP_REG_ACTION_ADD_KEY:
941 return "GP_REG_ACTION_ADD_KEY";
942 case GP_REG_ACTION_DEL_VALUES:
943 return "GP_REG_ACTION_DEL_VALUES";
944 case GP_REG_ACTION_DEL_VALUE:
945 return "GP_REG_ACTION_DEL_VALUE";
946 case GP_REG_ACTION_DEL_ALL_VALUES:
947 return "GP_REG_ACTION_DEL_ALL_VALUES";
948 case GP_REG_ACTION_DEL_KEYS:
949 return "GP_REG_ACTION_DEL_KEYS";
950 case GP_REG_ACTION_SEC_KEY_SET:
951 return "GP_REG_ACTION_SEC_KEY_SET";
952 case GP_REG_ACTION_SEC_KEY_RESET:
953 return "GP_REG_ACTION_SEC_KEY_RESET";
954 default:
955 return "unknown";
959 /****************************************************************
960 ****************************************************************/
962 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
963 struct registry_key *root_key,
964 struct gp_registry_context *reg_ctx,
965 struct gp_registry_entry *entry,
966 const struct security_token *token,
967 uint32_t flags)
969 WERROR werr;
970 struct registry_key *key = NULL;
972 if (flags & GPO_INFO_FLAG_VERBOSE) {
973 printf("about to store key: [%s]\n", entry->key);
974 printf(" value: [%s]\n", entry->value);
975 printf(" data: [%s]\n", str_regtype(entry->data->type));
976 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
979 werr = gp_store_reg_subkey(mem_ctx, entry->key,
980 root_key, &key);
981 /* reg_ctx->curr_key, &key); */
982 if (!W_ERROR_IS_OK(werr)) {
983 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
984 return werr;
987 switch (entry->action) {
988 case GP_REG_ACTION_NONE:
989 case GP_REG_ACTION_ADD_KEY:
990 return WERR_OK;
992 case GP_REG_ACTION_SEC_KEY_SET:
993 werr = gp_secure_key(mem_ctx, flags,
994 key,
995 &token->sids[PRIMARY_USER_SID_INDEX]);
996 if (!W_ERROR_IS_OK(werr)) {
997 DEBUG(0,("reg_apply_registry_entry: "
998 "gp_secure_key failed: %s\n",
999 win_errstr(werr)));
1000 return werr;
1002 break;
1003 case GP_REG_ACTION_ADD_VALUE:
1004 werr = reg_setvalue(key, entry->value, entry->data);
1005 if (!W_ERROR_IS_OK(werr)) {
1006 DEBUG(0,("reg_apply_registry_entry: "
1007 "reg_setvalue failed: %s\n",
1008 win_errstr(werr)));
1009 dump_reg_entry(flags, "STORE", entry);
1010 return werr;
1012 break;
1013 case GP_REG_ACTION_DEL_VALUE:
1014 werr = reg_deletevalue(key, entry->value);
1015 if (!W_ERROR_IS_OK(werr)) {
1016 DEBUG(0,("reg_apply_registry_entry: "
1017 "reg_deletevalue failed: %s\n",
1018 win_errstr(werr)));
1019 dump_reg_entry(flags, "STORE", entry);
1020 return werr;
1022 break;
1023 case GP_REG_ACTION_DEL_ALL_VALUES:
1024 werr = reg_deleteallvalues(key);
1025 if (!W_ERROR_IS_OK(werr)) {
1026 DEBUG(0,("reg_apply_registry_entry: "
1027 "reg_deleteallvalues failed: %s\n",
1028 win_errstr(werr)));
1029 dump_reg_entry(flags, "STORE", entry);
1030 return werr;
1032 break;
1033 case GP_REG_ACTION_DEL_VALUES:
1034 case GP_REG_ACTION_DEL_KEYS:
1035 case GP_REG_ACTION_SEC_KEY_RESET:
1036 DEBUG(0,("reg_apply_registry_entry: "
1037 "not yet supported: %s (%d)\n",
1038 gp_reg_action_str(entry->action),
1039 entry->action));
1040 return WERR_NOT_SUPPORTED;
1041 default:
1042 DEBUG(0,("invalid action: %d\n", entry->action));
1043 return WERR_INVALID_PARAMETER;
1046 return werr;