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