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