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