lib: relicense smb_strtoul(l) under LGPLv3
[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 "registry/reg_api_util.h"
34 #include <assert.h>
35 #include "../libcli/security/display_sec.h"
36 #include "../libcli/security/sddl.h"
37 #include "../libcli/registry/util_reg.h"
38 #include "passdb/machine_sid.h"
39 #include "net_registry_check.h"
40 #include "lib/util/util_tdb.h"
41 #include "lib/util/smb_strtox.h"
42
43 /*
44  *
45  * Helper functions
46  *
47  */
48
49 /**
50  * split given path into hive and remaining path and open the hive key
51  */
52 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
53                         uint32_t desired_access,
54                         struct registry_key **hive,
55                         char **subkeyname)
56 {
57         WERROR werr;
58         struct security_token *token = NULL;
59         char *hivename = NULL;
60         char *tmp_subkeyname = NULL;
61         TALLOC_CTX *tmp_ctx = talloc_stackframe();
62
63         if ((hive == NULL) || (subkeyname == NULL)) {
64                 werr = WERR_INVALID_PARAMETER;
65                 goto done;
66         }
67
68         werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
69         if (!W_ERROR_IS_OK(werr)) {
70                 goto done;
71         }
72         *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
73         if (*subkeyname == NULL) {
74                 werr = WERR_NOT_ENOUGH_MEMORY;
75                 goto done;
76         }
77
78         werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
79         if (!W_ERROR_IS_OK(werr)) {
80                 goto done;
81         }
82
83         werr = reg_openhive(ctx, hivename, desired_access, token, hive);
84         if (!W_ERROR_IS_OK(werr)) {
85                 goto done;
86         }
87
88         werr = WERR_OK;
89
90 done:
91         TALLOC_FREE(tmp_ctx);
92         return werr;
93 }
94
95 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
96                        uint32_t desired_access,
97                        struct registry_key **key)
98 {
99         WERROR werr;
100         char *subkey_name = NULL;
101         struct registry_key *hive = NULL;
102         TALLOC_CTX *tmp_ctx = talloc_stackframe();
103
104         if ((path == NULL) || (key == NULL)) {
105                 return WERR_INVALID_PARAMETER;
106         }
107
108         werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
109         if (!W_ERROR_IS_OK(werr)) {
110                 d_fprintf(stderr, _("open_hive failed: %s\n"),
111                           win_errstr(werr));
112                 goto done;
113         }
114
115         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
116         if (!W_ERROR_IS_OK(werr)) {
117                 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
118                           win_errstr(werr));
119                 goto done;
120         }
121
122         werr = WERR_OK;
123
124 done:
125         TALLOC_FREE(tmp_ctx);
126         return werr;
127 }
128
129 static WERROR registry_enumkey(struct registry_key *parent, const char *keyname,
130                                bool recursive)
131 {
132         WERROR werr;
133         TALLOC_CTX *ctx = talloc_stackframe();
134         char *subkey_name;
135         NTTIME modtime;
136         uint32_t count;
137         char *valname = NULL;
138         struct registry_value *valvalue = NULL;
139         struct registry_key *key = NULL;
140
141         werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
142         if (!W_ERROR_IS_OK(werr)) {
143                 goto done;
144         }
145
146         if (recursive) {
147                 printf("[%s]\n\n", key->key->name);
148         } else {
149                 for (count = 0;
150                      werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
151                      W_ERROR_IS_OK(werr);
152                      count++)
153                 {
154                         print_registry_key(subkey_name, &modtime);
155                 }
156                 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
157                         goto done;
158                 }
159         }
160
161         for (count = 0;
162              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
163              W_ERROR_IS_OK(werr);
164              count++)
165         {
166                 print_registry_value_with_name(valname, valvalue);
167         }
168         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
169                 goto done;
170         }
171
172         if (!recursive) {
173                 werr = WERR_OK;
174                 goto done;
175         }
176
177         for (count = 0;
178              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
179              W_ERROR_IS_OK(werr);
180              count++)
181         {
182                 werr = registry_enumkey(key, subkey_name, recursive);
183                 if (!W_ERROR_IS_OK(werr)) {
184                         goto done;
185                 }
186         }
187         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
188                 goto done;
189         }
190
191         werr = WERR_OK;
192
193 done:
194         TALLOC_FREE(ctx);
195         return werr;
196 }
197
198
199
200 /*
201  *
202  * the main "net registry" function implementations
203  *
204  */
205 static int net_registry_enumerate(struct net_context *c, int argc,
206                                   const char **argv)
207 {
208         WERROR werr;
209         struct registry_key *key = NULL;
210         char *name = NULL;
211         TALLOC_CTX *ctx = talloc_stackframe();
212         int ret = -1;
213
214         if (argc != 1 || c->display_usage) {
215                 d_printf("%s\n%s",
216                          _("Usage:"),
217                          _("net registry enumerate <path>\n"));
218                 d_printf("%s\n%s",
219                          _("Example:"),
220                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
221                 goto done;
222         }
223
224         werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
225         if (!W_ERROR_IS_OK(werr)) {
226                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
227                 goto done;
228         }
229
230         werr = registry_enumkey(key, name, c->opt_reboot);
231         if (W_ERROR_IS_OK(werr)) {
232                 ret = 0;
233         }
234 done:
235         TALLOC_FREE(ctx);
236         return ret;
237 }
238
239 static int net_registry_enumerate_recursive(struct net_context *c, int argc,
240                                             const char **argv)
241 {
242         WERROR werr;
243         struct registry_key *key = NULL;
244         char *name = NULL;
245         TALLOC_CTX *ctx = talloc_stackframe();
246         int ret = -1;
247
248         if (argc != 1 || c->display_usage) {
249                 d_printf("%s\n%s",
250                          _("Usage:"),
251                          _("net registry enumerate <path>\n"));
252                 d_printf("%s\n%s",
253                          _("Example:"),
254                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
255                 goto done;
256         }
257
258         werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
259         if (!W_ERROR_IS_OK(werr)) {
260                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
261                 goto done;
262         }
263
264         werr = registry_enumkey(key, name, true);
265         if (W_ERROR_IS_OK(werr)) {
266                 ret = 0;
267         }
268 done:
269         TALLOC_FREE(ctx);
270         return ret;
271 }
272
273
274 static int net_registry_createkey(struct net_context *c, int argc,
275                                   const char **argv)
276 {
277         WERROR werr;
278         enum winreg_CreateAction action;
279         char *subkeyname = NULL;
280         struct registry_key *hivekey = NULL;
281         struct registry_key *subkey = NULL;
282         TALLOC_CTX *ctx = talloc_stackframe();
283         int ret = -1;
284
285         if (argc != 1 || c->display_usage) {
286                 d_printf("%s\n%s",
287                          _("Usage:"),
288                          _("net registry createkey <path>\n"));
289                 d_printf("%s\n%s",
290                          _("Example:"),
291                          _("net registry createkey "
292                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
293                 goto done;
294         }
295         if (strlen(argv[0]) == 0) {
296                 d_fprintf(stderr, _("error: zero length key name given\n"));
297                 goto done;
298         }
299
300         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
301         if (!W_ERROR_IS_OK(werr)) {
302                 d_fprintf(stderr, _("open_hive failed: %s\n"),
303                           win_errstr(werr));
304                 goto done;
305         }
306
307         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
308                              &subkey, &action);
309         if (!W_ERROR_IS_OK(werr)) {
310                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
311                           win_errstr(werr));
312                 goto done;
313         }
314         switch (action) {
315                 case REG_ACTION_NONE:
316                         d_printf(_("createkey did nothing -- huh?\n"));
317                         break;
318                 case REG_CREATED_NEW_KEY:
319                         d_printf(_("createkey created %s\n"), argv[0]);
320                         break;
321                 case REG_OPENED_EXISTING_KEY:
322                         d_printf(_("createkey opened existing %s\n"), argv[0]);
323                         break;
324         }
325
326         ret = 0;
327
328 done:
329         TALLOC_FREE(ctx);
330         return ret;
331 }
332
333 static int net_registry_deletekey_internal(struct net_context *c, int argc,
334                                            const char **argv,
335                                            bool recursive)
336 {
337         WERROR werr;
338         char *subkeyname = NULL;
339         struct registry_key *hivekey = NULL;
340         TALLOC_CTX *ctx = talloc_stackframe();
341         int ret = -1;
342
343         if (argc != 1 || c->display_usage) {
344                 d_printf("%s\n%s",
345                          _("Usage:"),
346                          _("net registry deletekey <path>\n"));
347                 d_printf("%s\n%s",
348                          _("Example:"),
349                          _("net registry deletekey "
350                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
351                 goto done;
352         }
353         if (strlen(argv[0]) == 0) {
354                 d_fprintf(stderr, _("error: zero length key name given\n"));
355                 goto done;
356         }
357
358         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
359         if (!W_ERROR_IS_OK(werr)) {
360                 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
361                           win_errstr(werr));
362                 goto done;
363         }
364
365         if (recursive) {
366                 werr = reg_deletekey_recursive(hivekey, subkeyname);
367         } else {
368                 werr = reg_deletekey(hivekey, subkeyname);
369         }
370         if (!W_ERROR_IS_OK(werr) &&
371             !(c->opt_force && W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)))
372         {
373                 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
374                           win_errstr(werr));
375                 goto done;
376         }
377
378         ret = 0;
379
380 done:
381         TALLOC_FREE(ctx);
382         return ret;
383 }
384
385 static int net_registry_deletekey(struct net_context *c, int argc,
386                                   const char **argv)
387 {
388         return net_registry_deletekey_internal(c, argc, argv, false);
389 }
390
391 static int net_registry_deletekey_recursive(struct net_context *c, int argc,
392                                             const char **argv)
393 {
394         return net_registry_deletekey_internal(c, argc, argv, true);
395 }
396
397 static int net_registry_getvalue_internal(struct net_context *c, int argc,
398                                           const char **argv, bool raw)
399 {
400         WERROR werr;
401         int ret = -1;
402         struct registry_key *key = NULL;
403         struct registry_value *value = NULL;
404         TALLOC_CTX *ctx = talloc_stackframe();
405
406         if (argc != 2 || c->display_usage) {
407                 d_fprintf(stderr, "%s\n%s",
408                           _("Usage:"),
409                           _("net registry getvalue <key> <valuename>\n"));
410                 goto done;
411         }
412
413         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
414         if (!W_ERROR_IS_OK(werr)) {
415                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
416                 goto done;
417         }
418
419         werr = reg_queryvalue(ctx, key, argv[1], &value);
420         if (!W_ERROR_IS_OK(werr)) {
421                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
422                           win_errstr(werr));
423                 goto done;
424         }
425
426         print_registry_value(value, raw);
427
428         ret = 0;
429
430 done:
431         TALLOC_FREE(ctx);
432         return ret;
433 }
434
435 static int net_registry_getvalue(struct net_context *c, int argc,
436                                  const char **argv)
437 {
438         return net_registry_getvalue_internal(c, argc, argv, false);
439 }
440
441 static int net_registry_getvalueraw(struct net_context *c, int argc,
442                                     const char **argv)
443 {
444         return net_registry_getvalue_internal(c, argc, argv, true);
445 }
446
447 static int net_registry_getvaluesraw(struct net_context *c, int argc,
448                                      const char **argv)
449 {
450         WERROR werr;
451         int ret = -1;
452         struct registry_key *key = NULL;
453         TALLOC_CTX *ctx = talloc_stackframe();
454         uint32_t idx;
455
456         if (argc != 1 || c->display_usage) {
457                 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
458                           "<key>\n");
459                 goto done;
460         }
461
462         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
463         if (!W_ERROR_IS_OK(werr)) {
464                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
465                 goto done;
466         }
467
468         idx = 0;
469         while (true) {
470                 struct registry_value *val;
471
472                 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
473
474                 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
475                         ret = 0;
476                         break;
477                 }
478                 if (!W_ERROR_IS_OK(werr)) {
479                         break;
480                 }
481                 print_registry_value(val, true);
482                 TALLOC_FREE(val);
483                 idx += 1;
484         }
485 done:
486         TALLOC_FREE(ctx);
487         return ret;
488 }
489
490 static int net_registry_setvalue(struct net_context *c, int argc,
491                                  const char **argv)
492 {
493         WERROR werr;
494         struct registry_value value;
495         struct registry_key *key = NULL;
496         int ret = -1;
497         TALLOC_CTX *ctx = talloc_stackframe();
498
499         if (argc < 4 || c->display_usage) {
500                 d_fprintf(stderr, "%s\n%s",
501                           _("Usage:"),
502                           _("net registry setvalue <key> <valuename> "
503                             "<type> [<val>]+\n"));
504                 goto done;
505         }
506
507         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
508                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
509                 goto done;
510         }
511
512         if (strequal(argv[2], "dword")) {
513                 int error = 0;
514                 uint32_t v;
515
516                 v = smb_strtoul(argv[3], NULL, 10, &error, SMB_STR_STANDARD);
517                 if (error != 0) {
518                         goto done;
519                 }
520
521                 value.type = REG_DWORD;
522                 value.data = data_blob_talloc(ctx, NULL, 4);
523                 SIVAL(value.data.data, 0, v);
524         } else if (strequal(argv[2], "sz")) {
525                 value.type = REG_SZ;
526                 if (!push_reg_sz(ctx, &value.data, argv[3])) {
527                         goto done;
528                 }
529         } else if (strequal(argv[2], "multi_sz")) {
530                 const char **array;
531                 int count = argc - 3;
532                 int i;
533                 value.type = REG_MULTI_SZ;
534                 array = talloc_zero_array(ctx, const char *, count + 1);
535                 if (array == NULL) {
536                         goto done;
537                 }
538                 for (i=0; i < count; i++) {
539                         array[i] = talloc_strdup(array, argv[count+i]);
540                         if (array[i] == NULL) {
541                                 goto done;
542                         }
543                 }
544                 if (!push_reg_multi_sz(ctx, &value.data, array)) {
545                         goto done;
546                 }
547         } else {
548                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
549                 goto done;
550         }
551
552         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
553         if (!W_ERROR_IS_OK(werr)) {
554                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
555                 goto done;
556         }
557
558         werr = reg_setvalue(key, argv[1], &value);
559         if (!W_ERROR_IS_OK(werr)) {
560                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
561                           win_errstr(werr));
562                 goto done;
563         }
564
565         ret = 0;
566
567 done:
568         TALLOC_FREE(ctx);
569         return ret;
570 }
571
572 static int net_registry_increment(struct net_context *c, int argc,
573                                   const char **argv)
574 {
575         TDB_DATA lock_key = string_term_tdb_data("registry_increment_lock");
576         struct g_lock_ctx *ctx = NULL;
577         const char *keyname = NULL;
578         struct registry_key *key = NULL;
579         const char *valuename = NULL;
580         struct registry_value *value = NULL;
581         uint32_t v;
582         uint32_t increment;
583         uint32_t newvalue;
584         NTSTATUS status;
585         WERROR werr;
586         int ret = -1;
587
588         if (argc < 2 || c->display_usage) {
589                 d_fprintf(stderr, "%s\n%s",
590                           _("Usage:"),
591                           _("net registry increment <key> <valuename> "
592                             "[<increment>]\n"));
593                 goto done;
594         }
595
596         keyname = argv[0];
597         valuename = argv[1];
598
599         increment = 1;
600         if (argc == 3) {
601                 int error = 0;
602
603                 increment = smb_strtoul(
604                         argv[2], NULL, 10, &error, SMB_STR_STANDARD);
605                 if (error != 0) {
606                         goto done;
607                 }
608         }
609
610         ctx = g_lock_ctx_init(c, c->msg_ctx);
611         if (ctx == NULL) {
612                 d_fprintf(stderr, _("g_lock_ctx_init failed\n"));
613                 goto done;
614         }
615
616         status = g_lock_lock(ctx, lock_key, G_LOCK_WRITE, timeval_set(600, 0));
617         if (!NT_STATUS_IS_OK(status)) {
618                 d_fprintf(stderr, _("g_lock_lock failed: %s\n"),
619                           nt_errstr(status));
620                 goto done;
621         }
622
623         werr = open_key(c, keyname, REG_KEY_READ|REG_KEY_WRITE, &key);
624         if (!W_ERROR_IS_OK(werr)) {
625                 d_fprintf(stderr, _("open_key failed: %s\n"),
626                           win_errstr(werr));
627                 goto done;
628         }
629
630         werr = reg_queryvalue(key, key, valuename, &value);
631         if (!W_ERROR_IS_OK(werr)) {
632                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
633                           win_errstr(werr));
634                 goto done;
635         }
636
637         if (value->type != REG_DWORD) {
638                 d_fprintf(stderr, _("value not a DWORD: %s\n"),
639                           str_regtype(value->type));
640                 goto done;
641         }
642
643         if (value->data.length < 4) {
644                 d_fprintf(stderr, _("value too short for regular DWORD\n"));
645                 goto done;
646         }
647
648         v = IVAL(value->data.data, 0);
649         v += increment;
650         newvalue = v;
651
652         SIVAL(value->data.data, 0, v);
653
654         werr = reg_setvalue(key, valuename, value);
655         if (!W_ERROR_IS_OK(werr)) {
656                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
657                           win_errstr(werr));
658                 goto done;
659         }
660
661         if (!W_ERROR_IS_OK(werr)) {
662                 d_fprintf(stderr, _("increment failed: %s\n"),
663                           win_errstr(werr));
664                 goto done;
665         }
666
667         g_lock_unlock(ctx, lock_key);
668
669         d_printf(_("%"PRIu32"\n"), newvalue);
670
671         ret = 0;
672
673 done:
674         TALLOC_FREE(value);
675         TALLOC_FREE(key);
676         TALLOC_FREE(ctx);
677         return ret;
678 }
679
680 static int net_registry_deletevalue(struct net_context *c, int argc,
681                                     const char **argv)
682 {
683         WERROR werr;
684         struct registry_key *key = NULL;
685         TALLOC_CTX *ctx = talloc_stackframe();
686         int ret = -1;
687
688         if (argc != 2 || c->display_usage) {
689                 d_fprintf(stderr, "%s\n%s",
690                           _("Usage:"),
691                           _("net registry deletevalue <key> <valuename>\n"));
692                 goto done;
693         }
694
695         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
696         if (!W_ERROR_IS_OK(werr)) {
697                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
698                 goto done;
699         }
700
701         werr = reg_deletevalue(key, argv[1]);
702         if (!W_ERROR_IS_OK(werr)) {
703                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
704                           win_errstr(werr));
705                 goto done;
706         }
707
708         ret = 0;
709
710 done:
711         TALLOC_FREE(ctx);
712         return ret;
713 }
714
715 static WERROR net_registry_getsd_internal(struct net_context *c,
716                                           TALLOC_CTX *mem_ctx,
717                                           const char *keyname,
718                                           struct security_descriptor **sd)
719 {
720         WERROR werr;
721         struct registry_key *key = NULL;
722         TALLOC_CTX *ctx = talloc_stackframe();
723         uint32_t access_mask = REG_KEY_READ |
724                                SEC_FLAG_MAXIMUM_ALLOWED |
725                                SEC_FLAG_SYSTEM_SECURITY;
726
727         /*
728          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
729          * is denied with these perms right now...
730          */
731         access_mask = REG_KEY_READ;
732
733         if (sd == NULL) {
734                 d_fprintf(stderr, _("internal error: invalid argument\n"));
735                 werr = WERR_INVALID_PARAMETER;
736                 goto done;
737         }
738
739         if (strlen(keyname) == 0) {
740                 d_fprintf(stderr, _("error: zero length key name given\n"));
741                 werr = WERR_INVALID_PARAMETER;
742                 goto done;
743         }
744
745         werr = open_key(ctx, keyname, access_mask, &key);
746         if (!W_ERROR_IS_OK(werr)) {
747                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
748                           win_errstr(werr));
749                 goto done;
750         }
751
752         werr = reg_getkeysecurity(mem_ctx, key, sd);
753         if (!W_ERROR_IS_OK(werr)) {
754                 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
755                           win_errstr(werr));
756                 goto done;
757         }
758
759         werr = WERR_OK;
760
761 done:
762         TALLOC_FREE(ctx);
763         return werr;
764 }
765
766 static int net_registry_getsd(struct net_context *c, int argc,
767                               const char **argv)
768 {
769         WERROR werr;
770         int ret = -1;
771         struct security_descriptor *secdesc = NULL;
772         TALLOC_CTX *ctx = talloc_stackframe();
773
774         if (argc != 1 || c->display_usage) {
775                 d_printf("%s\n%s",
776                          _("Usage:"),
777                          _("net registry getsd <path>\n"));
778                 d_printf("%s\n%s",
779                          _("Example:"),
780                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
781                 goto done;
782         }
783
784         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
785         if (!W_ERROR_IS_OK(werr)) {
786                 goto done;
787         }
788
789         display_sec_desc(secdesc);
790
791         ret = 0;
792
793 done:
794         TALLOC_FREE(ctx);
795         return ret;
796 }
797
798 static int net_registry_getsd_sddl(struct net_context *c,
799                                    int argc, const char **argv)
800 {
801         WERROR werr;
802         int ret = -1;
803         struct security_descriptor *secdesc = NULL;
804         TALLOC_CTX *ctx = talloc_stackframe();
805
806         if (argc != 1 || c->display_usage) {
807                 d_printf("%s\n%s",
808                          _("Usage:"),
809                          _("net registry getsd_sddl <path>\n"));
810                 d_printf("%s\n%s",
811                          _("Example:"),
812                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
813                 goto done;
814         }
815
816         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
817         if (!W_ERROR_IS_OK(werr)) {
818                 goto done;
819         }
820
821         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
822
823         ret = 0;
824
825 done:
826         TALLOC_FREE(ctx);
827         return ret;
828 }
829
830 static WERROR net_registry_setsd_internal(struct net_context *c,
831                                           TALLOC_CTX *mem_ctx,
832                                           const char *keyname,
833                                           struct security_descriptor *sd)
834 {
835         WERROR werr;
836         struct registry_key *key = NULL;
837         TALLOC_CTX *ctx = talloc_stackframe();
838         uint32_t access_mask = REG_KEY_WRITE |
839                                SEC_FLAG_MAXIMUM_ALLOWED |
840                                SEC_FLAG_SYSTEM_SECURITY;
841
842         /*
843          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
844          * is denied with these perms right now...
845          */
846         access_mask = REG_KEY_WRITE;
847
848         if (strlen(keyname) == 0) {
849                 d_fprintf(stderr, _("error: zero length key name given\n"));
850                 werr = WERR_INVALID_PARAMETER;
851                 goto done;
852         }
853
854         werr = open_key(ctx, keyname, access_mask, &key);
855         if (!W_ERROR_IS_OK(werr)) {
856                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
857                           win_errstr(werr));
858                 goto done;
859         }
860
861         werr = reg_setkeysecurity(key, sd);
862         if (!W_ERROR_IS_OK(werr)) {
863                 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
864                           win_errstr(werr));
865                 goto done;
866         }
867
868         werr = WERR_OK;
869
870 done:
871         TALLOC_FREE(ctx);
872         return werr;
873 }
874
875 static int net_registry_setsd_sddl(struct net_context *c,
876                                    int argc, const char **argv)
877 {
878         WERROR werr;
879         int ret = -1;
880         struct security_descriptor *secdesc = NULL;
881         TALLOC_CTX *ctx = talloc_stackframe();
882
883         if (argc != 2 || c->display_usage) {
884                 d_printf("%s\n%s",
885                          _("Usage:"),
886                          _("net registry setsd_sddl <path> <security_descriptor>\n"));
887                 d_printf("%s\n%s",
888                          _("Example:"),
889                          _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
890                 goto done;
891         }
892
893         secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
894         if (secdesc == NULL) {
895                 goto done;
896         }
897
898         werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
899         if (!W_ERROR_IS_OK(werr)) {
900                 goto done;
901         }
902
903         ret = 0;
904
905 done:
906         TALLOC_FREE(ctx);
907         return ret;
908 }
909
910 /******************************************************************************/
911 /**
912  * @defgroup net_registry net registry
913  */
914
915 /**
916  * @defgroup net_registry_import Import
917  * @ingroup net_registry
918  * @{
919  */
920
921 struct import_ctx {
922         TALLOC_CTX *mem_ctx;
923 };
924
925
926 static WERROR import_create_key(struct import_ctx *ctx,
927                                 struct registry_key *parent,
928                                 const char *name, void **pkey, bool *existing)
929 {
930         WERROR werr;
931         TALLOC_CTX *mem_ctx = talloc_new(ctx->mem_ctx);
932
933         struct registry_key *key = NULL;
934         enum winreg_CreateAction action;
935
936         if (parent == NULL) {
937                 char *subkeyname = NULL;
938                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
939                          &parent, &subkeyname);
940                 if (!W_ERROR_IS_OK(werr)) {
941                         d_fprintf(stderr, _("open_hive failed: %s\n"),
942                                   win_errstr(werr));
943                         goto done;
944                 }
945                 name = subkeyname;
946         }
947
948         action = REG_ACTION_NONE;
949         werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
950                              &key, &action);
951         if (!W_ERROR_IS_OK(werr)) {
952                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
953                           win_errstr(werr));
954                 goto done;
955         }
956
957         if (action == REG_ACTION_NONE) {
958                 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
959                 werr = WERR_CREATE_FAILED;
960                 goto done;
961         }
962
963         if (existing != NULL) {
964                 *existing = (action == REG_OPENED_EXISTING_KEY);
965         }
966
967         if (pkey!=NULL) {
968                 *pkey = talloc_steal(ctx->mem_ctx, key);
969         }
970
971 done:
972         talloc_free(mem_ctx);
973         return werr;
974 }
975
976 static WERROR import_close_key(struct import_ctx *ctx,
977                                struct registry_key *key)
978 {
979         return WERR_OK;
980 }
981
982 static WERROR import_delete_key(struct import_ctx *ctx,
983                                 struct registry_key *parent, const char *name)
984 {
985         WERROR werr;
986         TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
987
988         if (parent == NULL) {
989                 char *subkeyname = NULL;
990                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
991                          &parent, &subkeyname);
992                 if (!W_ERROR_IS_OK(werr)) {
993                         d_fprintf(stderr, _("open_hive failed: %s\n"),
994                                   win_errstr(werr));
995                         goto done;
996                 }
997                 name = subkeyname;
998         }
999
1000         werr = reg_deletekey_recursive(parent, name);
1001         if (!W_ERROR_IS_OK(werr)) {
1002                 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n",
1003                           _("failed"), win_errstr(werr));
1004                 goto done;
1005         }
1006
1007 done:
1008         talloc_free(mem_ctx);
1009         return werr;
1010 }
1011
1012 static WERROR import_create_val (struct import_ctx *ctx,
1013                                  struct registry_key *parent, const char *name,
1014                                  const struct registry_value *value)
1015 {
1016         WERROR werr;
1017
1018         if (parent == NULL) {
1019                 return WERR_INVALID_PARAMETER;
1020         }
1021
1022         werr = reg_setvalue(parent, name, value);
1023         if (!W_ERROR_IS_OK(werr)) {
1024                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
1025                           win_errstr(werr));
1026         }
1027         return werr;
1028 }
1029
1030 static WERROR import_delete_val (struct import_ctx *ctx,
1031                                  struct registry_key *parent, const char *name)
1032 {
1033         WERROR werr;
1034
1035         if (parent == NULL) {
1036                 return WERR_INVALID_PARAMETER;
1037         }
1038
1039         werr = reg_deletevalue(parent, name);
1040         if (!W_ERROR_IS_OK(werr)) {
1041                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
1042                           win_errstr(werr));
1043         }
1044
1045         return werr;
1046 }
1047
1048 struct precheck_ctx {
1049         TALLOC_CTX *mem_ctx;
1050         bool failed;
1051 };
1052
1053 static WERROR precheck_create_key(struct precheck_ctx *ctx,
1054                                   struct registry_key *parent,
1055                                   const char *name, void **pkey, bool *existing)
1056 {
1057         WERROR werr;
1058         TALLOC_CTX *frame = talloc_stackframe();
1059         struct registry_key *key = NULL;
1060
1061         if (parent == NULL) {
1062                 char *subkeyname = NULL;
1063                 werr = open_hive(frame, name, REG_KEY_READ,
1064                                  &parent, &subkeyname);
1065                 if (!W_ERROR_IS_OK(werr)) {
1066                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
1067                                  name, win_errstr(werr));
1068                         goto done;
1069                 }
1070                 name = subkeyname;
1071         }
1072
1073         werr = reg_openkey(frame, parent, name, 0, &key);
1074         if (!W_ERROR_IS_OK(werr)) {
1075                 d_printf("Precheck: openkey [%s] failed: %s\n",
1076                          name, win_errstr(werr));
1077                 goto done;
1078         }
1079
1080         if (existing != NULL) {
1081                 *existing = true;
1082         }
1083
1084         if (pkey != NULL) {
1085                 *pkey = talloc_steal(ctx->mem_ctx, key);
1086         }
1087
1088 done:
1089         talloc_free(frame);
1090         ctx->failed = !W_ERROR_IS_OK(werr);
1091         return werr;
1092 }
1093
1094 static WERROR precheck_close_key(struct precheck_ctx *ctx,
1095                                  struct registry_key *key)
1096 {
1097         talloc_free(key);
1098         return WERR_OK;
1099 }
1100
1101 static WERROR precheck_delete_key(struct precheck_ctx *ctx,
1102                                   struct registry_key *parent, const char *name)
1103 {
1104         WERROR werr;
1105         TALLOC_CTX *frame = talloc_stackframe();
1106         struct registry_key *key;
1107
1108         if (parent == NULL) {
1109                 char *subkeyname = NULL;
1110                 werr = open_hive(frame, name, REG_KEY_READ,
1111                                  &parent, &subkeyname);
1112                 if (!W_ERROR_IS_OK(werr)) {
1113                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
1114                                  name, win_errstr(werr));
1115                         goto done;
1116                 }
1117                 name = subkeyname;
1118         }
1119
1120         werr = reg_openkey(ctx->mem_ctx, parent, name, 0, &key);
1121         if (W_ERROR_IS_OK(werr)) {
1122                 d_printf("Precheck: key [%s\\%s] should not exist\n",
1123                          parent->key->name, name);
1124                 werr = WERR_FILE_EXISTS;
1125         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1126                 werr = WERR_OK;
1127         } else {
1128                 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1129                          parent->key->name, name, win_errstr(werr));
1130         }
1131
1132 done:
1133         talloc_free(frame);
1134         ctx->failed = !W_ERROR_IS_OK(werr);
1135         return werr;
1136 }
1137
1138 static WERROR precheck_create_val(struct precheck_ctx *ctx,
1139                                   struct registry_key *parent,
1140                                   const char *name,
1141                                   const struct registry_value *value)
1142 {
1143         TALLOC_CTX *frame = talloc_stackframe();
1144         struct registry_value *old;
1145         WERROR werr;
1146
1147         SMB_ASSERT(parent);
1148
1149         werr = reg_queryvalue(frame, parent, name, &old);
1150         if (!W_ERROR_IS_OK(werr)) {
1151                 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1152                          name, parent->key->name, win_errstr(werr));
1153                 goto done;
1154         }
1155         if (registry_value_cmp(value, old) != 0) {
1156                 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1157                          name, parent->key->name);
1158                 ctx->failed = true;
1159         }
1160 done:
1161         talloc_free(frame);
1162         return werr;
1163 }
1164
1165 static WERROR precheck_delete_val(struct precheck_ctx *ctx,
1166                                   struct registry_key *parent,
1167                                   const char *name)
1168 {
1169         TALLOC_CTX *frame = talloc_stackframe();
1170         struct registry_value *old;
1171         WERROR werr;
1172
1173         SMB_ASSERT(parent);
1174
1175         werr = reg_queryvalue(frame, parent, name, &old);
1176         if (W_ERROR_IS_OK(werr)) {
1177                 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1178                          name, parent->key->name);
1179                 werr = WERR_FILE_EXISTS;
1180         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1181                 werr = WERR_OK;
1182         } else {
1183                 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1184                        name, parent->key->name, win_errstr(werr));
1185         }
1186
1187         talloc_free(frame);
1188         ctx->failed = !W_ERROR_IS_OK(werr);
1189         return werr;
1190 }
1191
1192 static bool import_precheck(const char *fname, const char *parse_options)
1193 {
1194         TALLOC_CTX *mem_ctx = talloc_tos();
1195         struct precheck_ctx precheck_ctx = {
1196                 .mem_ctx = mem_ctx,
1197                 .failed = false,
1198         };
1199         struct reg_import_callback precheck_callback = {
1200                 .openkey     = NULL,
1201                 .closekey    = (reg_import_callback_closekey_t)&precheck_close_key,
1202                 .createkey   = (reg_import_callback_createkey_t)&precheck_create_key,
1203                 .deletekey   = (reg_import_callback_deletekey_t)&precheck_delete_key,
1204                 .deleteval   = (reg_import_callback_deleteval_t)&precheck_delete_val,
1205                 .setval      = {
1206                         .registry_value = (reg_import_callback_setval_registry_value_t)
1207                                           &precheck_create_val,
1208                 },
1209                 .setval_type = REGISTRY_VALUE,
1210                 .data        = &precheck_ctx
1211         };
1212         struct reg_parse_callback *parse_callback;
1213         int ret;
1214
1215         if (!fname) {
1216                 return true;
1217         }
1218
1219         parse_callback = reg_import_adapter(mem_ctx, precheck_callback);
1220         if (parse_callback == NULL) {
1221                 d_printf("talloc failed\n");
1222                 return false;
1223         }
1224
1225         ret = reg_parse_file(fname, parse_callback, parse_options);
1226
1227         if (ret < 0 || precheck_ctx.failed) {
1228                 d_printf("Precheck failed\n");
1229                 return false;
1230         }
1231         return true;
1232 }
1233
1234 static int import_with_precheck_action(const char *import_fname,
1235                                        const char *precheck_fname,
1236                                        const char *parse_options)
1237 {
1238         TALLOC_CTX *frame = talloc_stackframe();
1239         struct import_ctx import_ctx = {
1240                 .mem_ctx = frame,
1241         };
1242         struct reg_import_callback import_callback = {
1243                 .openkey     = NULL,
1244                 .closekey    = (reg_import_callback_closekey_t)&import_close_key,
1245                 .createkey   = (reg_import_callback_createkey_t)&import_create_key,
1246                 .deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
1247                 .deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
1248                 .setval      = {
1249                         .registry_value = (reg_import_callback_setval_registry_value_t)
1250                                           &import_create_val,
1251                 },
1252                 .setval_type = REGISTRY_VALUE,
1253                 .data        = &import_ctx
1254         };
1255         struct reg_parse_callback *parse_callback;
1256         int ret = -1;
1257         bool precheck_ok;
1258
1259         precheck_ok = import_precheck(precheck_fname, parse_options);
1260         if (!precheck_ok) {
1261                 goto done;
1262         }
1263
1264         parse_callback = reg_import_adapter(frame, import_callback);
1265         if (parse_callback == NULL) {
1266                 d_printf("talloc failed\n");
1267                 goto done;
1268         }
1269
1270         ret = reg_parse_file(import_fname, parse_callback, parse_options);
1271
1272 done:
1273         talloc_free(frame);
1274         return ret;
1275 }
1276
1277 static int net_registry_import(struct net_context *c, int argc,
1278                                const char **argv)
1279 {
1280         const char *parse_options =  (argc > 1) ? argv[1] : NULL;
1281         int ret = -1;
1282         WERROR werr;
1283
1284         if (argc < 1 || argc > 2 || c->display_usage) {
1285                 d_printf("%s\n%s",
1286                          _("Usage:"),
1287                          _("net registry import <reg> [options]\n"));
1288                 d_printf("%s\n%s",
1289                          _("Example:"),
1290                          _("net registry import file.reg enc=CP1252\n"));
1291                 return -1;
1292         }
1293
1294         werr = regdb_open();
1295         if (!W_ERROR_IS_OK(werr)) {
1296                 d_printf("Failed to open regdb: %s\n", win_errstr(werr));
1297                 return -1;
1298         }
1299
1300         werr = regdb_transaction_start();
1301         if (!W_ERROR_IS_OK(werr)) {
1302                 d_printf("Failed to start transaction on regdb: %s\n",
1303                          win_errstr(werr));
1304                 goto done;
1305         }
1306
1307         ret = import_with_precheck_action(argv[0], c->opt_precheck,
1308                                           parse_options);
1309
1310         if (ret < 0) {
1311                 d_printf("Transaction canceled!\n");
1312                 regdb_transaction_cancel();
1313                 goto done;
1314         }
1315
1316         SMB_ASSERT(ret == 0);
1317
1318         if (c->opt_testmode) {
1319                 d_printf("Testmode: not committing changes.\n");
1320                 regdb_transaction_cancel();
1321                 goto done;
1322         }
1323
1324         werr = regdb_transaction_commit();
1325         if (!W_ERROR_IS_OK(werr)) {
1326                 d_printf("Failed to commit transaction on regdb: %s\n",
1327                          win_errstr(werr));
1328                 ret = -1;
1329         }
1330
1331 done:
1332         regdb_close();
1333         return ret;
1334 }
1335 /**@}*/
1336
1337 /******************************************************************************/
1338
1339 /**
1340  * @defgroup net_registry_export Export
1341  * @ingroup net_registry
1342  * @{
1343  */
1344
1345 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key *key,
1346                            struct reg_format *f)
1347 {
1348         int ret=-1;
1349         WERROR werr;
1350         uint32_t count;
1351
1352         struct registry_value *valvalue = NULL;
1353         char *valname = NULL;
1354
1355         char *subkey_name = NULL;
1356         NTTIME modtime = 0;
1357
1358         reg_format_registry_key(f, key, false);
1359
1360         /* print values */
1361         for (count = 0;
1362              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1363                      W_ERROR_IS_OK(werr);
1364              count++)
1365         {
1366                 reg_format_registry_value(f, valname, valvalue);
1367         }
1368         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1369                 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1370                           win_errstr(werr));
1371                 goto done;
1372         }
1373
1374         /* recurse on subkeys */
1375         for (count = 0;
1376              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1377                      W_ERROR_IS_OK(werr);
1378              count++)
1379         {
1380                 struct registry_key *subkey = NULL;
1381
1382                 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1383                                    &subkey);
1384                 if (!W_ERROR_IS_OK(werr)) {
1385                         d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1386                                   win_errstr(werr));
1387                         goto done;
1388                 }
1389
1390                 registry_export(ctx, subkey, f);
1391                 TALLOC_FREE(subkey);
1392         }
1393         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1394                 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1395                           win_errstr(werr));
1396                 goto done;
1397         }
1398         ret = 0;
1399 done:
1400         return ret;
1401 }
1402
1403 static int net_registry_export(struct net_context *c, int argc,
1404                                const char **argv)
1405 {
1406         int ret=-1;
1407         WERROR werr;
1408         struct registry_key *key = NULL;
1409         TALLOC_CTX *ctx = talloc_stackframe();
1410         struct reg_format *f=NULL;
1411
1412         if (argc < 2 || argc > 3 || c->display_usage) {
1413                 d_printf("%s\n%s",
1414                          _("Usage:"),
1415                          _("net registry export <path> <file> [opt]\n"));
1416                 d_printf("%s\n%s",
1417                          _("Example:"),
1418                          _("net registry export 'HKLM\\Software\\Samba' "
1419                            "samba.reg regedit5\n"));
1420                 goto done;
1421         }
1422
1423         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1424         if (!W_ERROR_IS_OK(werr)) {
1425                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1426                 goto done;
1427         }
1428
1429         f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1430         if (f == NULL) {
1431                 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1432                 goto done;
1433         }
1434
1435         ret = registry_export(ctx, key, f);
1436
1437 done:
1438         TALLOC_FREE(ctx);
1439         return ret;
1440 }
1441 /**@}*/
1442
1443 /******************************************************************************/
1444 /**
1445  * @defgroup net_registry_convert Convert
1446  * @ingroup net_registry
1447  * @{
1448  */
1449
1450 static int net_registry_convert(struct net_context *c, int argc,
1451                                const char **argv)
1452 {
1453         int ret;
1454         TALLOC_CTX *mem_ctx;
1455         const char *in_opt  = NULL;
1456         const char *out_opt = NULL;
1457
1458         if (argc < 2 || argc > 4|| c->display_usage) {
1459                 d_printf("%s\n%s",
1460                          _("Usage:"),
1461                          _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1462                            "net registry convert <in> <out> [out_opt]\n"));
1463                 d_printf("%s\n%s",
1464                          _("Example:"),
1465                          _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1466                 return -1;
1467         }
1468
1469         mem_ctx = talloc_stackframe();
1470
1471         switch (argc ) {
1472         case 2:
1473                 break;
1474         case 3:
1475                 out_opt = argv[2];
1476                 break;
1477         case 4:
1478                 out_opt = argv[3];
1479                 in_opt  = argv[2];
1480                 break;
1481         default:
1482                 assert(false);
1483         }
1484
1485
1486         ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1487                              reg_format_file(mem_ctx, argv[1], out_opt),
1488                              in_opt);
1489
1490         talloc_free(mem_ctx);
1491
1492         return ret;
1493 }
1494 /**@}*/
1495
1496 static int net_registry_check(struct net_context *c, int argc,
1497                               const char **argv)
1498 {
1499         char *dbfile;
1500         struct check_options opts;
1501         int ret;
1502
1503         if (argc > 1|| c->display_usage) {
1504                 d_printf("%s\n%s",
1505                          _("Usage:"),
1506                          _("net registry check  [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1507                            "  Check a registry database.\n"
1508                            "    -v|--verbose\t be verbose\n"
1509                            "    -r|--repair\t\t interactive repair mode\n"
1510                            "    -a|--auto\t\t noninteractive repair mode\n"
1511                            "    -T|--test\t\t dry run\n"
1512                            "    -f|--force\t\t force\n"
1513                            "    -l|--lock\t\t lock <TDB> while doing the check\n"
1514                            "    -o|--output=<ODB>\t output database\n"
1515                            "    --reg-version=n\t assume database format version {n|1,2,3}\n"
1516                            "    --wipe\t\t create a new database from scratch\n"
1517                            "    --db=<TDB>\t\t registry database to open\n"));
1518                 return c->display_usage ? 0 : -1;
1519         }
1520
1521         if (c->opt_db != NULL) {
1522                 dbfile = talloc_strdup(talloc_tos(), c->opt_db);
1523         } else if (argc > 0) {
1524                 dbfile = talloc_strdup(talloc_tos(), argv[0]);
1525         } else {
1526                 dbfile = state_path(talloc_tos(), "registry.tdb");
1527         }
1528         if (dbfile == NULL) {
1529                 return -1;
1530         }
1531
1532         opts = (struct check_options) {
1533                 .lock = c->opt_lock || c->opt_long_list_entries,
1534                 .test = c->opt_testmode,
1535                 .automatic = c->opt_auto,
1536                 .verbose = c->opt_verbose,
1537                 .force = c->opt_force,
1538                 .repair = c->opt_repair || c->opt_reboot,
1539                 .version = c->opt_reg_version,
1540                 .output  = c->opt_output,
1541                 .wipe = c->opt_wipe,
1542                 .implicit_db = (c->opt_db == NULL) && (argc == 0),
1543         };
1544
1545         ret = net_registry_check_db(dbfile, &opts);
1546         talloc_free(dbfile);
1547         return ret;
1548 }
1549
1550
1551 /******************************************************************************/
1552
1553 int net_registry(struct net_context *c, int argc, const char **argv)
1554 {
1555         int ret = -1;
1556
1557         struct functable func[] = {
1558                 {
1559                         "enumerate",
1560                         net_registry_enumerate,
1561                         NET_TRANSPORT_LOCAL,
1562                         N_("Enumerate registry keys and values"),
1563                         N_("net registry enumerate\n"
1564                            "    Enumerate registry keys and values")
1565                 },
1566                 {
1567                         "enumerate_recursive",
1568                         net_registry_enumerate_recursive,
1569                         NET_TRANSPORT_LOCAL,
1570                         N_("Enumerate registry keys and values"),
1571                         N_("net registry enumerate_recursive\n"
1572                            "    Enumerate registry keys and values")
1573                 },
1574                 {
1575                         "createkey",
1576                         net_registry_createkey,
1577                         NET_TRANSPORT_LOCAL,
1578                         N_("Create a new registry key"),
1579                         N_("net registry createkey\n"
1580                            "    Create a new registry key")
1581                 },
1582                 {
1583                         "deletekey",
1584                         net_registry_deletekey,
1585                         NET_TRANSPORT_LOCAL,
1586                         N_("Delete a registry key"),
1587                         N_("net registry deletekey\n"
1588                            "    Delete a registry key")
1589                 },
1590                 {
1591                         "deletekey_recursive",
1592                         net_registry_deletekey_recursive,
1593                         NET_TRANSPORT_LOCAL,
1594                         N_("Delete a registry key with subkeys"),
1595                         N_("net registry deletekey_recursive\n"
1596                            "    Delete a registry key with subkeys")
1597                 },
1598                 {
1599                         "getvalue",
1600                         net_registry_getvalue,
1601                         NET_TRANSPORT_LOCAL,
1602                         N_("Print a registry value"),
1603                         N_("net registry getvalue\n"
1604                            "    Print a registry value")
1605                 },
1606                 {
1607                         "getvalueraw",
1608                         net_registry_getvalueraw,
1609                         NET_TRANSPORT_LOCAL,
1610                         N_("Print a registry value (raw format)"),
1611                         N_("net registry getvalueraw\n"
1612                            "    Print a registry value (raw format)")
1613                 },
1614                 {
1615                         "getvaluesraw",
1616                         net_registry_getvaluesraw,
1617                         NET_TRANSPORT_LOCAL,
1618                         "Print all values of a key in raw format",
1619                         "net registry getvaluesraw <key>\n"
1620                         "    Print a registry value (raw format)"
1621                 },
1622                 {
1623                         "setvalue",
1624                         net_registry_setvalue,
1625                         NET_TRANSPORT_LOCAL,
1626                         N_("Set a new registry value"),
1627                         N_("net registry setvalue\n"
1628                            "    Set a new registry value")
1629                 },
1630                 {
1631                         "increment",
1632                         net_registry_increment,
1633                         NET_TRANSPORT_LOCAL,
1634                         N_("Increment a DWORD registry value under a lock"),
1635                         N_("net registry increment\n"
1636                            "    Increment a DWORD registry value under a lock")
1637                 },
1638                 {
1639                         "deletevalue",
1640                         net_registry_deletevalue,
1641                         NET_TRANSPORT_LOCAL,
1642                         N_("Delete a registry value"),
1643                         N_("net registry deletevalue\n"
1644                            "    Delete a registry value")
1645                 },
1646                 {
1647                         "getsd",
1648                         net_registry_getsd,
1649                         NET_TRANSPORT_LOCAL,
1650                         N_("Get security descriptor"),
1651                         N_("net registry getsd\n"
1652                            "    Get security descriptor")
1653                 },
1654                 {
1655                         "getsd_sddl",
1656                         net_registry_getsd_sddl,
1657                         NET_TRANSPORT_LOCAL,
1658                         N_("Get security descriptor in sddl format"),
1659                         N_("net registry getsd_sddl\n"
1660                            "    Get security descriptor in sddl format")
1661                 },
1662                 {
1663                         "setsd_sddl",
1664                         net_registry_setsd_sddl,
1665                         NET_TRANSPORT_LOCAL,
1666                         N_("Set security descriptor from sddl format string"),
1667                         N_("net registry setsd_sddl\n"
1668                            "    Set security descriptor from sddl format string")
1669                 },
1670                 {
1671                         "import",
1672                         net_registry_import,
1673                         NET_TRANSPORT_LOCAL,
1674                         N_("Import .reg file"),
1675                         N_("net registry import\n"
1676                            "    Import .reg file")
1677                 },
1678                 {
1679                         "export",
1680                         net_registry_export,
1681                         NET_TRANSPORT_LOCAL,
1682                         N_("Export .reg file"),
1683                         N_("net registry export\n"
1684                            "    Export .reg file")
1685                 },
1686                 {
1687                         "convert",
1688                         net_registry_convert,
1689                         NET_TRANSPORT_LOCAL,
1690                         N_("Convert .reg file"),
1691                         N_("net registry convert\n"
1692                            "    Convert .reg file")
1693                 },
1694                 {
1695                         "check",
1696                         net_registry_check,
1697                         NET_TRANSPORT_LOCAL,
1698                         N_("Check a registry database"),
1699                         N_("net registry check\n"
1700                            "    Check a registry database")
1701                 },
1702         { NULL, NULL, 0, NULL, NULL }
1703         };
1704
1705         if (!c->display_usage
1706             && argc > 0
1707             && (strcasecmp_m(argv[0], "convert") != 0)
1708             && (strcasecmp_m(argv[0], "check") != 0))
1709         {
1710                 if (!W_ERROR_IS_OK(registry_init_basic())) {
1711                         return -1;
1712                 }
1713         }
1714
1715         ret = net_run_function(c, argc, argv, "net registry", func);
1716
1717         return ret;
1718 }