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