release-scripts: add build-htmlman-nogit
[Samba/bb.git] / source3 / utils / net_registry.c
blob163d059ae077fae576973d2b8d859cf58e69d9c9
1 /*
2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local registry interface
6 * Copyright (C) Michael Adam 2008
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.
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.
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/>.
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>
37 * Helper functions
41 /**
42 * split given path into hive and remaining path and open the hive key
44 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
45 uint32 desired_access,
46 struct registry_key **hive,
47 char **subkeyname)
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();
55 if ((hive == NULL) || (subkeyname == NULL)) {
56 werr = WERR_INVALID_PARAM;
57 goto done;
60 werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
61 if (!W_ERROR_IS_OK(werr)) {
62 goto done;
64 *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
65 if (*subkeyname == NULL) {
66 werr = WERR_NOMEM;
67 goto done;
70 werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
71 if (!W_ERROR_IS_OK(werr)) {
72 goto done;
75 werr = reg_openhive(ctx, hivename, desired_access, token, hive);
76 if (!W_ERROR_IS_OK(werr)) {
77 goto done;
80 werr = WERR_OK;
82 done:
83 TALLOC_FREE(tmp_ctx);
84 return werr;
87 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
88 uint32 desired_access,
89 struct registry_key **key)
91 WERROR werr;
92 char *subkey_name = NULL;
93 struct registry_key *hive = NULL;
94 TALLOC_CTX *tmp_ctx = talloc_stackframe();
96 if ((path == NULL) || (key == NULL)) {
97 return WERR_INVALID_PARAM;
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;
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;
114 werr = WERR_OK;
116 done:
117 TALLOC_FREE(tmp_ctx);
118 return werr;
123 * the main "net registry" function implementations
127 static int net_registry_enumerate(struct net_context *c, int argc,
128 const char **argv)
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;
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;
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;
156 for (count = 0;
157 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
158 W_ERROR_IS_OK(werr);
159 count++)
161 print_registry_key(subkey_name, &modtime);
163 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
164 goto done;
167 for (count = 0;
168 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
169 W_ERROR_IS_OK(werr);
170 count++)
172 print_registry_value_with_name(valname, valvalue);
174 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
175 goto done;
178 ret = 0;
179 done:
180 TALLOC_FREE(ctx);
181 return ret;
184 static int net_registry_createkey(struct net_context *c, int argc,
185 const char **argv)
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;
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;
205 if (strlen(argv[0]) == 0) {
206 d_fprintf(stderr, _("error: zero length key name given\n"));
207 goto done;
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;
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;
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;
236 ret = 0;
238 done:
239 TALLOC_FREE(ctx);
240 return ret;
243 static int net_registry_deletekey_internal(struct net_context *c, int argc,
244 const char **argv,
245 bool recursive)
247 WERROR werr;
248 char *subkeyname;
249 struct registry_key *hivekey = NULL;
250 TALLOC_CTX *ctx = talloc_stackframe();
251 int ret = -1;
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;
263 if (strlen(argv[0]) == 0) {
264 d_fprintf(stderr, _("error: zero length key name given\n"));
265 goto done;
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;
275 if (recursive) {
276 werr = reg_deletekey_recursive(hivekey, subkeyname);
277 } else {
278 werr = reg_deletekey(hivekey, subkeyname);
280 if (!W_ERROR_IS_OK(werr)) {
281 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
282 win_errstr(werr));
283 goto done;
286 ret = 0;
288 done:
289 TALLOC_FREE(ctx);
290 return ret;
293 static int net_registry_deletekey(struct net_context *c, int argc,
294 const char **argv)
296 return net_registry_deletekey_internal(c, argc, argv, false);
299 static int net_registry_deletekey_recursive(struct net_context *c, int argc,
300 const char **argv)
302 return net_registry_deletekey_internal(c, argc, argv, true);
305 static int net_registry_getvalue_internal(struct net_context *c, int argc,
306 const char **argv, bool raw)
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();
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;
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;
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;
334 print_registry_value(value, raw);
336 ret = 0;
338 done:
339 TALLOC_FREE(ctx);
340 return ret;
343 static int net_registry_getvalue(struct net_context *c, int argc,
344 const char **argv)
346 return net_registry_getvalue_internal(c, argc, argv, false);
349 static int net_registry_getvalueraw(struct net_context *c, int argc,
350 const char **argv)
352 return net_registry_getvalue_internal(c, argc, argv, true);
355 static int net_registry_getvaluesraw(struct net_context *c, int argc,
356 const char **argv)
358 WERROR werr;
359 int ret = -1;
360 struct registry_key *key = NULL;
361 TALLOC_CTX *ctx = talloc_stackframe();
362 uint32_t idx;
364 if (argc != 1 || c->display_usage) {
365 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
366 "<key>\n");
367 goto done;
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;
376 idx = 0;
377 while (true) {
378 struct registry_value *val;
380 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
382 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
383 ret = 0;
384 break;
386 if (!W_ERROR_IS_OK(werr)) {
387 break;
389 print_registry_value(val, true);
390 TALLOC_FREE(val);
391 idx += 1;
393 done:
394 TALLOC_FREE(ctx);
395 return ret;
398 static int net_registry_setvalue(struct net_context *c, int argc,
399 const char **argv)
401 WERROR werr;
402 struct registry_value value;
403 struct registry_key *key = NULL;
404 int ret = -1;
405 TALLOC_CTX *ctx = talloc_stackframe();
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;
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;
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;
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;
439 for (i=0; i < count; i++) {
440 array[i] = talloc_strdup(array, argv[count+i]);
441 if (array[i] == NULL) {
442 goto done;
445 if (!push_reg_multi_sz(ctx, &value.data, array)) {
446 goto done;
448 } else {
449 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
450 goto done;
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;
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;
466 ret = 0;
468 done:
469 TALLOC_FREE(ctx);
470 return ret;
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;
481 static void net_registry_increment_fn(void *private_data)
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;
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;
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;
504 if (value->type != REG_DWORD) {
505 d_fprintf(stderr, _("value not a DWORD: %s\n"),
506 str_regtype(value->type));
507 goto done;
510 if (value->data.length < 4) {
511 d_fprintf(stderr, _("value too short for regular DWORD\n"));
512 goto done;
515 v = IVAL(value->data.data, 0);
516 v += state->increment;
517 state->newvalue = v;
519 SIVAL(value->data.data, 0, v);
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;
528 done:
529 TALLOC_FREE(key);
530 return;
533 static int net_registry_increment(struct net_context *c, int argc,
534 const char **argv)
536 struct net_registry_increment_state state;
537 NTSTATUS status;
538 int ret = -1;
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;
548 state.keyname = argv[0];
549 state.valuename = argv[1];
551 state.increment = 1;
552 if (argc == 3) {
553 state.increment = strtoul(argv[2], NULL, 10);
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;
564 if (!W_ERROR_IS_OK(state.werr)) {
565 d_fprintf(stderr, _("increment failed: %s\n"),
566 win_errstr(state.werr));
567 goto done;
570 d_printf(_("%u\n"), (unsigned)state.newvalue);
572 ret = 0;
574 done:
575 return ret;
578 static int net_registry_deletevalue(struct net_context *c, int argc,
579 const char **argv)
581 WERROR werr;
582 struct registry_key *key = NULL;
583 TALLOC_CTX *ctx = talloc_stackframe();
584 int ret = -1;
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;
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;
599 werr = reg_deletevalue(key, argv[1]);
600 if (!W_ERROR_IS_OK(werr)) {
601 d_fprintf(stderr, _("reg_deletekey failed: %s\n"),
602 win_errstr(werr));
603 goto done;
606 ret = 0;
608 done:
609 TALLOC_FREE(ctx);
610 return ret;
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)
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;
626 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
627 * is denied with these perms right now...
629 access_mask = REG_KEY_READ;
631 if (sd == NULL) {
632 d_fprintf(stderr, _("internal error: invalid argument\n"));
633 werr = WERR_INVALID_PARAM;
634 goto done;
637 if (strlen(keyname) == 0) {
638 d_fprintf(stderr, _("error: zero length key name given\n"));
639 werr = WERR_INVALID_PARAM;
640 goto done;
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;
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;
657 werr = WERR_OK;
659 done:
660 TALLOC_FREE(ctx);
661 return werr;
664 static int net_registry_getsd(struct net_context *c, int argc,
665 const char **argv)
667 WERROR werr;
668 int ret = -1;
669 struct security_descriptor *secdesc = NULL;
670 TALLOC_CTX *ctx = talloc_stackframe();
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;
682 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
683 if (!W_ERROR_IS_OK(werr)) {
684 goto done;
687 display_sec_desc(secdesc);
689 ret = 0;
691 done:
692 TALLOC_FREE(ctx);
693 return ret;
696 static int net_registry_getsd_sddl(struct net_context *c,
697 int argc, const char **argv)
699 WERROR werr;
700 int ret = -1;
701 struct security_descriptor *secdesc = NULL;
702 TALLOC_CTX *ctx = talloc_stackframe();
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;
714 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
715 if (!W_ERROR_IS_OK(werr)) {
716 goto done;
719 d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
721 ret = 0;
723 done:
724 TALLOC_FREE(ctx);
725 return ret;
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)
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;
741 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
742 * is denied with these perms right now...
744 access_mask = REG_KEY_WRITE;
746 if (strlen(keyname) == 0) {
747 d_fprintf(stderr, _("error: zero length key name given\n"));
748 werr = WERR_INVALID_PARAM;
749 goto done;
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;
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;
766 werr = WERR_OK;
768 done:
769 TALLOC_FREE(ctx);
770 return werr;
773 static int net_registry_setsd_sddl(struct net_context *c,
774 int argc, const char **argv)
776 WERROR werr;
777 int ret = -1;
778 struct security_descriptor *secdesc = NULL;
779 TALLOC_CTX *ctx = talloc_stackframe();
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;
791 secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
792 if (secdesc == NULL) {
793 goto done;
796 werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
797 if (!W_ERROR_IS_OK(werr)) {
798 goto done;
801 ret = 0;
803 done:
804 TALLOC_FREE(ctx);
805 return ret;
808 /******************************************************************************/
810 * @defgroup net_registry net registry
814 * @defgroup net_registry_import Import
815 * @ingroup net_registry
816 * @{
819 struct import_ctx {
820 TALLOC_CTX *mem_ctx;
824 static WERROR import_create_key(struct import_ctx* ctx,
825 struct registry_key* parent,
826 const char* name, void** pkey, bool* existing)
828 WERROR werr;
829 void* mem_ctx = talloc_new(ctx->mem_ctx);
831 struct registry_key* key = NULL;
832 enum winreg_CreateAction action;
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;
843 name = subkeyname;
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;
855 if (action == REG_ACTION_NONE) {
856 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
857 werr = WERR_CREATE_FAILED;
858 goto done;
861 if (existing != NULL) {
862 *existing = (action == REG_OPENED_EXISTING_KEY);
865 if (pkey!=NULL) {
866 *pkey = talloc_steal(ctx->mem_ctx, key);
869 done:
870 talloc_free(mem_ctx);
871 return werr;
874 static WERROR import_close_key(struct import_ctx* ctx,
875 struct registry_key* key)
877 return WERR_OK;
880 static WERROR import_delete_key(struct import_ctx* ctx,
881 struct registry_key* parent, const char* name)
883 WERROR werr;
884 void* mem_ctx = talloc_new(talloc_tos());
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;
895 name = subkeyname;
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;
905 done:
906 talloc_free(mem_ctx);
907 return werr;
910 static WERROR import_create_val (struct import_ctx* ctx,
911 struct registry_key* parent, const char* name,
912 const struct registry_value* value)
914 WERROR werr;
916 if (parent == NULL) {
917 return WERR_INVALID_PARAM;
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));
925 return werr;
928 static WERROR import_delete_val (struct import_ctx* ctx, struct registry_key* parent, const char* name) {
929 WERROR werr;
931 if (parent == NULL) {
932 return WERR_INVALID_PARAM;
935 werr = reg_deletevalue(parent, name);
936 if (!W_ERROR_IS_OK(werr)) {
937 d_fprintf(stderr, _("reg_deletekey failed: %s\n"),
938 win_errstr(werr));
941 return werr;
945 static int net_registry_import(struct net_context *c, int argc,
946 const char **argv)
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
961 int ret;
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;
973 ZERO_STRUCT(import_ctx);
974 import_ctx.mem_ctx = talloc_stackframe();
976 regdb_open();
977 regdb_transaction_start();
979 ret = reg_parse_file(argv[0],
980 reg_import_adapter(import_ctx.mem_ctx,
981 import_callback),
982 (argc > 1) ? argv[1] : NULL
984 if (ret < 0) {
985 d_printf("reg_parse_file failed: transaction canceled\n");
986 regdb_transaction_cancel();
987 } else{
988 regdb_transaction_commit();
991 regdb_close();
992 talloc_free(import_ctx.mem_ctx);
994 return ret;
996 /**@}*/
998 /******************************************************************************/
1001 * @defgroup net_registry_export Export
1002 * @ingroup net_registry
1003 * @{
1006 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key* key,
1007 struct reg_format* f)
1009 int ret=-1;
1010 WERROR werr;
1011 uint32_t count;
1013 struct registry_value *valvalue = NULL;
1014 char *valname = NULL;
1016 struct registry_key* subkey = NULL;
1017 char *subkey_name = NULL;
1018 NTTIME modtime = 0;
1020 reg_format_registry_key(f, key, false);
1022 /* print values */
1023 for (count = 0;
1024 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1025 W_ERROR_IS_OK(werr);
1026 count++)
1028 reg_format_registry_value(f, valname, valvalue);
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;
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++)
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;
1050 registry_export(ctx, subkey, f);
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;
1057 ret = 0;
1058 done:
1059 return ret;
1062 static int net_registry_export(struct net_context *c, int argc,
1063 const char **argv)
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;
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;
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;
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;
1094 ret = registry_export(ctx, key, f);
1096 done:
1097 TALLOC_FREE(ctx);
1098 return ret;
1100 /**@}*/
1102 /******************************************************************************/
1104 * @defgroup net_registry_convert Convert
1105 * @ingroup net_registry
1106 * @{
1109 static int net_registry_convert(struct net_context *c, int argc,
1110 const char **argv)
1112 int ret;
1113 void* mem_ctx;
1114 const char* in_opt = NULL;
1115 const char* out_opt = NULL;
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;
1128 mem_ctx = talloc_stackframe();
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);
1145 ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1146 reg_format_file(mem_ctx, argv[1], out_opt),
1147 in_opt);
1149 talloc_free(mem_ctx);
1151 return ret;
1153 /**@}*/
1155 /******************************************************************************/
1157 int net_registry(struct net_context *c, int argc, const char **argv)
1159 int ret = -1;
1161 struct functable func[] = {
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")
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")
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")
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")
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")
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)")
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)"
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")
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")
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")
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")
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")
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")
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")
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")
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")
1290 { NULL, NULL, 0, NULL, NULL }
1293 if (!W_ERROR_IS_OK(registry_init_basic())) {
1294 return -1;
1297 ret = net_run_function(c, argc, argv, "net registry", func);
1299 return ret;