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