s3/utils: Use sddl_decode_err_msg instead of sddl_decode
[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,
617                              lock_key,
618                              G_LOCK_WRITE,
619                              timeval_set(600, 0),
620                              NULL,
621                              NULL);
622         if (!NT_STATUS_IS_OK(status)) {
623                 d_fprintf(stderr, _("g_lock_lock failed: %s\n"),
624                           nt_errstr(status));
625                 goto done;
626         }
627
628         werr = open_key(c, keyname, REG_KEY_READ|REG_KEY_WRITE, &key);
629         if (!W_ERROR_IS_OK(werr)) {
630                 d_fprintf(stderr, _("open_key failed: %s\n"),
631                           win_errstr(werr));
632                 goto done;
633         }
634
635         werr = reg_queryvalue(key, key, valuename, &value);
636         if (!W_ERROR_IS_OK(werr)) {
637                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
638                           win_errstr(werr));
639                 goto done;
640         }
641
642         if (value->type != REG_DWORD) {
643                 d_fprintf(stderr, _("value not a DWORD: %s\n"),
644                           str_regtype(value->type));
645                 goto done;
646         }
647
648         if (value->data.length < 4) {
649                 d_fprintf(stderr, _("value too short for regular DWORD\n"));
650                 goto done;
651         }
652
653         v = IVAL(value->data.data, 0);
654         v += increment;
655         newvalue = v;
656
657         SIVAL(value->data.data, 0, v);
658
659         werr = reg_setvalue(key, valuename, value);
660         if (!W_ERROR_IS_OK(werr)) {
661                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
662                           win_errstr(werr));
663                 goto done;
664         }
665
666         if (!W_ERROR_IS_OK(werr)) {
667                 d_fprintf(stderr, _("increment failed: %s\n"),
668                           win_errstr(werr));
669                 goto done;
670         }
671
672         g_lock_unlock(ctx, lock_key);
673
674         d_printf(_("%"PRIu32"\n"), newvalue);
675
676         ret = 0;
677
678 done:
679         TALLOC_FREE(value);
680         TALLOC_FREE(key);
681         TALLOC_FREE(ctx);
682         return ret;
683 }
684
685 static int net_registry_deletevalue(struct net_context *c, int argc,
686                                     const char **argv)
687 {
688         WERROR werr;
689         struct registry_key *key = NULL;
690         TALLOC_CTX *ctx = talloc_stackframe();
691         int ret = -1;
692
693         if (argc != 2 || c->display_usage) {
694                 d_fprintf(stderr, "%s\n%s",
695                           _("Usage:"),
696                           _("net registry deletevalue <key> <valuename>\n"));
697                 goto done;
698         }
699
700         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
701         if (!W_ERROR_IS_OK(werr)) {
702                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
703                 goto done;
704         }
705
706         werr = reg_deletevalue(key, argv[1]);
707         if (!W_ERROR_IS_OK(werr)) {
708                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
709                           win_errstr(werr));
710                 goto done;
711         }
712
713         ret = 0;
714
715 done:
716         TALLOC_FREE(ctx);
717         return ret;
718 }
719
720 static WERROR net_registry_getsd_internal(struct net_context *c,
721                                           TALLOC_CTX *mem_ctx,
722                                           const char *keyname,
723                                           struct security_descriptor **sd)
724 {
725         WERROR werr;
726         struct registry_key *key = NULL;
727         TALLOC_CTX *ctx = talloc_stackframe();
728         uint32_t access_mask = REG_KEY_READ |
729                                SEC_FLAG_MAXIMUM_ALLOWED |
730                                SEC_FLAG_SYSTEM_SECURITY;
731
732         /*
733          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
734          * is denied with these perms right now...
735          */
736         access_mask = REG_KEY_READ;
737
738         if (sd == NULL) {
739                 d_fprintf(stderr, _("internal error: invalid argument\n"));
740                 werr = WERR_INVALID_PARAMETER;
741                 goto done;
742         }
743
744         if (strlen(keyname) == 0) {
745                 d_fprintf(stderr, _("error: zero length key name given\n"));
746                 werr = WERR_INVALID_PARAMETER;
747                 goto done;
748         }
749
750         werr = open_key(ctx, keyname, access_mask, &key);
751         if (!W_ERROR_IS_OK(werr)) {
752                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
753                           win_errstr(werr));
754                 goto done;
755         }
756
757         werr = reg_getkeysecurity(mem_ctx, key, sd);
758         if (!W_ERROR_IS_OK(werr)) {
759                 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
760                           win_errstr(werr));
761                 goto done;
762         }
763
764         werr = WERR_OK;
765
766 done:
767         TALLOC_FREE(ctx);
768         return werr;
769 }
770
771 static int net_registry_getsd(struct net_context *c, int argc,
772                               const char **argv)
773 {
774         WERROR werr;
775         int ret = -1;
776         struct security_descriptor *secdesc = NULL;
777         TALLOC_CTX *ctx = talloc_stackframe();
778
779         if (argc != 1 || c->display_usage) {
780                 d_printf("%s\n%s",
781                          _("Usage:"),
782                          _("net registry getsd <path>\n"));
783                 d_printf("%s\n%s",
784                          _("Example:"),
785                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
786                 goto done;
787         }
788
789         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
790         if (!W_ERROR_IS_OK(werr)) {
791                 goto done;
792         }
793
794         display_sec_desc(secdesc);
795
796         ret = 0;
797
798 done:
799         TALLOC_FREE(ctx);
800         return ret;
801 }
802
803 static int net_registry_getsd_sddl(struct net_context *c,
804                                    int argc, const char **argv)
805 {
806         WERROR werr;
807         int ret = -1;
808         struct security_descriptor *secdesc = NULL;
809         TALLOC_CTX *ctx = talloc_stackframe();
810
811         if (argc != 1 || c->display_usage) {
812                 d_printf("%s\n%s",
813                          _("Usage:"),
814                          _("net registry getsd_sddl <path>\n"));
815                 d_printf("%s\n%s",
816                          _("Example:"),
817                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
818                 goto done;
819         }
820
821         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
822         if (!W_ERROR_IS_OK(werr)) {
823                 goto done;
824         }
825
826         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
827
828         ret = 0;
829
830 done:
831         TALLOC_FREE(ctx);
832         return ret;
833 }
834
835 static WERROR net_registry_setsd_internal(struct net_context *c,
836                                           TALLOC_CTX *mem_ctx,
837                                           const char *keyname,
838                                           struct security_descriptor *sd)
839 {
840         WERROR werr;
841         struct registry_key *key = NULL;
842         TALLOC_CTX *ctx = talloc_stackframe();
843         uint32_t access_mask = REG_KEY_WRITE |
844                                SEC_FLAG_MAXIMUM_ALLOWED |
845                                SEC_FLAG_SYSTEM_SECURITY;
846
847         /*
848          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
849          * is denied with these perms right now...
850          */
851         access_mask = REG_KEY_WRITE;
852
853         if (strlen(keyname) == 0) {
854                 d_fprintf(stderr, _("error: zero length key name given\n"));
855                 werr = WERR_INVALID_PARAMETER;
856                 goto done;
857         }
858
859         werr = open_key(ctx, keyname, access_mask, &key);
860         if (!W_ERROR_IS_OK(werr)) {
861                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
862                           win_errstr(werr));
863                 goto done;
864         }
865
866         werr = reg_setkeysecurity(key, sd);
867         if (!W_ERROR_IS_OK(werr)) {
868                 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
869                           win_errstr(werr));
870                 goto done;
871         }
872
873         werr = WERR_OK;
874
875 done:
876         TALLOC_FREE(ctx);
877         return werr;
878 }
879
880 static int net_registry_setsd_sddl(struct net_context *c,
881                                    int argc, const char **argv)
882 {
883         WERROR werr;
884         int ret = -1;
885         struct security_descriptor *secdesc = NULL;
886         TALLOC_CTX *ctx = talloc_stackframe();
887
888         if (argc != 2 || c->display_usage) {
889                 d_printf("%s\n%s",
890                          _("Usage:"),
891                          _("net registry setsd_sddl <path> <security_descriptor>\n"));
892                 d_printf("%s\n%s",
893                          _("Example:"),
894                          _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
895                 goto done;
896         }
897
898         secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
899         if (secdesc == NULL) {
900                 goto done;
901         }
902
903         werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
904         if (!W_ERROR_IS_OK(werr)) {
905                 goto done;
906         }
907
908         ret = 0;
909
910 done:
911         TALLOC_FREE(ctx);
912         return ret;
913 }
914
915 /******************************************************************************/
916 /**
917  * @defgroup net_registry net registry
918  */
919
920 /**
921  * @defgroup net_registry_import Import
922  * @ingroup net_registry
923  * @{
924  */
925
926 struct import_ctx {
927         TALLOC_CTX *mem_ctx;
928 };
929
930
931 static WERROR import_create_key(struct import_ctx *ctx,
932                                 struct registry_key *parent,
933                                 const char *name, void **pkey, bool *existing)
934 {
935         WERROR werr;
936         TALLOC_CTX *mem_ctx = talloc_new(ctx->mem_ctx);
937
938         struct registry_key *key = NULL;
939         enum winreg_CreateAction action;
940
941         if (parent == NULL) {
942                 char *subkeyname = NULL;
943                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
944                          &parent, &subkeyname);
945                 if (!W_ERROR_IS_OK(werr)) {
946                         d_fprintf(stderr, _("open_hive failed: %s\n"),
947                                   win_errstr(werr));
948                         goto done;
949                 }
950                 name = subkeyname;
951         }
952
953         action = REG_ACTION_NONE;
954         werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
955                              &key, &action);
956         if (!W_ERROR_IS_OK(werr)) {
957                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
958                           win_errstr(werr));
959                 goto done;
960         }
961
962         if (action == REG_ACTION_NONE) {
963                 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
964                 werr = WERR_CREATE_FAILED;
965                 goto done;
966         }
967
968         if (existing != NULL) {
969                 *existing = (action == REG_OPENED_EXISTING_KEY);
970         }
971
972         if (pkey!=NULL) {
973                 *pkey = talloc_steal(ctx->mem_ctx, key);
974         }
975
976 done:
977         talloc_free(mem_ctx);
978         return werr;
979 }
980
981 static WERROR import_close_key(struct import_ctx *ctx,
982                                struct registry_key *key)
983 {
984         return WERR_OK;
985 }
986
987 static WERROR import_delete_key(struct import_ctx *ctx,
988                                 struct registry_key *parent, const char *name)
989 {
990         WERROR werr;
991         TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
992
993         if (parent == NULL) {
994                 char *subkeyname = NULL;
995                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
996                          &parent, &subkeyname);
997                 if (!W_ERROR_IS_OK(werr)) {
998                         d_fprintf(stderr, _("open_hive failed: %s\n"),
999                                   win_errstr(werr));
1000                         goto done;
1001                 }
1002                 name = subkeyname;
1003         }
1004
1005         werr = reg_deletekey_recursive(parent, name);
1006         if (!W_ERROR_IS_OK(werr)) {
1007                 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n",
1008                           _("failed"), win_errstr(werr));
1009                 goto done;
1010         }
1011
1012 done:
1013         talloc_free(mem_ctx);
1014         return werr;
1015 }
1016
1017 static WERROR import_create_val (struct import_ctx *ctx,
1018                                  struct registry_key *parent, const char *name,
1019                                  const struct registry_value *value)
1020 {
1021         WERROR werr;
1022
1023         if (parent == NULL) {
1024                 return WERR_INVALID_PARAMETER;
1025         }
1026
1027         werr = reg_setvalue(parent, name, value);
1028         if (!W_ERROR_IS_OK(werr)) {
1029                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
1030                           win_errstr(werr));
1031         }
1032         return werr;
1033 }
1034
1035 static WERROR import_delete_val (struct import_ctx *ctx,
1036                                  struct registry_key *parent, const char *name)
1037 {
1038         WERROR werr;
1039
1040         if (parent == NULL) {
1041                 return WERR_INVALID_PARAMETER;
1042         }
1043
1044         werr = reg_deletevalue(parent, name);
1045         if (!W_ERROR_IS_OK(werr)) {
1046                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
1047                           win_errstr(werr));
1048         }
1049
1050         return werr;
1051 }
1052
1053 struct precheck_ctx {
1054         TALLOC_CTX *mem_ctx;
1055         bool failed;
1056 };
1057
1058 static WERROR precheck_create_key(struct precheck_ctx *ctx,
1059                                   struct registry_key *parent,
1060                                   const char *name, void **pkey, bool *existing)
1061 {
1062         WERROR werr;
1063         TALLOC_CTX *frame = talloc_stackframe();
1064         struct registry_key *key = NULL;
1065
1066         if (parent == NULL) {
1067                 char *subkeyname = NULL;
1068                 werr = open_hive(frame, name, REG_KEY_READ,
1069                                  &parent, &subkeyname);
1070                 if (!W_ERROR_IS_OK(werr)) {
1071                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
1072                                  name, win_errstr(werr));
1073                         goto done;
1074                 }
1075                 name = subkeyname;
1076         }
1077
1078         werr = reg_openkey(frame, parent, name, 0, &key);
1079         if (!W_ERROR_IS_OK(werr)) {
1080                 d_printf("Precheck: openkey [%s] failed: %s\n",
1081                          name, win_errstr(werr));
1082                 goto done;
1083         }
1084
1085         if (existing != NULL) {
1086                 *existing = true;
1087         }
1088
1089         if (pkey != NULL) {
1090                 *pkey = talloc_steal(ctx->mem_ctx, key);
1091         }
1092
1093 done:
1094         talloc_free(frame);
1095         ctx->failed = !W_ERROR_IS_OK(werr);
1096         return werr;
1097 }
1098
1099 static WERROR precheck_close_key(struct precheck_ctx *ctx,
1100                                  struct registry_key *key)
1101 {
1102         talloc_free(key);
1103         return WERR_OK;
1104 }
1105
1106 static WERROR precheck_delete_key(struct precheck_ctx *ctx,
1107                                   struct registry_key *parent, const char *name)
1108 {
1109         WERROR werr;
1110         TALLOC_CTX *frame = talloc_stackframe();
1111         struct registry_key *key;
1112
1113         if (parent == NULL) {
1114                 char *subkeyname = NULL;
1115                 werr = open_hive(frame, name, REG_KEY_READ,
1116                                  &parent, &subkeyname);
1117                 if (!W_ERROR_IS_OK(werr)) {
1118                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
1119                                  name, win_errstr(werr));
1120                         goto done;
1121                 }
1122                 name = subkeyname;
1123         }
1124
1125         werr = reg_openkey(ctx->mem_ctx, parent, name, 0, &key);
1126         if (W_ERROR_IS_OK(werr)) {
1127                 d_printf("Precheck: key [%s\\%s] should not exist\n",
1128                          parent->key->name, name);
1129                 werr = WERR_FILE_EXISTS;
1130         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1131                 werr = WERR_OK;
1132         } else {
1133                 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1134                          parent->key->name, name, win_errstr(werr));
1135         }
1136
1137 done:
1138         talloc_free(frame);
1139         ctx->failed = !W_ERROR_IS_OK(werr);
1140         return werr;
1141 }
1142
1143 static int registry_value_cmp(
1144         const struct registry_value* v1, const struct registry_value* v2)
1145 {
1146         if (v1->type == v2->type) {
1147                 return data_blob_cmp(&v1->data, &v2->data);
1148         }
1149         return v1->type - v2->type;
1150 }
1151
1152 static WERROR precheck_create_val(struct precheck_ctx *ctx,
1153                                   struct registry_key *parent,
1154                                   const char *name,
1155                                   const struct registry_value *value)
1156 {
1157         TALLOC_CTX *frame = talloc_stackframe();
1158         struct registry_value *old;
1159         WERROR werr;
1160
1161         SMB_ASSERT(parent);
1162
1163         werr = reg_queryvalue(frame, parent, name, &old);
1164         if (!W_ERROR_IS_OK(werr)) {
1165                 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1166                          name, parent->key->name, win_errstr(werr));
1167                 goto done;
1168         }
1169         if (registry_value_cmp(value, old) != 0) {
1170                 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1171                          name, parent->key->name);
1172                 ctx->failed = true;
1173         }
1174 done:
1175         talloc_free(frame);
1176         return werr;
1177 }
1178
1179 static WERROR precheck_delete_val(struct precheck_ctx *ctx,
1180                                   struct registry_key *parent,
1181                                   const char *name)
1182 {
1183         TALLOC_CTX *frame = talloc_stackframe();
1184         struct registry_value *old;
1185         WERROR werr;
1186
1187         SMB_ASSERT(parent);
1188
1189         werr = reg_queryvalue(frame, parent, name, &old);
1190         if (W_ERROR_IS_OK(werr)) {
1191                 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1192                          name, parent->key->name);
1193                 werr = WERR_FILE_EXISTS;
1194         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1195                 werr = WERR_OK;
1196         } else {
1197                 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1198                        name, parent->key->name, win_errstr(werr));
1199         }
1200
1201         talloc_free(frame);
1202         ctx->failed = !W_ERROR_IS_OK(werr);
1203         return werr;
1204 }
1205
1206 static bool import_precheck(const char *fname, const char *parse_options)
1207 {
1208         TALLOC_CTX *mem_ctx = talloc_tos();
1209         struct precheck_ctx precheck_ctx = {
1210                 .mem_ctx = mem_ctx,
1211                 .failed = false,
1212         };
1213         struct reg_import_callback precheck_callback = {
1214                 .openkey     = NULL,
1215                 .closekey    = (reg_import_callback_closekey_t)&precheck_close_key,
1216                 .createkey   = (reg_import_callback_createkey_t)&precheck_create_key,
1217                 .deletekey   = (reg_import_callback_deletekey_t)&precheck_delete_key,
1218                 .deleteval   = (reg_import_callback_deleteval_t)&precheck_delete_val,
1219                 .setval      = {
1220                         .registry_value = (reg_import_callback_setval_registry_value_t)
1221                                           &precheck_create_val,
1222                 },
1223                 .setval_type = REGISTRY_VALUE,
1224                 .data        = &precheck_ctx
1225         };
1226         struct reg_parse_callback *parse_callback;
1227         int ret;
1228
1229         if (!fname) {
1230                 return true;
1231         }
1232
1233         parse_callback = reg_import_adapter(mem_ctx, precheck_callback);
1234         if (parse_callback == NULL) {
1235                 d_printf("talloc failed\n");
1236                 return false;
1237         }
1238
1239         ret = reg_parse_file(fname, parse_callback, parse_options);
1240
1241         if (ret < 0 || precheck_ctx.failed) {
1242                 d_printf("Precheck failed\n");
1243                 return false;
1244         }
1245         return true;
1246 }
1247
1248 static int import_with_precheck_action(const char *import_fname,
1249                                        const char *precheck_fname,
1250                                        const char *parse_options)
1251 {
1252         TALLOC_CTX *frame = talloc_stackframe();
1253         struct import_ctx import_ctx = {
1254                 .mem_ctx = frame,
1255         };
1256         struct reg_import_callback import_callback = {
1257                 .openkey     = NULL,
1258                 .closekey    = (reg_import_callback_closekey_t)&import_close_key,
1259                 .createkey   = (reg_import_callback_createkey_t)&import_create_key,
1260                 .deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
1261                 .deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
1262                 .setval      = {
1263                         .registry_value = (reg_import_callback_setval_registry_value_t)
1264                                           &import_create_val,
1265                 },
1266                 .setval_type = REGISTRY_VALUE,
1267                 .data        = &import_ctx
1268         };
1269         struct reg_parse_callback *parse_callback;
1270         int ret = -1;
1271         bool precheck_ok;
1272
1273         precheck_ok = import_precheck(precheck_fname, parse_options);
1274         if (!precheck_ok) {
1275                 goto done;
1276         }
1277
1278         parse_callback = reg_import_adapter(frame, import_callback);
1279         if (parse_callback == NULL) {
1280                 d_printf("talloc failed\n");
1281                 goto done;
1282         }
1283
1284         ret = reg_parse_file(import_fname, parse_callback, parse_options);
1285
1286 done:
1287         talloc_free(frame);
1288         return ret;
1289 }
1290
1291 static int net_registry_import(struct net_context *c, int argc,
1292                                const char **argv)
1293 {
1294         const char *parse_options =  (argc > 1) ? argv[1] : NULL;
1295         int ret = -1;
1296         WERROR werr;
1297
1298         if (argc < 1 || argc > 2 || c->display_usage) {
1299                 d_printf("%s\n%s",
1300                          _("Usage:"),
1301                          _("net registry import <reg> [options]\n"));
1302                 d_printf("%s\n%s",
1303                          _("Example:"),
1304                          _("net registry import file.reg enc=CP1252\n"));
1305                 return -1;
1306         }
1307
1308         werr = regdb_open();
1309         if (!W_ERROR_IS_OK(werr)) {
1310                 d_printf("Failed to open regdb: %s\n", win_errstr(werr));
1311                 return -1;
1312         }
1313
1314         werr = regdb_transaction_start();
1315         if (!W_ERROR_IS_OK(werr)) {
1316                 d_printf("Failed to start transaction on regdb: %s\n",
1317                          win_errstr(werr));
1318                 goto done;
1319         }
1320
1321         ret = import_with_precheck_action(argv[0], c->opt_precheck,
1322                                           parse_options);
1323
1324         if (ret < 0) {
1325                 d_printf("Transaction canceled!\n");
1326                 regdb_transaction_cancel();
1327                 goto done;
1328         }
1329
1330         SMB_ASSERT(ret == 0);
1331
1332         if (c->opt_testmode) {
1333                 d_printf("Testmode: not committing changes.\n");
1334                 regdb_transaction_cancel();
1335                 goto done;
1336         }
1337
1338         werr = regdb_transaction_commit();
1339         if (!W_ERROR_IS_OK(werr)) {
1340                 d_printf("Failed to commit transaction on regdb: %s\n",
1341                          win_errstr(werr));
1342                 ret = -1;
1343         }
1344
1345 done:
1346         regdb_close();
1347         return ret;
1348 }
1349 /**@}*/
1350
1351 /******************************************************************************/
1352
1353 /**
1354  * @defgroup net_registry_export Export
1355  * @ingroup net_registry
1356  * @{
1357  */
1358
1359 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key *key,
1360                            struct reg_format *f)
1361 {
1362         int ret=-1;
1363         WERROR werr;
1364         uint32_t count;
1365
1366         struct registry_value *valvalue = NULL;
1367         char *valname = NULL;
1368
1369         char *subkey_name = NULL;
1370         NTTIME modtime = 0;
1371
1372         reg_format_registry_key(f, key, false);
1373
1374         /* print values */
1375         for (count = 0;
1376              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1377                      W_ERROR_IS_OK(werr);
1378              count++)
1379         {
1380                 reg_format_registry_value(f, valname, valvalue);
1381         }
1382         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1383                 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1384                           win_errstr(werr));
1385                 goto done;
1386         }
1387
1388         /* recurse on subkeys */
1389         for (count = 0;
1390              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1391                      W_ERROR_IS_OK(werr);
1392              count++)
1393         {
1394                 struct registry_key *subkey = NULL;
1395
1396                 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1397                                    &subkey);
1398                 if (!W_ERROR_IS_OK(werr)) {
1399                         d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1400                                   win_errstr(werr));
1401                         goto done;
1402                 }
1403
1404                 registry_export(ctx, subkey, f);
1405                 TALLOC_FREE(subkey);
1406         }
1407         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1408                 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1409                           win_errstr(werr));
1410                 goto done;
1411         }
1412         ret = 0;
1413 done:
1414         return ret;
1415 }
1416
1417 static int net_registry_export(struct net_context *c, int argc,
1418                                const char **argv)
1419 {
1420         int ret=-1;
1421         WERROR werr;
1422         struct registry_key *key = NULL;
1423         TALLOC_CTX *ctx = talloc_stackframe();
1424         struct reg_format *f=NULL;
1425
1426         if (argc < 2 || argc > 3 || c->display_usage) {
1427                 d_printf("%s\n%s",
1428                          _("Usage:"),
1429                          _("net registry export <path> <file> [opt]\n"));
1430                 d_printf("%s\n%s",
1431                          _("Example:"),
1432                          _("net registry export 'HKLM\\Software\\Samba' "
1433                            "samba.reg regedit5\n"));
1434                 goto done;
1435         }
1436
1437         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1438         if (!W_ERROR_IS_OK(werr)) {
1439                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1440                 goto done;
1441         }
1442
1443         f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1444         if (f == NULL) {
1445                 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1446                 goto done;
1447         }
1448
1449         ret = registry_export(ctx, key, f);
1450
1451 done:
1452         TALLOC_FREE(ctx);
1453         return ret;
1454 }
1455 /**@}*/
1456
1457 /******************************************************************************/
1458 /**
1459  * @defgroup net_registry_convert Convert
1460  * @ingroup net_registry
1461  * @{
1462  */
1463
1464 static int net_registry_convert(struct net_context *c, int argc,
1465                                const char **argv)
1466 {
1467         int ret;
1468         TALLOC_CTX *mem_ctx;
1469         const char *in_opt  = NULL;
1470         const char *out_opt = NULL;
1471
1472         if (argc < 2 || argc > 4|| c->display_usage) {
1473                 d_printf("%s\n%s",
1474                          _("Usage:"),
1475                          _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1476                            "net registry convert <in> <out> [out_opt]\n"));
1477                 d_printf("%s\n%s",
1478                          _("Example:"),
1479                          _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1480                 return -1;
1481         }
1482
1483         mem_ctx = talloc_stackframe();
1484
1485         switch (argc ) {
1486         case 2:
1487                 break;
1488         case 3:
1489                 out_opt = argv[2];
1490                 break;
1491         case 4:
1492                 out_opt = argv[3];
1493                 in_opt  = argv[2];
1494                 break;
1495         default:
1496                 assert(false);
1497         }
1498
1499
1500         ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1501                              reg_format_file(mem_ctx, argv[1], out_opt),
1502                              in_opt);
1503
1504         talloc_free(mem_ctx);
1505
1506         return ret;
1507 }
1508 /**@}*/
1509
1510 static int net_registry_check(struct net_context *c, int argc,
1511                               const char **argv)
1512 {
1513         char *dbfile;
1514         struct check_options opts;
1515         int ret;
1516
1517         if (argc > 1|| c->display_usage) {
1518                 d_printf("%s\n%s",
1519                          _("Usage:"),
1520                          _("net registry check  [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1521                            "  Check a registry database.\n"
1522                            "    -v|--verbose\t be verbose\n"
1523                            "    -r|--repair\t\t interactive repair mode\n"
1524                            "    -a|--auto\t\t noninteractive repair mode\n"
1525                            "    -T|--test\t\t dry run\n"
1526                            "    -f|--force\t\t force\n"
1527                            "    -l|--lock\t\t lock <TDB> while doing the check\n"
1528                            "    -o|--output=<ODB>\t output database\n"
1529                            "    --reg-version=n\t assume database format version {n|1,2,3}\n"
1530                            "    --wipe\t\t create a new database from scratch\n"
1531                            "    --db=<TDB>\t\t registry database to open\n"));
1532                 return c->display_usage ? 0 : -1;
1533         }
1534
1535         if (c->opt_db != NULL) {
1536                 dbfile = talloc_strdup(talloc_tos(), c->opt_db);
1537         } else if (argc > 0) {
1538                 dbfile = talloc_strdup(talloc_tos(), argv[0]);
1539         } else {
1540                 dbfile = state_path(talloc_tos(), "registry.tdb");
1541         }
1542         if (dbfile == NULL) {
1543                 return -1;
1544         }
1545
1546         opts = (struct check_options) {
1547                 .lock = c->opt_lock || c->opt_long_list_entries,
1548                 .test = c->opt_testmode,
1549                 .automatic = c->opt_auto,
1550                 .verbose = c->opt_verbose,
1551                 .force = c->opt_force,
1552                 .repair = c->opt_repair || c->opt_reboot,
1553                 .version = c->opt_reg_version,
1554                 .output  = c->opt_output,
1555                 .wipe = c->opt_wipe,
1556                 .implicit_db = (c->opt_db == NULL) && (argc == 0),
1557         };
1558
1559         ret = net_registry_check_db(dbfile, &opts);
1560         talloc_free(dbfile);
1561         return ret;
1562 }
1563
1564
1565 /******************************************************************************/
1566
1567 int net_registry(struct net_context *c, int argc, const char **argv)
1568 {
1569         int ret = -1;
1570
1571         struct functable func[] = {
1572                 {
1573                         "enumerate",
1574                         net_registry_enumerate,
1575                         NET_TRANSPORT_LOCAL,
1576                         N_("Enumerate registry keys and values"),
1577                         N_("net registry enumerate\n"
1578                            "    Enumerate registry keys and values")
1579                 },
1580                 {
1581                         "enumerate_recursive",
1582                         net_registry_enumerate_recursive,
1583                         NET_TRANSPORT_LOCAL,
1584                         N_("Enumerate registry keys and values"),
1585                         N_("net registry enumerate_recursive\n"
1586                            "    Enumerate registry keys and values")
1587                 },
1588                 {
1589                         "createkey",
1590                         net_registry_createkey,
1591                         NET_TRANSPORT_LOCAL,
1592                         N_("Create a new registry key"),
1593                         N_("net registry createkey\n"
1594                            "    Create a new registry key")
1595                 },
1596                 {
1597                         "deletekey",
1598                         net_registry_deletekey,
1599                         NET_TRANSPORT_LOCAL,
1600                         N_("Delete a registry key"),
1601                         N_("net registry deletekey\n"
1602                            "    Delete a registry key")
1603                 },
1604                 {
1605                         "deletekey_recursive",
1606                         net_registry_deletekey_recursive,
1607                         NET_TRANSPORT_LOCAL,
1608                         N_("Delete a registry key with subkeys"),
1609                         N_("net registry deletekey_recursive\n"
1610                            "    Delete a registry key with subkeys")
1611                 },
1612                 {
1613                         "getvalue",
1614                         net_registry_getvalue,
1615                         NET_TRANSPORT_LOCAL,
1616                         N_("Print a registry value"),
1617                         N_("net registry getvalue\n"
1618                            "    Print a registry value")
1619                 },
1620                 {
1621                         "getvalueraw",
1622                         net_registry_getvalueraw,
1623                         NET_TRANSPORT_LOCAL,
1624                         N_("Print a registry value (raw format)"),
1625                         N_("net registry getvalueraw\n"
1626                            "    Print a registry value (raw format)")
1627                 },
1628                 {
1629                         "getvaluesraw",
1630                         net_registry_getvaluesraw,
1631                         NET_TRANSPORT_LOCAL,
1632                         "Print all values of a key in raw format",
1633                         "net registry getvaluesraw <key>\n"
1634                         "    Print a registry value (raw format)"
1635                 },
1636                 {
1637                         "setvalue",
1638                         net_registry_setvalue,
1639                         NET_TRANSPORT_LOCAL,
1640                         N_("Set a new registry value"),
1641                         N_("net registry setvalue\n"
1642                            "    Set a new registry value")
1643                 },
1644                 {
1645                         "increment",
1646                         net_registry_increment,
1647                         NET_TRANSPORT_LOCAL,
1648                         N_("Increment a DWORD registry value under a lock"),
1649                         N_("net registry increment\n"
1650                            "    Increment a DWORD registry value under a lock")
1651                 },
1652                 {
1653                         "deletevalue",
1654                         net_registry_deletevalue,
1655                         NET_TRANSPORT_LOCAL,
1656                         N_("Delete a registry value"),
1657                         N_("net registry deletevalue\n"
1658                            "    Delete a registry value")
1659                 },
1660                 {
1661                         "getsd",
1662                         net_registry_getsd,
1663                         NET_TRANSPORT_LOCAL,
1664                         N_("Get security descriptor"),
1665                         N_("net registry getsd\n"
1666                            "    Get security descriptor")
1667                 },
1668                 {
1669                         "getsd_sddl",
1670                         net_registry_getsd_sddl,
1671                         NET_TRANSPORT_LOCAL,
1672                         N_("Get security descriptor in sddl format"),
1673                         N_("net registry getsd_sddl\n"
1674                            "    Get security descriptor in sddl format")
1675                 },
1676                 {
1677                         "setsd_sddl",
1678                         net_registry_setsd_sddl,
1679                         NET_TRANSPORT_LOCAL,
1680                         N_("Set security descriptor from sddl format string"),
1681                         N_("net registry setsd_sddl\n"
1682                            "    Set security descriptor from sddl format string")
1683                 },
1684                 {
1685                         "import",
1686                         net_registry_import,
1687                         NET_TRANSPORT_LOCAL,
1688                         N_("Import .reg file"),
1689                         N_("net registry import\n"
1690                            "    Import .reg file")
1691                 },
1692                 {
1693                         "export",
1694                         net_registry_export,
1695                         NET_TRANSPORT_LOCAL,
1696                         N_("Export .reg file"),
1697                         N_("net registry export\n"
1698                            "    Export .reg file")
1699                 },
1700                 {
1701                         "convert",
1702                         net_registry_convert,
1703                         NET_TRANSPORT_LOCAL,
1704                         N_("Convert .reg file"),
1705                         N_("net registry convert\n"
1706                            "    Convert .reg file")
1707                 },
1708                 {
1709                         "check",
1710                         net_registry_check,
1711                         NET_TRANSPORT_LOCAL,
1712                         N_("Check a registry database"),
1713                         N_("net registry check\n"
1714                            "    Check a registry database")
1715                 },
1716         { NULL, NULL, 0, NULL, NULL }
1717         };
1718
1719         if (!c->display_usage
1720             && argc > 0
1721             && (strcasecmp_m(argv[0], "convert") != 0)
1722             && (strcasecmp_m(argv[0], "check") != 0))
1723         {
1724                 if (!W_ERROR_IS_OK(registry_init_basic())) {
1725                         return -1;
1726                 }
1727         }
1728
1729         ret = net_run_function(c, argc, argv, "net registry", func);
1730
1731         return ret;
1732 }