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