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