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