s3-srvsvc: Use struct pipes_struct.
[Samba/gbeck.git] / source3 / libgpo / gpo_reg.c
blob5b56ecd365df813172010536eaa333f225204500
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_backend_db.h"
27 /****************************************************************
28 ****************************************************************/
30 struct nt_user_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
32 struct nt_user_token *token = NULL;
34 token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
35 if (!token) {
36 DEBUG(1,("talloc failed\n"));
37 return NULL;
40 token->privileges = se_priv_all;
42 if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
43 &token->user_sids, &token->num_sids))) {
44 DEBUG(1,("Error adding nt-authority system sid to token\n"));
45 return NULL;
48 return 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 nt_user_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_PARAM;
67 werr = registry_init_basic();
68 if (!W_ERROR_IS_OK(werr)) {
69 return werr;
72 tmp_ctx = TALLOC_ZERO_P(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_NOMEM;
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_NOMEM;
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_PARAM;
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_NOMEM;
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_NOMEM;
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_PARAM;
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);
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 NULL);
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 if (flags & GPO_LIST_FLAG_MACHINE) {
305 return "GroupMembership";
308 return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
309 "GroupMembership");
312 /****************************************************************
313 ****************************************************************/
315 static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
316 struct registry_key *key,
317 const struct nt_user_token *token,
318 uint32_t flags)
320 const char *path = NULL;
322 path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
323 flags);
324 W_ERROR_HAVE_NO_MEMORY(path);
326 return reg_deletekey_recursive(mem_ctx, key, path);
330 /****************************************************************
331 ****************************************************************/
333 static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
334 struct gp_registry_context *reg_ctx,
335 const struct nt_user_token *token,
336 uint32_t flags)
338 struct registry_key *key = NULL;
339 WERROR werr;
340 int i = 0;
341 const char *valname = NULL;
342 const char *path = NULL;
343 const char *val = NULL;
344 int count = 0;
346 path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
347 flags);
348 W_ERROR_HAVE_NO_MEMORY(path);
350 gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
352 werr = gp_store_reg_subkey(mem_ctx, path,
353 reg_ctx->curr_key, &key);
354 W_ERROR_NOT_OK_RETURN(werr);
356 for (i=0; i<token->num_sids; i++) {
358 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
359 W_ERROR_HAVE_NO_MEMORY(valname);
361 val = sid_string_talloc(mem_ctx, &token->user_sids[i]);
362 W_ERROR_HAVE_NO_MEMORY(val);
363 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
364 W_ERROR_NOT_OK_RETURN(werr);
367 werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
368 W_ERROR_NOT_OK_RETURN(werr);
370 return WERR_OK;
373 /****************************************************************
374 ****************************************************************/
375 #if 0
376 /* not used yet */
377 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
378 struct gp_registry_context *reg_ctx,
379 const struct dom_sid *object_sid,
380 struct nt_user_token **token,
381 uint32_t flags)
383 struct registry_key *key = NULL;
384 WERROR werr;
385 int i = 0;
386 const char *valname = NULL;
387 const char *val = NULL;
388 const char *path = NULL;
389 uint32_t count = 0;
390 int num_token_sids = 0;
391 struct nt_user_token *tmp_token = NULL;
393 tmp_token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
394 W_ERROR_HAVE_NO_MEMORY(tmp_token);
396 path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
397 W_ERROR_HAVE_NO_MEMORY(path);
399 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
400 W_ERROR_NOT_OK_RETURN(werr);
402 werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
403 W_ERROR_NOT_OK_RETURN(werr);
405 for (i=0; i<count; i++) {
407 valname = talloc_asprintf(mem_ctx, "Group%d", i);
408 W_ERROR_HAVE_NO_MEMORY(valname);
410 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
411 W_ERROR_NOT_OK_RETURN(werr);
413 if (!string_to_sid(&tmp_token->user_sids[num_token_sids++],
414 val)) {
415 return WERR_INSUFFICIENT_BUFFER;
419 tmp_token->num_sids = num_token_sids;
421 *token = tmp_token;
423 return WERR_OK;
425 #endif
426 /****************************************************************
427 ****************************************************************/
429 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
430 const struct dom_sid *sid,
431 uint32_t flags)
433 if (flags & GPO_LIST_FLAG_MACHINE) {
434 return GPO_REG_STATE_MACHINE;
437 return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid));
440 /****************************************************************
441 ****************************************************************/
443 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
444 struct registry_key *key,
445 const char *path)
447 return reg_deletesubkeys_recursive(mem_ctx, key, path);
450 /****************************************************************
451 ****************************************************************/
453 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
454 uint32_t flags,
455 const char *dn,
456 const struct nt_user_token *token,
457 struct GROUP_POLICY_OBJECT *gpo_list)
459 struct gp_registry_context *reg_ctx = NULL;
460 WERROR werr = WERR_GENERAL_FAILURE;
461 const char *subkeyname = NULL;
462 struct GROUP_POLICY_OBJECT *gpo;
463 int count = 0;
464 struct registry_key *key;
466 werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
467 token, &reg_ctx);
468 W_ERROR_NOT_OK_RETURN(werr);
470 werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
471 &token->user_sids[0]);
472 if (!W_ERROR_IS_OK(werr)) {
473 DEBUG(0,("failed to secure key: %s\n", win_errstr(werr)));
474 goto done;
477 werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
478 if (!W_ERROR_IS_OK(werr)) {
479 DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr)));
480 goto done;
483 subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags);
484 if (!subkeyname) {
485 werr = WERR_NOMEM;
486 goto done;
489 werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
490 if (!W_ERROR_IS_OK(werr)) {
491 DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr)));
492 /* goto done; */
495 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
496 reg_ctx->curr_key, &reg_ctx->curr_key);
497 if (!W_ERROR_IS_OK(werr)) {
498 goto done;
501 werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
502 "Distinguished-Name", dn);
503 if (!W_ERROR_IS_OK(werr)) {
504 goto done;
507 /* store link list */
509 werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
510 reg_ctx->curr_key, &key);
511 if (!W_ERROR_IS_OK(werr)) {
512 goto done;
515 /* store gpo list */
517 werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
518 reg_ctx->curr_key, &reg_ctx->curr_key);
519 if (!W_ERROR_IS_OK(werr)) {
520 goto done;
523 for (gpo = gpo_list; gpo; gpo = gpo->next) {
525 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
526 if (!subkeyname) {
527 werr = WERR_NOMEM;
528 goto done;
531 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
532 reg_ctx->curr_key, &key);
533 if (!W_ERROR_IS_OK(werr)) {
534 goto done;
537 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
538 if (!W_ERROR_IS_OK(werr)) {
539 DEBUG(0,("gp_reg_state_store: "
540 "gpo_store_reg_gpovals failed for %s: %s\n",
541 gpo->display_name, win_errstr(werr)));
542 goto done;
545 done:
546 gp_free_reg_ctx(reg_ctx);
547 return werr;
550 /****************************************************************
551 ****************************************************************/
553 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
554 struct registry_key *key,
555 struct GROUP_POLICY_OBJECT *gpo)
557 WERROR werr;
559 if (!key || !gpo) {
560 return WERR_INVALID_PARAM;
563 werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
564 &gpo->version);
565 W_ERROR_NOT_OK_RETURN(werr);
567 werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
568 &gpo->options);
569 W_ERROR_NOT_OK_RETURN(werr);
571 werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
572 &gpo->name);
573 W_ERROR_NOT_OK_RETURN(werr);
575 werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
576 &gpo->link);
577 W_ERROR_NOT_OK_RETURN(werr);
579 werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
580 &gpo->display_name);
581 W_ERROR_NOT_OK_RETURN(werr);
583 return werr;
586 /****************************************************************
587 ****************************************************************/
589 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
590 struct registry_key *key,
591 struct GROUP_POLICY_OBJECT **gpo_ret)
593 struct GROUP_POLICY_OBJECT *gpo = NULL;
594 WERROR werr;
596 if (!gpo_ret || !key) {
597 return WERR_INVALID_PARAM;
600 gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
601 W_ERROR_HAVE_NO_MEMORY(gpo);
603 werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
604 W_ERROR_NOT_OK_RETURN(werr);
606 *gpo_ret = gpo;
608 return werr;
611 /****************************************************************
612 ****************************************************************/
614 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
615 uint32_t flags,
616 const struct dom_sid *sid,
617 struct GROUP_POLICY_OBJECT **gpo_list)
619 struct gp_registry_context *reg_ctx = NULL;
620 WERROR werr = WERR_GENERAL_FAILURE;
621 const char *subkeyname = NULL;
622 struct GROUP_POLICY_OBJECT *gpo = NULL;
623 int count = 0;
624 struct registry_key *key = NULL;
625 const char *path = NULL;
626 const char *gp_state_path = NULL;
628 if (!gpo_list) {
629 return WERR_INVALID_PARAM;
632 ZERO_STRUCTP(gpo_list);
634 gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
635 if (!gp_state_path) {
636 werr = WERR_NOMEM;
637 goto done;
640 path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
641 KEY_GROUP_POLICY,
642 gp_state_path,
643 "GPO-List");
644 if (!path) {
645 werr = WERR_NOMEM;
646 goto done;
649 werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
650 if (!W_ERROR_IS_OK(werr)) {
651 goto done;
654 while (1) {
656 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
657 if (!subkeyname) {
658 werr = WERR_NOMEM;
659 goto done;
662 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
663 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
664 werr = WERR_OK;
665 break;
667 if (!W_ERROR_IS_OK(werr)) {
668 DEBUG(0,("gp_reg_state_read: "
669 "gp_read_reg_subkey gave: %s\n",
670 win_errstr(werr)));
671 goto done;
674 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
675 if (!W_ERROR_IS_OK(werr)) {
676 goto done;
679 DLIST_ADD(*gpo_list, gpo);
682 done:
683 gp_free_reg_ctx(reg_ctx);
684 return werr;
687 /****************************************************************
688 ****************************************************************/
690 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
691 const struct dom_sid *sid,
692 struct security_descriptor **sd,
693 size_t *sd_size)
695 struct security_ace ace[6];
696 uint32_t mask;
698 struct security_acl *theacl = NULL;
700 uint8_t inherit_flags;
702 mask = REG_KEY_ALL;
703 init_sec_ace(&ace[0],
704 &global_sid_System,
705 SEC_ACE_TYPE_ACCESS_ALLOWED,
706 mask, 0);
708 mask = REG_KEY_ALL;
709 init_sec_ace(&ace[1],
710 &global_sid_Builtin_Administrators,
711 SEC_ACE_TYPE_ACCESS_ALLOWED,
712 mask, 0);
714 mask = REG_KEY_READ;
715 init_sec_ace(&ace[2],
716 sid ? sid : &global_sid_Authenticated_Users,
717 SEC_ACE_TYPE_ACCESS_ALLOWED,
718 mask, 0);
720 inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
721 SEC_ACE_FLAG_CONTAINER_INHERIT |
722 SEC_ACE_FLAG_INHERIT_ONLY;
724 mask = REG_KEY_ALL;
725 init_sec_ace(&ace[3],
726 &global_sid_System,
727 SEC_ACE_TYPE_ACCESS_ALLOWED,
728 mask, inherit_flags);
730 mask = REG_KEY_ALL;
731 init_sec_ace(&ace[4],
732 &global_sid_Builtin_Administrators,
733 SEC_ACE_TYPE_ACCESS_ALLOWED,
734 mask, inherit_flags);
736 mask = REG_KEY_READ;
737 init_sec_ace(&ace[5],
738 sid ? sid : &global_sid_Authenticated_Users,
739 SEC_ACE_TYPE_ACCESS_ALLOWED,
740 mask, inherit_flags);
742 theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
743 W_ERROR_HAVE_NO_MEMORY(theacl);
745 *sd = make_sec_desc(mem_ctx, SD_REVISION,
746 SEC_DESC_SELF_RELATIVE |
747 SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
748 SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
749 NULL, NULL, NULL,
750 theacl, sd_size);
751 W_ERROR_HAVE_NO_MEMORY(*sd);
753 return WERR_OK;
756 /****************************************************************
757 ****************************************************************/
759 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
760 uint32_t flags,
761 struct registry_key *key,
762 const struct dom_sid *sid)
764 struct security_descriptor *sd = NULL;
765 size_t sd_size = 0;
766 const struct dom_sid *sd_sid = NULL;
767 WERROR werr;
769 if (!(flags & GPO_LIST_FLAG_MACHINE)) {
770 sd_sid = sid;
773 werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
774 W_ERROR_NOT_OK_RETURN(werr);
776 return reg_setkeysecurity(key, sd);
779 /****************************************************************
780 ****************************************************************/
782 void dump_reg_val(int lvl, const char *direction,
783 const char *key, const char *subkey,
784 struct registry_value *val)
786 int i = 0;
787 const char *type_str = NULL;
789 if (!val) {
790 DEBUG(lvl,("no val!\n"));
791 return;
794 type_str = str_regtype(val->type);
796 DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
797 direction, key, subkey, type_str));
799 switch (val->type) {
800 case REG_DWORD: {
801 uint32_t v;
802 if (val->data.length < 4) {
803 break;
805 v = IVAL(val->data.data, 0);
806 DEBUG(lvl,("%d (0x%08x)\n",
807 (int)v, v));
808 break;
810 case REG_QWORD: {
811 uint64_t v;
812 if (val->data.length < 8) {
813 break;
815 v = BVAL(val->data.data, 0);
816 DEBUG(lvl,("%d (0x%016llx)\n",
817 (int)v,
818 (unsigned long long)v));
819 break;
821 case REG_SZ: {
822 const char *s;
823 if (!pull_reg_sz(talloc_tos(), &val->data, &s)) {
824 break;
826 DEBUG(lvl,("%s (length: %d)\n",
827 s, (int)strlen_m(s)));
828 break;
830 case REG_MULTI_SZ: {
831 const char **a;
832 if (!pull_reg_multi_sz(talloc_tos(), &val->data, &a)) {
833 break;
835 for (i=0; a[i] != NULL; i++) {
838 DEBUG(lvl,("(num_strings: %d)\n", i));
839 for (i=0; a[i] != NULL; i++) {
840 DEBUGADD(lvl,("\t%s\n", a[i]));
842 break;
844 case REG_NONE:
845 DEBUG(lvl,("\n"));
846 break;
847 case REG_BINARY:
848 dump_data(lvl, val->data.data,
849 val->data.length);
850 break;
851 default:
852 DEBUG(lvl,("unsupported type: %d\n", val->type));
853 break;
857 /****************************************************************
858 ****************************************************************/
860 void dump_reg_entry(uint32_t flags,
861 const char *dir,
862 struct gp_registry_entry *entry)
864 if (!(flags & GPO_INFO_FLAG_VERBOSE))
865 return;
867 dump_reg_val(1, dir,
868 entry->key,
869 entry->value,
870 entry->data);
873 /****************************************************************
874 ****************************************************************/
876 void dump_reg_entries(uint32_t flags,
877 const char *dir,
878 struct gp_registry_entry *entries,
879 size_t num_entries)
881 size_t i;
883 if (!(flags & GPO_INFO_FLAG_VERBOSE))
884 return;
886 for (i=0; i < num_entries; i++) {
887 dump_reg_entry(flags, dir, &entries[i]);
891 /****************************************************************
892 ****************************************************************/
894 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
895 struct gp_registry_entry *entry,
896 struct gp_registry_entry **entries,
897 size_t *num)
899 *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
900 struct gp_registry_entry,
901 (*num)+1);
903 if (*entries == NULL) {
904 *num = 0;
905 return false;
908 (*entries)[*num].action = entry->action;
909 (*entries)[*num].key = entry->key;
910 (*entries)[*num].value = entry->value;
911 (*entries)[*num].data = entry->data;
913 *num += 1;
914 return true;
917 /****************************************************************
918 ****************************************************************/
920 static const char *gp_reg_action_str(enum gp_reg_action action)
922 switch (action) {
923 case GP_REG_ACTION_NONE:
924 return "GP_REG_ACTION_NONE";
925 case GP_REG_ACTION_ADD_VALUE:
926 return "GP_REG_ACTION_ADD_VALUE";
927 case GP_REG_ACTION_ADD_KEY:
928 return "GP_REG_ACTION_ADD_KEY";
929 case GP_REG_ACTION_DEL_VALUES:
930 return "GP_REG_ACTION_DEL_VALUES";
931 case GP_REG_ACTION_DEL_VALUE:
932 return "GP_REG_ACTION_DEL_VALUE";
933 case GP_REG_ACTION_DEL_ALL_VALUES:
934 return "GP_REG_ACTION_DEL_ALL_VALUES";
935 case GP_REG_ACTION_DEL_KEYS:
936 return "GP_REG_ACTION_DEL_KEYS";
937 case GP_REG_ACTION_SEC_KEY_SET:
938 return "GP_REG_ACTION_SEC_KEY_SET";
939 case GP_REG_ACTION_SEC_KEY_RESET:
940 return "GP_REG_ACTION_SEC_KEY_RESET";
941 default:
942 return "unknown";
946 /****************************************************************
947 ****************************************************************/
949 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
950 struct registry_key *root_key,
951 struct gp_registry_context *reg_ctx,
952 struct gp_registry_entry *entry,
953 const struct nt_user_token *token,
954 uint32_t flags)
956 WERROR werr;
957 struct registry_key *key = NULL;
959 if (flags & GPO_INFO_FLAG_VERBOSE) {
960 printf("about to store key: [%s]\n", entry->key);
961 printf(" value: [%s]\n", entry->value);
962 printf(" data: [%s]\n", str_regtype(entry->data->type));
963 printf(" action: [%s]\n", gp_reg_action_str(entry->action));
966 werr = gp_store_reg_subkey(mem_ctx, entry->key,
967 root_key, &key);
968 /* reg_ctx->curr_key, &key); */
969 if (!W_ERROR_IS_OK(werr)) {
970 DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr)));
971 return werr;
974 switch (entry->action) {
975 case GP_REG_ACTION_NONE:
976 case GP_REG_ACTION_ADD_KEY:
977 return WERR_OK;
979 case GP_REG_ACTION_SEC_KEY_SET:
980 werr = gp_secure_key(mem_ctx, flags,
981 key,
982 &token->user_sids[0]);
983 if (!W_ERROR_IS_OK(werr)) {
984 DEBUG(0,("reg_apply_registry_entry: "
985 "gp_secure_key failed: %s\n",
986 win_errstr(werr)));
987 return werr;
989 break;
990 case GP_REG_ACTION_ADD_VALUE:
991 werr = reg_setvalue(key, entry->value, entry->data);
992 if (!W_ERROR_IS_OK(werr)) {
993 DEBUG(0,("reg_apply_registry_entry: "
994 "reg_setvalue failed: %s\n",
995 win_errstr(werr)));
996 dump_reg_entry(flags, "STORE", entry);
997 return werr;
999 break;
1000 case GP_REG_ACTION_DEL_VALUE:
1001 werr = reg_deletevalue(key, entry->value);
1002 if (!W_ERROR_IS_OK(werr)) {
1003 DEBUG(0,("reg_apply_registry_entry: "
1004 "reg_deletevalue failed: %s\n",
1005 win_errstr(werr)));
1006 dump_reg_entry(flags, "STORE", entry);
1007 return werr;
1009 break;
1010 case GP_REG_ACTION_DEL_ALL_VALUES:
1011 werr = reg_deleteallvalues(key);
1012 if (!W_ERROR_IS_OK(werr)) {
1013 DEBUG(0,("reg_apply_registry_entry: "
1014 "reg_deleteallvalues failed: %s\n",
1015 win_errstr(werr)));
1016 dump_reg_entry(flags, "STORE", entry);
1017 return werr;
1019 break;
1020 case GP_REG_ACTION_DEL_VALUES:
1021 case GP_REG_ACTION_DEL_KEYS:
1022 case GP_REG_ACTION_SEC_KEY_RESET:
1023 DEBUG(0,("reg_apply_registry_entry: "
1024 "not yet supported: %s (%d)\n",
1025 gp_reg_action_str(entry->action),
1026 entry->action));
1027 return WERR_NOT_SUPPORTED;
1028 default:
1029 DEBUG(0,("invalid action: %d\n", entry->action));
1030 return WERR_INVALID_PARAM;
1033 return werr;