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