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