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