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