s3-passdb: use passdb headers where needed.
[samba.git] / source3 / utils / net_registry.c
1 /*
2  * Samba Unix/Linux SMB client library
3  * Distributed SMB/CIFS Server Management Utility
4  * Local registry interface
5  *
6  * Copyright (C) Michael Adam 2008
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23 #include "registry.h"
24 #include "registry/reg_api.h"
25 #include "registry/reg_util_token.h"
26 #include "registry/reg_init_basic.h"
27 #include "utils/net.h"
28 #include "utils/net_registry_util.h"
29 #include "include/g_lock.h"
30 #include "registry/reg_backend_db.h"
31 #include "registry/reg_import.h"
32 #include "registry/reg_format.h"
33 #include <assert.h>
34 #include "../libcli/security/display_sec.h"
35 #include "../libcli/security/sddl.h"
36 #include "../libcli/registry/util_reg.h"
37 #include "passdb/machine_sid.h"
38
39 /*
40  *
41  * Helper functions
42  *
43  */
44
45 /**
46  * split given path into hive and remaining path and open the hive key
47  */
48 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
49                         uint32 desired_access,
50                         struct registry_key **hive,
51                         char **subkeyname)
52 {
53         WERROR werr;
54         struct security_token *token = NULL;
55         char *hivename = NULL;
56         char *tmp_subkeyname = NULL;
57         TALLOC_CTX *tmp_ctx = talloc_stackframe();
58
59         if ((hive == NULL) || (subkeyname == NULL)) {
60                 werr = WERR_INVALID_PARAM;
61                 goto done;
62         }
63
64         werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
65         if (!W_ERROR_IS_OK(werr)) {
66                 goto done;
67         }
68         *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
69         if (*subkeyname == NULL) {
70                 werr = WERR_NOMEM;
71                 goto done;
72         }
73
74         werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
75         if (!W_ERROR_IS_OK(werr)) {
76                 goto done;
77         }
78
79         werr = reg_openhive(ctx, hivename, desired_access, token, hive);
80         if (!W_ERROR_IS_OK(werr)) {
81                 goto done;
82         }
83
84         werr = WERR_OK;
85
86 done:
87         TALLOC_FREE(tmp_ctx);
88         return werr;
89 }
90
91 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
92                        uint32 desired_access,
93                        struct registry_key **key)
94 {
95         WERROR werr;
96         char *subkey_name = NULL;
97         struct registry_key *hive = NULL;
98         TALLOC_CTX *tmp_ctx = talloc_stackframe();
99
100         if ((path == NULL) || (key == NULL)) {
101                 return WERR_INVALID_PARAM;
102         }
103
104         werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
105         if (!W_ERROR_IS_OK(werr)) {
106                 d_fprintf(stderr, _("open_hive failed: %s\n"),
107                           win_errstr(werr));
108                 goto done;
109         }
110
111         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
112         if (!W_ERROR_IS_OK(werr)) {
113                 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
114                           win_errstr(werr));
115                 goto done;
116         }
117
118         werr = WERR_OK;
119
120 done:
121         TALLOC_FREE(tmp_ctx);
122         return werr;
123 }
124
125 /*
126  *
127  * the main "net registry" function implementations
128  *
129  */
130
131 static int net_registry_enumerate(struct net_context *c, int argc,
132                                   const char **argv)
133 {
134         WERROR werr;
135         struct registry_key *key = NULL;
136         TALLOC_CTX *ctx = talloc_stackframe();
137         char *subkey_name;
138         NTTIME modtime;
139         uint32_t count;
140         char *valname = NULL;
141         struct registry_value *valvalue = NULL;
142         int ret = -1;
143
144         if (argc != 1 || c->display_usage) {
145                 d_printf("%s\n%s",
146                          _("Usage:"),
147                          _("net registry enumerate <path>\n"));
148                 d_printf("%s\n%s",
149                          _("Example:"),
150                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
151                 goto done;
152         }
153
154         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
155         if (!W_ERROR_IS_OK(werr)) {
156                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
157                 goto done;
158         }
159
160         for (count = 0;
161              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
162              W_ERROR_IS_OK(werr);
163              count++)
164         {
165                 print_registry_key(subkey_name, &modtime);
166         }
167         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
168                 goto done;
169         }
170
171         for (count = 0;
172              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
173              W_ERROR_IS_OK(werr);
174              count++)
175         {
176                 print_registry_value_with_name(valname, valvalue);
177         }
178         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
179                 goto done;
180         }
181
182         ret = 0;
183 done:
184         TALLOC_FREE(ctx);
185         return ret;
186 }
187
188 static int net_registry_createkey(struct net_context *c, int argc,
189                                   const char **argv)
190 {
191         WERROR werr;
192         enum winreg_CreateAction action;
193         char *subkeyname;
194         struct registry_key *hivekey = NULL;
195         struct registry_key *subkey = NULL;
196         TALLOC_CTX *ctx = talloc_stackframe();
197         int ret = -1;
198
199         if (argc != 1 || c->display_usage) {
200                 d_printf("%s\n%s",
201                          _("Usage:"),
202                          _("net registry createkey <path>\n"));
203                 d_printf("%s\n%s",
204                          _("Example:"),
205                          _("net registry createkey "
206                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
207                 goto done;
208         }
209         if (strlen(argv[0]) == 0) {
210                 d_fprintf(stderr, _("error: zero length key name given\n"));
211                 goto done;
212         }
213
214         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
215         if (!W_ERROR_IS_OK(werr)) {
216                 d_fprintf(stderr, _("open_hive failed: %s\n"),
217                           win_errstr(werr));
218                 goto done;
219         }
220
221         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
222                              &subkey, &action);
223         if (!W_ERROR_IS_OK(werr)) {
224                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
225                           win_errstr(werr));
226                 goto done;
227         }
228         switch (action) {
229                 case REG_ACTION_NONE:
230                         d_printf(_("createkey did nothing -- huh?\n"));
231                         break;
232                 case REG_CREATED_NEW_KEY:
233                         d_printf(_("createkey created %s\n"), argv[0]);
234                         break;
235                 case REG_OPENED_EXISTING_KEY:
236                         d_printf(_("createkey opened existing %s\n"), argv[0]);
237                         break;
238         }
239
240         ret = 0;
241
242 done:
243         TALLOC_FREE(ctx);
244         return ret;
245 }
246
247 static int net_registry_deletekey_internal(struct net_context *c, int argc,
248                                            const char **argv,
249                                            bool recursive)
250 {
251         WERROR werr;
252         char *subkeyname;
253         struct registry_key *hivekey = NULL;
254         TALLOC_CTX *ctx = talloc_stackframe();
255         int ret = -1;
256
257         if (argc != 1 || c->display_usage) {
258                 d_printf("%s\n%s",
259                          _("Usage:"),
260                          _("net registry deletekey <path>\n"));
261                 d_printf("%s\n%s",
262                          _("Example:"),
263                          _("net registry deletekey "
264                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
265                 goto done;
266         }
267         if (strlen(argv[0]) == 0) {
268                 d_fprintf(stderr, _("error: zero length key name given\n"));
269                 goto done;
270         }
271
272         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
273         if (!W_ERROR_IS_OK(werr)) {
274                 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
275                           win_errstr(werr));
276                 goto done;
277         }
278
279         if (recursive) {
280                 werr = reg_deletekey_recursive(hivekey, subkeyname);
281         } else {
282                 werr = reg_deletekey(hivekey, subkeyname);
283         }
284         if (!W_ERROR_IS_OK(werr) &&
285             !(c->opt_force && W_ERROR_EQUAL(werr, WERR_BADFILE)))
286         {
287                 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
288                           win_errstr(werr));
289                 goto done;
290         }
291
292         ret = 0;
293
294 done:
295         TALLOC_FREE(ctx);
296         return ret;
297 }
298
299 static int net_registry_deletekey(struct net_context *c, int argc,
300                                   const char **argv)
301 {
302         return net_registry_deletekey_internal(c, argc, argv, false);
303 }
304
305 static int net_registry_deletekey_recursive(struct net_context *c, int argc,
306                                             const char **argv)
307 {
308         return net_registry_deletekey_internal(c, argc, argv, true);
309 }
310
311 static int net_registry_getvalue_internal(struct net_context *c, int argc,
312                                           const char **argv, bool raw)
313 {
314         WERROR werr;
315         int ret = -1;
316         struct registry_key *key = NULL;
317         struct registry_value *value = NULL;
318         TALLOC_CTX *ctx = talloc_stackframe();
319
320         if (argc != 2 || c->display_usage) {
321                 d_fprintf(stderr, "%s\n%s",
322                           _("Usage:"),
323                           _("net registry getvalue <key> <valuename>\n"));
324                 goto done;
325         }
326
327         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
328         if (!W_ERROR_IS_OK(werr)) {
329                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
330                 goto done;
331         }
332
333         werr = reg_queryvalue(ctx, key, argv[1], &value);
334         if (!W_ERROR_IS_OK(werr)) {
335                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
336                           win_errstr(werr));
337                 goto done;
338         }
339
340         print_registry_value(value, raw);
341
342         ret = 0;
343
344 done:
345         TALLOC_FREE(ctx);
346         return ret;
347 }
348
349 static int net_registry_getvalue(struct net_context *c, int argc,
350                                  const char **argv)
351 {
352         return net_registry_getvalue_internal(c, argc, argv, false);
353 }
354
355 static int net_registry_getvalueraw(struct net_context *c, int argc,
356                                     const char **argv)
357 {
358         return net_registry_getvalue_internal(c, argc, argv, true);
359 }
360
361 static int net_registry_getvaluesraw(struct net_context *c, int argc,
362                                      const char **argv)
363 {
364         WERROR werr;
365         int ret = -1;
366         struct registry_key *key = NULL;
367         TALLOC_CTX *ctx = talloc_stackframe();
368         uint32_t idx;
369
370         if (argc != 1 || c->display_usage) {
371                 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
372                           "<key>\n");
373                 goto done;
374         }
375
376         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
377         if (!W_ERROR_IS_OK(werr)) {
378                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
379                 goto done;
380         }
381
382         idx = 0;
383         while (true) {
384                 struct registry_value *val;
385
386                 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
387
388                 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
389                         ret = 0;
390                         break;
391                 }
392                 if (!W_ERROR_IS_OK(werr)) {
393                         break;
394                 }
395                 print_registry_value(val, true);
396                 TALLOC_FREE(val);
397                 idx += 1;
398         }
399 done:
400         TALLOC_FREE(ctx);
401         return ret;
402 }
403
404 static int net_registry_setvalue(struct net_context *c, int argc,
405                                  const char **argv)
406 {
407         WERROR werr;
408         struct registry_value value;
409         struct registry_key *key = NULL;
410         int ret = -1;
411         TALLOC_CTX *ctx = talloc_stackframe();
412
413         if (argc < 4 || c->display_usage) {
414                 d_fprintf(stderr, "%s\n%s",
415                           _("Usage:"),
416                           _("net registry setvalue <key> <valuename> "
417                             "<type> [<val>]+\n"));
418                 goto done;
419         }
420
421         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
422                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
423                 goto done;
424         }
425
426         if (strequal(argv[2], "dword")) {
427                 uint32_t v = strtoul(argv[3], NULL, 10);
428                 value.type = REG_DWORD;
429                 value.data = data_blob_talloc(ctx, NULL, 4);
430                 SIVAL(value.data.data, 0, v);
431         } else if (strequal(argv[2], "sz")) {
432                 value.type = REG_SZ;
433                 if (!push_reg_sz(ctx, &value.data, argv[3])) {
434                         goto done;
435                 }
436         } else if (strequal(argv[2], "multi_sz")) {
437                 const char **array;
438                 int count = argc - 3;
439                 int i;
440                 value.type = REG_MULTI_SZ;
441                 array = talloc_zero_array(ctx, const char *, count + 1);
442                 if (array == NULL) {
443                         goto done;
444                 }
445                 for (i=0; i < count; i++) {
446                         array[i] = talloc_strdup(array, argv[count+i]);
447                         if (array[i] == NULL) {
448                                 goto done;
449                         }
450                 }
451                 if (!push_reg_multi_sz(ctx, &value.data, array)) {
452                         goto done;
453                 }
454         } else {
455                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
456                 goto done;
457         }
458
459         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
460         if (!W_ERROR_IS_OK(werr)) {
461                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
462                 goto done;
463         }
464
465         werr = reg_setvalue(key, argv[1], &value);
466         if (!W_ERROR_IS_OK(werr)) {
467                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
468                           win_errstr(werr));
469                 goto done;
470         }
471
472         ret = 0;
473
474 done:
475         TALLOC_FREE(ctx);
476         return ret;
477 }
478
479 struct net_registry_increment_state {
480         const char *keyname;
481         const char *valuename;
482         uint32_t increment;
483         uint32_t newvalue;
484         WERROR werr;
485 };
486
487 static void net_registry_increment_fn(void *private_data)
488 {
489         struct net_registry_increment_state *state =
490                 (struct net_registry_increment_state *)private_data;
491         struct registry_value *value;
492         struct registry_key *key = NULL;
493         uint32_t v;
494
495         state->werr = open_key(talloc_tos(), state->keyname,
496                                REG_KEY_READ|REG_KEY_WRITE, &key);
497         if (!W_ERROR_IS_OK(state->werr)) {
498                 d_fprintf(stderr, _("open_key failed: %s\n"),
499                           win_errstr(state->werr));
500                 goto done;
501         }
502
503         state->werr = reg_queryvalue(key, key, state->valuename, &value);
504         if (!W_ERROR_IS_OK(state->werr)) {
505                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
506                           win_errstr(state->werr));
507                 goto done;
508         }
509
510         if (value->type != REG_DWORD) {
511                 d_fprintf(stderr, _("value not a DWORD: %s\n"),
512                           str_regtype(value->type));
513                 goto done;
514         }
515
516         if (value->data.length < 4) {
517                 d_fprintf(stderr, _("value too short for regular DWORD\n"));
518                 goto done;
519         }
520
521         v = IVAL(value->data.data, 0);
522         v += state->increment;
523         state->newvalue = v;
524
525         SIVAL(value->data.data, 0, v);
526
527         state->werr = reg_setvalue(key, state->valuename, value);
528         if (!W_ERROR_IS_OK(state->werr)) {
529                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
530                           win_errstr(state->werr));
531                 goto done;
532         }
533
534 done:
535         TALLOC_FREE(key);
536         return;
537 }
538
539 static int net_registry_increment(struct net_context *c, int argc,
540                                   const char **argv)
541 {
542         struct net_registry_increment_state state;
543         NTSTATUS status;
544         int ret = -1;
545
546         if (argc < 2 || c->display_usage) {
547                 d_fprintf(stderr, "%s\n%s",
548                           _("Usage:"),
549                           _("net registry increment <key> <valuename> "
550                             "[<increment>]\n"));
551                 goto done;
552         }
553
554         state.keyname = argv[0];
555         state.valuename = argv[1];
556
557         state.increment = 1;
558         if (argc == 3) {
559                 state.increment = strtoul(argv[2], NULL, 10);
560         }
561
562         status = g_lock_do("registry_increment_lock", G_LOCK_WRITE,
563                            timeval_set(600, 0), procid_self(),
564                            net_registry_increment_fn, &state);
565         if (!NT_STATUS_IS_OK(status)) {
566                 d_fprintf(stderr, _("g_lock_do failed: %s\n"),
567                           nt_errstr(status));
568                 goto done;
569         }
570         if (!W_ERROR_IS_OK(state.werr)) {
571                 d_fprintf(stderr, _("increment failed: %s\n"),
572                           win_errstr(state.werr));
573                 goto done;
574         }
575
576         d_printf(_("%u\n"), (unsigned)state.newvalue);
577
578         ret = 0;
579
580 done:
581         return ret;
582 }
583
584 static int net_registry_deletevalue(struct net_context *c, int argc,
585                                     const char **argv)
586 {
587         WERROR werr;
588         struct registry_key *key = NULL;
589         TALLOC_CTX *ctx = talloc_stackframe();
590         int ret = -1;
591
592         if (argc != 2 || c->display_usage) {
593                 d_fprintf(stderr, "%s\n%s",
594                           _("Usage:"),
595                           _("net registry deletevalue <key> <valuename>\n"));
596                 goto done;
597         }
598
599         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
600         if (!W_ERROR_IS_OK(werr)) {
601                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
602                 goto done;
603         }
604
605         werr = reg_deletevalue(key, argv[1]);
606         if (!W_ERROR_IS_OK(werr)) {
607                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
608                           win_errstr(werr));
609                 goto done;
610         }
611
612         ret = 0;
613
614 done:
615         TALLOC_FREE(ctx);
616         return ret;
617 }
618
619 static WERROR net_registry_getsd_internal(struct net_context *c,
620                                           TALLOC_CTX *mem_ctx,
621                                           const char *keyname,
622                                           struct security_descriptor **sd)
623 {
624         WERROR werr;
625         struct registry_key *key = NULL;
626         TALLOC_CTX *ctx = talloc_stackframe();
627         uint32_t access_mask = REG_KEY_READ |
628                                SEC_FLAG_MAXIMUM_ALLOWED |
629                                SEC_FLAG_SYSTEM_SECURITY;
630
631         /*
632          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
633          * is denied with these perms right now...
634          */
635         access_mask = REG_KEY_READ;
636
637         if (sd == NULL) {
638                 d_fprintf(stderr, _("internal error: invalid argument\n"));
639                 werr = WERR_INVALID_PARAM;
640                 goto done;
641         }
642
643         if (strlen(keyname) == 0) {
644                 d_fprintf(stderr, _("error: zero length key name given\n"));
645                 werr = WERR_INVALID_PARAM;
646                 goto done;
647         }
648
649         werr = open_key(ctx, keyname, access_mask, &key);
650         if (!W_ERROR_IS_OK(werr)) {
651                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
652                           win_errstr(werr));
653                 goto done;
654         }
655
656         werr = reg_getkeysecurity(mem_ctx, key, sd);
657         if (!W_ERROR_IS_OK(werr)) {
658                 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
659                           win_errstr(werr));
660                 goto done;
661         }
662
663         werr = WERR_OK;
664
665 done:
666         TALLOC_FREE(ctx);
667         return werr;
668 }
669
670 static int net_registry_getsd(struct net_context *c, int argc,
671                               const char **argv)
672 {
673         WERROR werr;
674         int ret = -1;
675         struct security_descriptor *secdesc = NULL;
676         TALLOC_CTX *ctx = talloc_stackframe();
677
678         if (argc != 1 || c->display_usage) {
679                 d_printf("%s\n%s",
680                          _("Usage:"),
681                          _("net registry getsd <path>\n"));
682                 d_printf("%s\n%s",
683                          _("Example:"),
684                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
685                 goto done;
686         }
687
688         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
689         if (!W_ERROR_IS_OK(werr)) {
690                 goto done;
691         }
692
693         display_sec_desc(secdesc);
694
695         ret = 0;
696
697 done:
698         TALLOC_FREE(ctx);
699         return ret;
700 }
701
702 static int net_registry_getsd_sddl(struct net_context *c,
703                                    int argc, const char **argv)
704 {
705         WERROR werr;
706         int ret = -1;
707         struct security_descriptor *secdesc = NULL;
708         TALLOC_CTX *ctx = talloc_stackframe();
709
710         if (argc != 1 || c->display_usage) {
711                 d_printf("%s\n%s",
712                          _("Usage:"),
713                          _("net registry getsd_sddl <path>\n"));
714                 d_printf("%s\n%s",
715                          _("Example:"),
716                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
717                 goto done;
718         }
719
720         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
721         if (!W_ERROR_IS_OK(werr)) {
722                 goto done;
723         }
724
725         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
726
727         ret = 0;
728
729 done:
730         TALLOC_FREE(ctx);
731         return ret;
732 }
733
734 static WERROR net_registry_setsd_internal(struct net_context *c,
735                                           TALLOC_CTX *mem_ctx,
736                                           const char *keyname,
737                                           struct security_descriptor *sd)
738 {
739         WERROR werr;
740         struct registry_key *key = NULL;
741         TALLOC_CTX *ctx = talloc_stackframe();
742         uint32_t access_mask = REG_KEY_WRITE |
743                                SEC_FLAG_MAXIMUM_ALLOWED |
744                                SEC_FLAG_SYSTEM_SECURITY;
745
746         /*
747          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
748          * is denied with these perms right now...
749          */
750         access_mask = REG_KEY_WRITE;
751
752         if (strlen(keyname) == 0) {
753                 d_fprintf(stderr, _("error: zero length key name given\n"));
754                 werr = WERR_INVALID_PARAM;
755                 goto done;
756         }
757
758         werr = open_key(ctx, keyname, access_mask, &key);
759         if (!W_ERROR_IS_OK(werr)) {
760                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
761                           win_errstr(werr));
762                 goto done;
763         }
764
765         werr = reg_setkeysecurity(key, sd);
766         if (!W_ERROR_IS_OK(werr)) {
767                 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
768                           win_errstr(werr));
769                 goto done;
770         }
771
772         werr = WERR_OK;
773
774 done:
775         TALLOC_FREE(ctx);
776         return werr;
777 }
778
779 static int net_registry_setsd_sddl(struct net_context *c,
780                                    int argc, const char **argv)
781 {
782         WERROR werr;
783         int ret = -1;
784         struct security_descriptor *secdesc = NULL;
785         TALLOC_CTX *ctx = talloc_stackframe();
786
787         if (argc != 2 || c->display_usage) {
788                 d_printf("%s\n%s",
789                          _("Usage:"),
790                          _("net registry setsd_sddl <path> <security_descriptor>\n"));
791                 d_printf("%s\n%s",
792                          _("Example:"),
793                          _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
794                 goto done;
795         }
796
797         secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
798         if (secdesc == NULL) {
799                 goto done;
800         }
801
802         werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
803         if (!W_ERROR_IS_OK(werr)) {
804                 goto done;
805         }
806
807         ret = 0;
808
809 done:
810         TALLOC_FREE(ctx);
811         return ret;
812 }
813
814 /******************************************************************************/
815 /**
816  * @defgroup net_registry net registry
817  */
818
819 /**
820  * @defgroup net_registry_import Import
821  * @ingroup net_registry
822  * @{
823  */
824
825 struct import_ctx {
826         TALLOC_CTX *mem_ctx;
827 };
828
829
830 static WERROR import_create_key(struct import_ctx* ctx,
831                                 struct registry_key* parent,
832                                 const char* name, void** pkey, bool* existing)
833 {
834         WERROR werr;
835         void* mem_ctx = talloc_new(ctx->mem_ctx);
836
837         struct registry_key* key = NULL;
838         enum winreg_CreateAction action;
839
840         if (parent == NULL) {
841                 char* subkeyname = NULL;
842                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
843                          &parent, &subkeyname);
844                 if (!W_ERROR_IS_OK(werr)) {
845                         d_fprintf(stderr, _("open_hive failed: %s\n"),
846                                   win_errstr(werr));
847                         goto done;
848                 }
849                 name = subkeyname;
850         }
851
852         action = REG_ACTION_NONE;
853         werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
854                              &key, &action);
855         if (!W_ERROR_IS_OK(werr)) {
856                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
857                           win_errstr(werr));
858                 goto done;
859         }
860
861         if (action == REG_ACTION_NONE) {
862                 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
863                 werr = WERR_CREATE_FAILED;
864                 goto done;
865         }
866
867         if (existing != NULL) {
868                 *existing = (action == REG_OPENED_EXISTING_KEY);
869         }
870
871         if (pkey!=NULL) {
872                 *pkey = talloc_steal(ctx->mem_ctx, key);
873         }
874
875 done:
876         talloc_free(mem_ctx);
877         return werr;
878 }
879
880 static WERROR import_close_key(struct import_ctx* ctx,
881                                struct registry_key* key)
882 {
883         return WERR_OK;
884 }
885
886 static WERROR import_delete_key(struct import_ctx* ctx,
887                                 struct registry_key* parent, const char* name)
888 {
889         WERROR werr;
890         void* mem_ctx = talloc_new(talloc_tos());
891
892         if (parent == NULL) {
893                 char* subkeyname = NULL;
894                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
895                          &parent, &subkeyname);
896                 if (!W_ERROR_IS_OK(werr)) {
897                         d_fprintf(stderr, _("open_hive failed: %s\n"),
898                                   win_errstr(werr));
899                         goto done;
900                 }
901                 name = subkeyname;
902         }
903
904         werr = reg_deletekey_recursive(parent, name);
905         if (!W_ERROR_IS_OK(werr)) {
906                 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n", _("failed"),
907                           win_errstr(werr));
908                 goto done;
909         }
910
911 done:
912         talloc_free(mem_ctx);
913         return werr;
914 }
915
916 static WERROR import_create_val (struct import_ctx* ctx,
917                                  struct registry_key* parent, const char* name,
918                                  const struct registry_value* value)
919 {
920         WERROR werr;
921
922         if (parent == NULL) {
923                 return WERR_INVALID_PARAM;
924         }
925
926         werr = reg_setvalue(parent, name, value);
927         if (!W_ERROR_IS_OK(werr)) {
928                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
929                           win_errstr(werr));
930         }
931         return werr;
932 }
933
934 static WERROR import_delete_val (struct import_ctx* ctx, struct registry_key* parent, const char* name) {
935         WERROR werr;
936
937         if (parent == NULL) {
938                 return WERR_INVALID_PARAM;
939         }
940
941         werr = reg_deletevalue(parent, name);
942         if (!W_ERROR_IS_OK(werr)) {
943                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
944                           win_errstr(werr));
945         }
946
947         return werr;
948 }
949
950
951 static int net_registry_import(struct net_context *c, int argc,
952                                const char **argv)
953 {
954         struct import_ctx import_ctx;
955         struct reg_import_callback import_callback = {
956                 .openkey     = NULL,
957                 .closekey    = (reg_import_callback_closekey_t)&import_close_key,
958                 .createkey   = (reg_import_callback_createkey_t)&import_create_key,
959                 .deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
960                 .deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
961                 .setval.registry_value = (reg_import_callback_setval_registry_value_t)
962                 &import_create_val,
963                 .setval_type           = REGISTRY_VALUE,
964                 .data        = &import_ctx
965         };
966
967         int ret;
968
969         if (argc < 1 || argc > 2 || c->display_usage) {
970                 d_printf("%s\n%s",
971                          _("Usage:"),
972                          _("net registry import <reg> [options]\n"));
973                 d_printf("%s\n%s",
974                          _("Example:"),
975                          _("net registry import file.reg enc=CP1252\n"));
976                 return -1;
977         }
978
979         ZERO_STRUCT(import_ctx);
980         import_ctx.mem_ctx = talloc_stackframe();
981
982         regdb_open();
983         regdb_transaction_start();
984
985         ret = reg_parse_file(argv[0],
986                              reg_import_adapter(import_ctx.mem_ctx,
987                                                 import_callback),
988                              (argc > 1) ? argv[1] : NULL
989                 );
990         if (ret < 0) {
991                 d_printf("reg_parse_file failed: transaction canceled\n");
992                 regdb_transaction_cancel();
993         } else{
994                 regdb_transaction_commit();
995         }
996
997         regdb_close();
998         talloc_free(import_ctx.mem_ctx);
999
1000         return ret;
1001 }
1002 /**@}*/
1003
1004 /******************************************************************************/
1005
1006 /**
1007  * @defgroup net_registry_export Export
1008  * @ingroup net_registry
1009  * @{
1010  */
1011
1012 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key* key,
1013                            struct reg_format* f)
1014 {
1015         int ret=-1;
1016         WERROR werr;
1017         uint32_t count;
1018
1019         struct registry_value *valvalue = NULL;
1020         char *valname = NULL;
1021
1022         struct registry_key* subkey = NULL;
1023         char *subkey_name = NULL;
1024         NTTIME modtime = 0;
1025
1026         reg_format_registry_key(f, key, false);
1027
1028         /* print values */
1029         for (count = 0;
1030              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1031                      W_ERROR_IS_OK(werr);
1032              count++)
1033         {
1034                 reg_format_registry_value(f, valname, valvalue);
1035         }
1036         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1037                 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1038                           win_errstr(werr));
1039                 goto done;
1040         }
1041
1042         /* recurse on subkeys */
1043         for (count = 0;
1044              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1045                      W_ERROR_IS_OK(werr);
1046              count++)
1047         {
1048                 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1049                                    &subkey);
1050                 if (!W_ERROR_IS_OK(werr)) {
1051                         d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1052                                   win_errstr(werr));
1053                         goto done;
1054                 }
1055
1056                 registry_export(ctx, subkey, f);
1057         }
1058         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1059                 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1060                           win_errstr(werr));
1061                 goto done;
1062         }
1063         ret = 0;
1064 done:
1065         return ret;
1066 }
1067
1068 static int net_registry_export(struct net_context *c, int argc,
1069                                const char **argv)
1070 {
1071         int ret=-1;
1072         WERROR werr;
1073         struct registry_key *key = NULL;
1074         TALLOC_CTX *ctx = talloc_stackframe();
1075         struct reg_format* f=NULL;
1076
1077         if (argc < 2 || argc > 3 || c->display_usage) {
1078                 d_printf("%s\n%s",
1079                          _("Usage:"),
1080                          _("net registry export <path> <file> [opt]\n"));
1081                 d_printf("%s\n%s",
1082                          _("Example:"),
1083                          _("net registry export 'HKLM\\Software\\Samba' "
1084                            "samba.reg regedit5\n"));
1085                 goto done;
1086         }
1087
1088         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1089         if (!W_ERROR_IS_OK(werr)) {
1090                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1091                 goto done;
1092         }
1093
1094         f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1095         if (f == NULL) {
1096                 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1097                 goto done;
1098         }
1099
1100         ret = registry_export(ctx, key, f);
1101
1102 done:
1103         TALLOC_FREE(ctx);
1104         return ret;
1105 }
1106 /**@}*/
1107
1108 /******************************************************************************/
1109 /**
1110  * @defgroup net_registry_convert Convert
1111  * @ingroup net_registry
1112  * @{
1113  */
1114
1115 static int net_registry_convert(struct net_context *c, int argc,
1116                                const char **argv)
1117 {
1118         int ret;
1119         void* mem_ctx;
1120         const char* in_opt  = NULL;
1121         const char* out_opt = NULL;
1122
1123         if (argc < 2 || argc > 4|| c->display_usage) {
1124                 d_printf("%s\n%s",
1125                          _("Usage:"),
1126                          _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1127                            "net registry convert <in> <out> [out_opt]\n"));
1128                 d_printf("%s\n%s",
1129                          _("Example:"),
1130                          _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1131                 return -1;
1132         }
1133
1134         mem_ctx = talloc_stackframe();
1135
1136         switch (argc ) {
1137         case 2:
1138                 break;
1139         case 3:
1140                 out_opt = argv[2];
1141                 break;
1142         case 4:
1143                 out_opt = argv[3];
1144                 in_opt  = argv[2];
1145                 break;
1146         default:
1147                 assert(false);
1148         }
1149
1150
1151         ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1152                              reg_format_file(mem_ctx, argv[1], out_opt),
1153                              in_opt);
1154
1155         talloc_free(mem_ctx);
1156
1157         return ret;
1158 }
1159 /**@}*/
1160
1161 /******************************************************************************/
1162
1163 int net_registry(struct net_context *c, int argc, const char **argv)
1164 {
1165         int ret = -1;
1166
1167         struct functable func[] = {
1168                 {
1169                         "enumerate",
1170                         net_registry_enumerate,
1171                         NET_TRANSPORT_LOCAL,
1172                         N_("Enumerate registry keys and values"),
1173                         N_("net registry enumerate\n"
1174                            "    Enumerate registry keys and values")
1175                 },
1176                 {
1177                         "createkey",
1178                         net_registry_createkey,
1179                         NET_TRANSPORT_LOCAL,
1180                         N_("Create a new registry key"),
1181                         N_("net registry createkey\n"
1182                            "    Create a new registry key")
1183                 },
1184                 {
1185                         "deletekey",
1186                         net_registry_deletekey,
1187                         NET_TRANSPORT_LOCAL,
1188                         N_("Delete a registry key"),
1189                         N_("net registry deletekey\n"
1190                            "    Delete a registry key")
1191                 },
1192                 {
1193                         "deletekey_recursive",
1194                         net_registry_deletekey_recursive,
1195                         NET_TRANSPORT_LOCAL,
1196                         N_("Delete a registry key with subkeys"),
1197                         N_("net registry deletekey_recursive\n"
1198                            "    Delete a registry key with subkeys")
1199                 },
1200                 {
1201                         "getvalue",
1202                         net_registry_getvalue,
1203                         NET_TRANSPORT_LOCAL,
1204                         N_("Print a registry value"),
1205                         N_("net registry getvalue\n"
1206                            "    Print a registry value")
1207                 },
1208                 {
1209                         "getvalueraw",
1210                         net_registry_getvalueraw,
1211                         NET_TRANSPORT_LOCAL,
1212                         N_("Print a registry value (raw format)"),
1213                         N_("net registry getvalueraw\n"
1214                            "    Print a registry value (raw format)")
1215                 },
1216                 {
1217                         "getvaluesraw",
1218                         net_registry_getvaluesraw,
1219                         NET_TRANSPORT_LOCAL,
1220                         "Print all values of a key in raw format",
1221                         "net registry getvaluesraw <key>\n"
1222                         "    Print a registry value (raw format)"
1223                 },
1224                 {
1225                         "setvalue",
1226                         net_registry_setvalue,
1227                         NET_TRANSPORT_LOCAL,
1228                         N_("Set a new registry value"),
1229                         N_("net registry setvalue\n"
1230                            "    Set a new registry value")
1231                 },
1232                 {
1233                         "increment",
1234                         net_registry_increment,
1235                         NET_TRANSPORT_LOCAL,
1236                         N_("Increment a DWORD registry value under a lock"),
1237                         N_("net registry increment\n"
1238                            "    Increment a DWORD registry value under a lock")
1239                 },
1240                 {
1241                         "deletevalue",
1242                         net_registry_deletevalue,
1243                         NET_TRANSPORT_LOCAL,
1244                         N_("Delete a registry value"),
1245                         N_("net registry deletevalue\n"
1246                            "    Delete a registry value")
1247                 },
1248                 {
1249                         "getsd",
1250                         net_registry_getsd,
1251                         NET_TRANSPORT_LOCAL,
1252                         N_("Get security descriptor"),
1253                         N_("net registry getsd\n"
1254                            "    Get security descriptor")
1255                 },
1256                 {
1257                         "getsd_sddl",
1258                         net_registry_getsd_sddl,
1259                         NET_TRANSPORT_LOCAL,
1260                         N_("Get security descriptor in sddl format"),
1261                         N_("net registry getsd_sddl\n"
1262                            "    Get security descriptor in sddl format")
1263                 },
1264                 {
1265                         "setsd_sddl",
1266                         net_registry_setsd_sddl,
1267                         NET_TRANSPORT_LOCAL,
1268                         N_("Set security descriptor from sddl format string"),
1269                         N_("net registry setsd_sddl\n"
1270                            "    Set security descriptor from sddl format string")
1271                 },
1272                 {
1273                         "import",
1274                         net_registry_import,
1275                         NET_TRANSPORT_LOCAL,
1276                         N_("Import .reg file"),
1277                         N_("net registry import\n"
1278                            "    Import .reg file")
1279                 },
1280                 {
1281                         "export",
1282                         net_registry_export,
1283                         NET_TRANSPORT_LOCAL,
1284                         N_("Export .reg file"),
1285                         N_("net registry export\n"
1286                            "    Export .reg file")
1287                 },
1288                 {
1289                         "convert",
1290                         net_registry_convert,
1291                         NET_TRANSPORT_LOCAL,
1292                         N_("Convert .reg file"),
1293                         N_("net registry convert\n"
1294                            "    Convert .reg file")
1295                 },
1296         { NULL, NULL, 0, NULL, NULL }
1297         };
1298
1299         if (!W_ERROR_IS_OK(registry_init_basic())) {
1300                 return -1;
1301         }
1302
1303         ret = net_run_function(c, argc, argv, "net registry", func);
1304
1305         return ret;
1306 }