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