d49315021e4eccb8cb3c6184f5cbaa524e7902ce
[sfrench/samba-autobuild/.git] / source3 / libgpo / gpo_reg.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Guenther Deschner 2007-2008
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include "includes.h"
21
22
23 /****************************************************************
24 ****************************************************************/
25
26 struct nt_user_token *registry_create_system_token(TALLOC_CTX *mem_ctx)
27 {
28         struct nt_user_token *token = NULL;
29
30         token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
31         if (!token) {
32                 DEBUG(1,("talloc failed\n"));
33                 return NULL;
34         }
35
36         token->privileges = se_priv_all;
37
38         if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System,
39                          &token->user_sids, &token->num_sids))) {
40                 DEBUG(1,("Error adding nt-authority system sid to token\n"));
41                 return NULL;
42         }
43
44         return token;
45 }
46
47 /****************************************************************
48 ****************************************************************/
49
50 WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx,
51                        const char *initial_path,
52                        uint32_t desired_access,
53                        const struct nt_user_token *token,
54                        struct gp_registry_context **reg_ctx)
55 {
56         struct gp_registry_context *tmp_ctx;
57         WERROR werr;
58
59         if (!reg_ctx) {
60                 return WERR_INVALID_PARAM;
61         }
62
63         werr = registry_init_basic();
64         if (!W_ERROR_IS_OK(werr)) {
65                 return werr;
66         }
67
68         tmp_ctx = TALLOC_ZERO_P(mem_ctx, struct gp_registry_context);
69         W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
70
71         if (token) {
72                 tmp_ctx->token = token;
73         } else {
74                 tmp_ctx->token = registry_create_system_token(mem_ctx);
75         }
76         if (!tmp_ctx->token) {
77                 TALLOC_FREE(tmp_ctx);
78                 return WERR_NOMEM;
79         }
80
81         werr = regdb_open();
82         if (!W_ERROR_IS_OK(werr)) {
83                 return werr;
84         }
85
86         if (initial_path) {
87                 tmp_ctx->path = talloc_strdup(mem_ctx, initial_path);
88                 if (!tmp_ctx->path) {
89                         TALLOC_FREE(tmp_ctx);
90                         return WERR_NOMEM;
91                 }
92
93                 werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access,
94                                      tmp_ctx->token, &tmp_ctx->curr_key);
95                 if (!W_ERROR_IS_OK(werr)) {
96                         TALLOC_FREE(tmp_ctx);
97                         return werr;
98                 }
99         }
100
101         *reg_ctx = tmp_ctx;
102
103         return WERR_OK;
104 }
105
106 /****************************************************************
107 ****************************************************************/
108
109 void gp_free_reg_ctx(struct gp_registry_context *reg_ctx)
110 {
111         TALLOC_FREE(reg_ctx);
112 }
113
114 /****************************************************************
115 ****************************************************************/
116
117 WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx,
118                            const char *subkeyname,
119                            struct registry_key *curr_key,
120                            struct registry_key **new_key)
121 {
122         enum winreg_CreateAction action = REG_ACTION_NONE;
123         WERROR werr;
124
125         werr = reg_createkey(mem_ctx, curr_key, subkeyname,
126                              REG_KEY_WRITE, new_key, &action);
127         if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
128                 return WERR_OK;
129         }
130
131         return werr;
132 }
133
134 /****************************************************************
135 ****************************************************************/
136
137 WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx,
138                           struct gp_registry_context *reg_ctx,
139                           const char *subkeyname,
140                           struct registry_key **key)
141 {
142         const char *tmp = NULL;
143
144         if (!reg_ctx || !subkeyname || !key) {
145                 return WERR_INVALID_PARAM;
146         }
147
148         tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname);
149         W_ERROR_HAVE_NO_MEMORY(tmp);
150
151         return reg_open_path(mem_ctx, tmp, REG_KEY_READ,
152                              reg_ctx->token, key);
153 }
154
155 /****************************************************************
156 ****************************************************************/
157
158 WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx,
159                            struct registry_key *key,
160                            const char *val_name,
161                            const char *val)
162 {
163         struct registry_value reg_val;
164         ZERO_STRUCT(reg_val);
165
166         /* FIXME: hack */
167         val = val ? val : " ";
168
169         reg_val.type = REG_SZ;
170         reg_val.v.sz.len = strlen(val);
171         reg_val.v.sz.str = talloc_strdup(mem_ctx, val);
172         W_ERROR_HAVE_NO_MEMORY(reg_val.v.sz.str);
173
174         return reg_setvalue(key, val_name, &reg_val);
175 }
176
177 /****************************************************************
178 ****************************************************************/
179
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)
184 {
185         struct registry_value reg_val;
186         ZERO_STRUCT(reg_val);
187
188         reg_val.type = REG_DWORD;
189         reg_val.v.dword = val;
190
191         return reg_setvalue(key, val_name, &reg_val);
192 }
193
194 /****************************************************************
195 ****************************************************************/
196
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)
201 {
202         WERROR werr;
203         struct registry_value *reg_val = NULL;
204
205         werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
206         W_ERROR_NOT_OK_RETURN(werr);
207
208         if (reg_val->type != REG_SZ) {
209                 return WERR_INVALID_DATATYPE;
210         }
211
212         *val = talloc_strdup(mem_ctx, reg_val->v.sz.str);
213         W_ERROR_HAVE_NO_MEMORY(*val);
214
215         return WERR_OK;
216 }
217
218 /****************************************************************
219 ****************************************************************/
220
221 static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx,
222                                     struct registry_key *key,
223                                     const char *val_name,
224                                     uint32_t *val)
225 {
226         WERROR werr;
227         struct registry_value *reg_val = NULL;
228
229         werr = reg_queryvalue(mem_ctx, key, val_name, &reg_val);
230         W_ERROR_NOT_OK_RETURN(werr);
231
232         if (reg_val->type != REG_DWORD) {
233                 return WERR_INVALID_DATATYPE;
234         }
235
236         *val = reg_val->v.dword;
237
238         return WERR_OK;
239 }
240
241 /****************************************************************
242 ****************************************************************/
243
244 static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx,
245                                    struct registry_key *key,
246                                    struct GROUP_POLICY_OBJECT *gpo)
247 {
248         WERROR werr;
249
250         if (!key || !gpo) {
251                 return WERR_INVALID_PARAM;
252         }
253
254         werr = gp_store_reg_val_dword(mem_ctx, key, "Version",
255                                       gpo->version);
256         W_ERROR_NOT_OK_RETURN(werr);
257
258         werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass",
259                                       true); /* fake */
260         W_ERROR_NOT_OK_RETURN(werr);
261
262         werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied",
263                                       false); /* fake */
264         W_ERROR_NOT_OK_RETURN(werr);
265
266         werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled",
267                                       (gpo->options & GPO_FLAG_DISABLE));
268         W_ERROR_NOT_OK_RETURN(werr);
269
270         werr = gp_store_reg_val_dword(mem_ctx, key, "Options",
271                                       gpo->options);
272         W_ERROR_NOT_OK_RETURN(werr);
273
274         werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID",
275                                    gpo->name);
276         W_ERROR_NOT_OK_RETURN(werr);
277
278         werr = gp_store_reg_val_sz(mem_ctx, key, "SOM",
279                                    gpo->link);
280         W_ERROR_NOT_OK_RETURN(werr);
281
282         werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName",
283                                    gpo->display_name);
284         W_ERROR_NOT_OK_RETURN(werr);
285
286         werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id",
287                                    NULL);
288         W_ERROR_NOT_OK_RETURN(werr);
289
290         return werr;
291 }
292
293 /****************************************************************
294 ****************************************************************/
295
296 static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx,
297                                                const DOM_SID *sid,
298                                                uint32_t flags)
299 {
300         if (flags & GPO_LIST_FLAG_MACHINE) {
301                 return "GroupMembership";
302         }
303
304         return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid),
305                                "GroupMembership");
306 }
307
308 /****************************************************************
309 ****************************************************************/
310
311 static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx,
312                                          struct registry_key *key,
313                                          const struct nt_user_token *token,
314                                          uint32_t flags)
315 {
316         const char *path = NULL;
317
318         path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
319                                            flags);
320         W_ERROR_HAVE_NO_MEMORY(path);
321
322         return reg_deletekey_recursive(mem_ctx, key, path);
323
324 }
325
326 /****************************************************************
327 ****************************************************************/
328
329 static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx,
330                                            struct gp_registry_context *reg_ctx,
331                                            const struct nt_user_token *token,
332                                            uint32_t flags)
333 {
334         struct registry_key *key = NULL;
335         WERROR werr;
336         int i = 0;
337         const char *valname = NULL;
338         const char *path = NULL;
339         const char *val = NULL;
340         int count = 0;
341
342         path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0],
343                                            flags);
344         W_ERROR_HAVE_NO_MEMORY(path);
345
346         gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags);
347
348         werr = gp_store_reg_subkey(mem_ctx, path,
349                                    reg_ctx->curr_key, &key);
350         W_ERROR_NOT_OK_RETURN(werr);
351
352         for (i=0; i<token->num_sids; i++) {
353
354                 valname = talloc_asprintf(mem_ctx, "Group%d", count++);
355                 W_ERROR_HAVE_NO_MEMORY(valname);
356
357                 val = sid_string_talloc(mem_ctx, &token->user_sids[i]);
358                 W_ERROR_HAVE_NO_MEMORY(val);
359                 werr = gp_store_reg_val_sz(mem_ctx, key, valname, val);
360                 W_ERROR_NOT_OK_RETURN(werr);
361         }
362
363         werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count);
364         W_ERROR_NOT_OK_RETURN(werr);
365
366         return WERR_OK;
367 }
368
369 /****************************************************************
370 ****************************************************************/
371 #if 0
372 /* not used yet */
373 static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx,
374                                           struct gp_registry_context *reg_ctx,
375                                           const DOM_SID *object_sid,
376                                           struct nt_user_token **token,
377                                           uint32_t flags)
378 {
379         struct registry_key *key = NULL;
380         WERROR werr;
381         int i = 0;
382         const char *valname = NULL;
383         const char *val = NULL;
384         const char *path = NULL;
385         uint32_t count = 0;
386         int num_token_sids = 0;
387         struct nt_user_token *tmp_token = NULL;
388
389         tmp_token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token);
390         W_ERROR_HAVE_NO_MEMORY(tmp_token);
391
392         path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags);
393         W_ERROR_HAVE_NO_MEMORY(path);
394
395         werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key);
396         W_ERROR_NOT_OK_RETURN(werr);
397
398         werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count);
399         W_ERROR_NOT_OK_RETURN(werr);
400
401         for (i=0; i<count; i++) {
402
403                 valname = talloc_asprintf(mem_ctx, "Group%d", i);
404                 W_ERROR_HAVE_NO_MEMORY(valname);
405
406                 werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val);
407                 W_ERROR_NOT_OK_RETURN(werr);
408
409                 if (!string_to_sid(&tmp_token->user_sids[num_token_sids++],
410                                    val)) {
411                         return WERR_INSUFFICIENT_BUFFER;
412                 }
413         }
414
415         tmp_token->num_sids = num_token_sids;
416
417         *token = tmp_token;
418
419         return WERR_OK;
420 }
421 #endif
422 /****************************************************************
423 ****************************************************************/
424
425 static const char *gp_req_state_path(TALLOC_CTX *mem_ctx,
426                                      const DOM_SID *sid,
427                                      uint32_t flags)
428 {
429         if (flags & GPO_LIST_FLAG_MACHINE) {
430                 return GPO_REG_STATE_MACHINE;
431         }
432
433         return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid));
434 }
435
436 /****************************************************************
437 ****************************************************************/
438
439 static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx,
440                                struct registry_key *key,
441                                const char *path)
442 {
443         return reg_deletesubkeys_recursive(mem_ctx, key, path);
444 }
445
446 /****************************************************************
447 ****************************************************************/
448
449 WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx,
450                           uint32_t flags,
451                           const char *dn,
452                           const struct nt_user_token *token,
453                           struct GROUP_POLICY_OBJECT *gpo_list)
454 {
455         struct gp_registry_context *reg_ctx = NULL;
456         WERROR werr = WERR_GENERAL_FAILURE;
457         const char *subkeyname = NULL;
458         struct GROUP_POLICY_OBJECT *gpo;
459         int count = 0;
460         struct registry_key *key;
461
462         werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE,
463                                token, &reg_ctx);
464         W_ERROR_NOT_OK_RETURN(werr);
465
466         werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key,
467                              &token->user_sids[0]);
468         if (!W_ERROR_IS_OK(werr)) {
469                 DEBUG(0,("failed to secure key: %s\n", dos_errstr(werr)));
470                 goto done;
471         }
472
473         werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags);
474         if (!W_ERROR_IS_OK(werr)) {
475                 DEBUG(0,("failed to store group membership: %s\n", dos_errstr(werr)));
476                 goto done;
477         }
478
479         subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags);
480         if (!subkeyname) {
481                 werr = WERR_NOMEM;
482                 goto done;
483         }
484
485         werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname);
486         if (!W_ERROR_IS_OK(werr)) {
487                 DEBUG(0,("failed to delete old state: %s\n", dos_errstr(werr)));
488                 /* goto done; */
489         }
490
491         werr = gp_store_reg_subkey(mem_ctx, subkeyname,
492                                    reg_ctx->curr_key, &reg_ctx->curr_key);
493         if (!W_ERROR_IS_OK(werr)) {
494                 goto done;
495         }
496
497         werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key,
498                                    "Distinguished-Name", dn);
499         if (!W_ERROR_IS_OK(werr)) {
500                 goto done;
501         }
502
503         /* store link list */
504
505         werr = gp_store_reg_subkey(mem_ctx, "GPLink-List",
506                                    reg_ctx->curr_key, &key);
507         if (!W_ERROR_IS_OK(werr)) {
508                 goto done;
509         }
510
511         /* store gpo list */
512
513         werr = gp_store_reg_subkey(mem_ctx, "GPO-List",
514                                    reg_ctx->curr_key, &reg_ctx->curr_key);
515         if (!W_ERROR_IS_OK(werr)) {
516                 goto done;
517         }
518
519         for (gpo = gpo_list; gpo; gpo = gpo->next) {
520
521                 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
522                 if (!subkeyname) {
523                         werr = WERR_NOMEM;
524                         goto done;
525                 }
526
527                 werr = gp_store_reg_subkey(mem_ctx, subkeyname,
528                                            reg_ctx->curr_key, &key);
529                 if (!W_ERROR_IS_OK(werr)) {
530                         goto done;
531                 }
532
533                 werr = gp_store_reg_gpovals(mem_ctx, key, gpo);
534                 if (!W_ERROR_IS_OK(werr)) {
535                         DEBUG(0,("gp_reg_state_store: "
536                                 "gpo_store_reg_gpovals failed for %s: %s\n",
537                                 gpo->display_name, dos_errstr(werr)));
538                         goto done;
539                 }
540         }
541  done:
542         gp_free_reg_ctx(reg_ctx);
543         return werr;
544 }
545
546 /****************************************************************
547 ****************************************************************/
548
549 static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx,
550                                   struct registry_key *key,
551                                   struct GROUP_POLICY_OBJECT *gpo)
552 {
553         WERROR werr;
554
555         if (!key || !gpo) {
556                 return WERR_INVALID_PARAM;
557         }
558
559         werr = gp_read_reg_val_dword(mem_ctx, key, "Version",
560                                      &gpo->version);
561         W_ERROR_NOT_OK_RETURN(werr);
562
563         werr = gp_read_reg_val_dword(mem_ctx, key, "Options",
564                                      &gpo->options);
565         W_ERROR_NOT_OK_RETURN(werr);
566
567         werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID",
568                                   &gpo->name);
569         W_ERROR_NOT_OK_RETURN(werr);
570
571         werr = gp_read_reg_val_sz(mem_ctx, key, "SOM",
572                                   &gpo->link);
573         W_ERROR_NOT_OK_RETURN(werr);
574
575         werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName",
576                                   &gpo->display_name);
577         W_ERROR_NOT_OK_RETURN(werr);
578
579         return werr;
580 }
581
582 /****************************************************************
583 ****************************************************************/
584
585 static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx,
586                               struct registry_key *key,
587                               struct GROUP_POLICY_OBJECT **gpo_ret)
588 {
589         struct GROUP_POLICY_OBJECT *gpo = NULL;
590         WERROR werr;
591
592         if (!gpo_ret || !key) {
593                 return WERR_INVALID_PARAM;
594         }
595
596         gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
597         W_ERROR_HAVE_NO_MEMORY(gpo);
598
599         werr = gp_read_reg_gpovals(mem_ctx, key, gpo);
600         W_ERROR_NOT_OK_RETURN(werr);
601
602         *gpo_ret = gpo;
603
604         return werr;
605 }
606
607 /****************************************************************
608 ****************************************************************/
609
610 WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx,
611                          uint32_t flags,
612                          const DOM_SID *sid,
613                          struct GROUP_POLICY_OBJECT **gpo_list)
614 {
615         struct gp_registry_context *reg_ctx = NULL;
616         WERROR werr = WERR_GENERAL_FAILURE;
617         const char *subkeyname = NULL;
618         struct GROUP_POLICY_OBJECT *gpo = NULL;
619         int count = 0;
620         struct registry_key *key = NULL;
621         const char *path = NULL;
622         const char *gp_state_path = NULL;
623
624         if (!gpo_list) {
625                 return WERR_INVALID_PARAM;
626         }
627
628         ZERO_STRUCTP(gpo_list);
629
630         gp_state_path = gp_req_state_path(mem_ctx, sid, flags);
631         if (!gp_state_path) {
632                 werr = WERR_NOMEM;
633                 goto done;
634         }
635
636         path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
637                                KEY_GROUP_POLICY,
638                                gp_state_path,
639                                "GPO-List");
640         if (!path) {
641                 werr = WERR_NOMEM;
642                 goto done;
643         }
644
645         werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, &reg_ctx);
646         if (!W_ERROR_IS_OK(werr)) {
647                 goto done;
648         }
649
650         while (1) {
651
652                 subkeyname = talloc_asprintf(mem_ctx, "%d", count++);
653                 if (!subkeyname) {
654                         werr = WERR_NOMEM;
655                         goto done;
656                 }
657
658                 werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key);
659                 if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
660                         werr = WERR_OK;
661                         break;
662                 }
663                 if (!W_ERROR_IS_OK(werr)) {
664                         DEBUG(0,("gp_reg_state_read: "
665                                 "gp_read_reg_subkey gave: %s\n",
666                                 dos_errstr(werr)));
667                         goto done;
668                 }
669
670                 werr = gp_read_reg_gpo(mem_ctx, key, &gpo);
671                 if (!W_ERROR_IS_OK(werr)) {
672                         goto done;
673                 }
674
675                 DLIST_ADD(*gpo_list, gpo);
676         }
677
678  done:
679         gp_free_reg_ctx(reg_ctx);
680         return werr;
681 }
682
683 /****************************************************************
684 ****************************************************************/
685
686 static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
687                                  const DOM_SID *sid,
688                                  struct security_descriptor **sd,
689                                  size_t *sd_size)
690 {
691         SEC_ACE ace[6];
692         uint32_t mask;
693
694         SEC_ACL *acl = NULL;
695
696         uint8_t inherit_flags;
697
698         mask = REG_KEY_ALL;
699         init_sec_ace(&ace[0],
700                      &global_sid_System,
701                      SEC_ACE_TYPE_ACCESS_ALLOWED,
702                      mask, 0);
703
704         mask = REG_KEY_ALL;
705         init_sec_ace(&ace[1],
706                      &global_sid_Builtin_Administrators,
707                      SEC_ACE_TYPE_ACCESS_ALLOWED,
708                      mask, 0);
709
710         mask = REG_KEY_READ;
711         init_sec_ace(&ace[2],
712                      sid ? sid : &global_sid_Authenticated_Users,
713                      SEC_ACE_TYPE_ACCESS_ALLOWED,
714                      mask, 0);
715
716         inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
717                         SEC_ACE_FLAG_CONTAINER_INHERIT |
718                         SEC_ACE_FLAG_INHERIT_ONLY;
719
720         mask = REG_KEY_ALL;
721         init_sec_ace(&ace[3],
722                      &global_sid_System,
723                      SEC_ACE_TYPE_ACCESS_ALLOWED,
724                      mask, inherit_flags);
725
726         mask = REG_KEY_ALL;
727         init_sec_ace(&ace[4],
728                      &global_sid_Builtin_Administrators,
729                      SEC_ACE_TYPE_ACCESS_ALLOWED,
730                      mask, inherit_flags);
731
732         mask = REG_KEY_READ;
733         init_sec_ace(&ace[5],
734                      sid ? sid : &global_sid_Authenticated_Users,
735                      SEC_ACE_TYPE_ACCESS_ALLOWED,
736                      mask, inherit_flags);
737
738         acl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
739         W_ERROR_HAVE_NO_MEMORY(acl);
740
741         *sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
742                             SEC_DESC_SELF_RELATIVE |
743                             SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
744                             SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
745                             NULL, NULL, NULL,
746                             acl, sd_size);
747         W_ERROR_HAVE_NO_MEMORY(*sd);
748
749         return WERR_OK;
750 }
751
752 /****************************************************************
753 ****************************************************************/
754
755 WERROR gp_secure_key(TALLOC_CTX *mem_ctx,
756                      uint32_t flags,
757                      struct registry_key *key,
758                      const DOM_SID *sid)
759 {
760         struct security_descriptor *sd = NULL;
761         size_t sd_size = 0;
762         const DOM_SID *sd_sid = NULL;
763         WERROR werr;
764
765         if (!(flags & GPO_LIST_FLAG_MACHINE)) {
766                 sd_sid = sid;
767         }
768
769         werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size);
770         W_ERROR_NOT_OK_RETURN(werr);
771
772         return reg_setkeysecurity(key, sd);
773 }
774
775 /****************************************************************
776 ****************************************************************/
777
778 void dump_reg_val(int lvl, const char *direction,
779                   const char *key, const char *subkey,
780                   struct registry_value *val)
781 {
782         int i = 0;
783         const char *type_str = NULL;
784
785         if (!val) {
786                 DEBUG(lvl,("no val!\n"));
787                 return;
788         }
789
790         type_str = reg_type_lookup(val->type);
791
792         DEBUG(lvl,("\tdump_reg_val:\t%s '%s'\n\t\t\t'%s' %s: ",
793                 direction, key, subkey, type_str));
794
795         switch (val->type) {
796                 case REG_DWORD:
797                         DEBUG(lvl,("%d (0x%08x)\n",
798                                 (int)val->v.dword, val->v.dword));
799                         break;
800                 case REG_QWORD:
801                         DEBUG(lvl,("%d (0x%016llx)\n",
802                                 (int)val->v.qword,
803                                 (unsigned long long)val->v.qword));
804                         break;
805                 case REG_SZ:
806                         DEBUG(lvl,("%s (length: %d)\n",
807                                    val->v.sz.str,
808                                    (int)val->v.sz.len));
809                         break;
810                 case REG_MULTI_SZ:
811                         DEBUG(lvl,("(num_strings: %d)\n",
812                                    val->v.multi_sz.num_strings));
813                         for (i=0; i < val->v.multi_sz.num_strings; i++) {
814                                 DEBUGADD(lvl,("\t%s\n",
815                                         val->v.multi_sz.strings[i]));
816                         }
817                         break;
818                 case REG_NONE:
819                         DEBUG(lvl,("\n"));
820                         break;
821                 case REG_BINARY:
822                         dump_data(lvl, val->v.binary.data,
823                                   val->v.binary.length);
824                         break;
825                 default:
826                         DEBUG(lvl,("unsupported type: %d\n", val->type));
827                         break;
828         }
829 }
830
831 /****************************************************************
832 ****************************************************************/
833
834 void dump_reg_entry(uint32_t flags,
835                     const char *dir,
836                     struct gp_registry_entry *entry)
837 {
838         if (!(flags & GPO_INFO_FLAG_VERBOSE))
839                 return;
840
841         dump_reg_val(1, dir,
842                      entry->key,
843                      entry->value,
844                      entry->data);
845 }
846
847 /****************************************************************
848 ****************************************************************/
849
850 void dump_reg_entries(uint32_t flags,
851                       const char *dir,
852                       struct gp_registry_entry *entries,
853                       size_t num_entries)
854 {
855         size_t i;
856
857         if (!(flags & GPO_INFO_FLAG_VERBOSE))
858                 return;
859
860         for (i=0; i < num_entries; i++) {
861                 dump_reg_entry(flags, dir, &entries[i]);
862         }
863 }
864
865 /****************************************************************
866 ****************************************************************/
867
868 bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx,
869                                     struct gp_registry_entry *entry,
870                                     struct gp_registry_entry **entries,
871                                     size_t *num)
872 {
873         *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
874                                         struct gp_registry_entry,
875                                         (*num)+1);
876
877         if (*entries == NULL) {
878                 *num = 0;
879                 return false;
880         }
881
882         (*entries)[*num].action = entry->action;
883         (*entries)[*num].key = entry->key;
884         (*entries)[*num].value = entry->value;
885         (*entries)[*num].data = entry->data;
886
887         *num += 1;
888         return true;
889 }
890
891 /****************************************************************
892 ****************************************************************/
893
894 static const char *gp_reg_action_str(enum gp_reg_action action)
895 {
896         switch (action) {
897                 case GP_REG_ACTION_NONE:
898                         return "GP_REG_ACTION_NONE";
899                 case GP_REG_ACTION_ADD_VALUE:
900                         return "GP_REG_ACTION_ADD_VALUE";
901                 case GP_REG_ACTION_ADD_KEY:
902                         return "GP_REG_ACTION_ADD_KEY";
903                 case GP_REG_ACTION_DEL_VALUES:
904                         return "GP_REG_ACTION_DEL_VALUES";
905                 case GP_REG_ACTION_DEL_VALUE:
906                         return "GP_REG_ACTION_DEL_VALUE";
907                 case GP_REG_ACTION_DEL_ALL_VALUES:
908                         return "GP_REG_ACTION_DEL_ALL_VALUES";
909                 case GP_REG_ACTION_DEL_KEYS:
910                         return "GP_REG_ACTION_DEL_KEYS";
911                 case GP_REG_ACTION_SEC_KEY_SET:
912                         return "GP_REG_ACTION_SEC_KEY_SET";
913                 case GP_REG_ACTION_SEC_KEY_RESET:
914                         return "GP_REG_ACTION_SEC_KEY_RESET";
915                 default:
916                         return "unknown";
917         }
918 }
919
920 /****************************************************************
921 ****************************************************************/
922
923 WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx,
924                                 struct registry_key *root_key,
925                                 struct gp_registry_context *reg_ctx,
926                                 struct gp_registry_entry *entry,
927                                 const struct nt_user_token *token,
928                                 uint32_t flags)
929 {
930         WERROR werr;
931         struct registry_key *key = NULL;
932
933         if (flags & GPO_INFO_FLAG_VERBOSE) {
934                 printf("about to store key:    [%s]\n", entry->key);
935                 printf("               value:  [%s]\n", entry->value);
936                 printf("               data:   [%s]\n", reg_type_lookup(entry->data->type));
937                 printf("               action: [%s]\n", gp_reg_action_str(entry->action));
938         }
939
940         werr = gp_store_reg_subkey(mem_ctx, entry->key,
941                                    root_key, &key);
942                                    /* reg_ctx->curr_key, &key); */
943         if (!W_ERROR_IS_OK(werr)) {
944                 DEBUG(0,("gp_store_reg_subkey failed: %s\n", dos_errstr(werr)));
945                 return werr;
946         }
947
948         switch (entry->action) {
949                 case GP_REG_ACTION_NONE:
950                 case GP_REG_ACTION_ADD_KEY:
951                         return WERR_OK;
952
953                 case GP_REG_ACTION_SEC_KEY_SET:
954                         werr = gp_secure_key(mem_ctx, flags,
955                                              key,
956                                              &token->user_sids[0]);
957                         if (!W_ERROR_IS_OK(werr)) {
958                                 DEBUG(0,("reg_apply_registry_entry: "
959                                         "gp_secure_key failed: %s\n",
960                                         dos_errstr(werr)));
961                                 return werr;
962                         }
963                         break;
964                 case GP_REG_ACTION_ADD_VALUE:
965                         werr = reg_setvalue(key, entry->value, entry->data);
966                         if (!W_ERROR_IS_OK(werr)) {
967                                 DEBUG(0,("reg_apply_registry_entry: "
968                                         "reg_setvalue failed: %s\n",
969                                         dos_errstr(werr)));
970                                 dump_reg_entry(flags, "STORE", entry);
971                                 return werr;
972                         }
973                         break;
974                 case GP_REG_ACTION_DEL_VALUE:
975                         werr = reg_deletevalue(key, entry->value);
976                         if (!W_ERROR_IS_OK(werr)) {
977                                 DEBUG(0,("reg_apply_registry_entry: "
978                                         "reg_deletevalue failed: %s\n",
979                                         dos_errstr(werr)));
980                                 dump_reg_entry(flags, "STORE", entry);
981                                 return werr;
982                         }
983                         break;
984                 case GP_REG_ACTION_DEL_ALL_VALUES:
985                         werr = reg_deleteallvalues(key);
986                         if (!W_ERROR_IS_OK(werr)) {
987                                 DEBUG(0,("reg_apply_registry_entry: "
988                                         "reg_deleteallvalues failed: %s\n",
989                                         dos_errstr(werr)));
990                                 dump_reg_entry(flags, "STORE", entry);
991                                 return werr;
992                         }
993                         break;
994                 case GP_REG_ACTION_DEL_VALUES:
995                 case GP_REG_ACTION_DEL_KEYS:
996                 case GP_REG_ACTION_SEC_KEY_RESET:
997                         DEBUG(0,("reg_apply_registry_entry: "
998                                 "not yet supported: %s (%d)\n",
999                                 gp_reg_action_str(entry->action),
1000                                 entry->action));
1001                         return WERR_NOT_SUPPORTED;
1002                 default:
1003                         DEBUG(0,("invalid action: %d\n", entry->action));
1004                         return WERR_INVALID_PARAM;
1005         }
1006
1007         return werr;
1008 }
1009