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