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/>.
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 "registry/reg_api_util.h"
35 #include "../libcli/security/display_sec.h"
36 #include "../libcli/security/sddl.h"
37 #include "../libcli/registry/util_reg.h"
38 #include "passdb/machine_sid.h"
39 #include "net_registry_check.h"
40 #include "lib/util/util_tdb.h"
49 * split given path into hive and remaining path and open the hive key
51 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
52 uint32_t desired_access,
53 struct registry_key **hive,
57 struct security_token *token = NULL;
58 char *hivename = NULL;
59 char *tmp_subkeyname = NULL;
60 TALLOC_CTX *tmp_ctx = talloc_stackframe();
62 if ((hive == NULL) || (subkeyname == NULL)) {
63 werr = WERR_INVALID_PARAMETER;
67 werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
68 if (!W_ERROR_IS_OK(werr)) {
71 *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
72 if (*subkeyname == NULL) {
73 werr = WERR_NOT_ENOUGH_MEMORY;
77 werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
78 if (!W_ERROR_IS_OK(werr)) {
82 werr = reg_openhive(ctx, hivename, desired_access, token, hive);
83 if (!W_ERROR_IS_OK(werr)) {
94 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
95 uint32_t desired_access,
96 struct registry_key **key)
99 char *subkey_name = NULL;
100 struct registry_key *hive = NULL;
101 TALLOC_CTX *tmp_ctx = talloc_stackframe();
103 if ((path == NULL) || (key == NULL)) {
104 return WERR_INVALID_PARAMETER;
107 werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
108 if (!W_ERROR_IS_OK(werr)) {
109 d_fprintf(stderr, _("open_hive failed: %s\n"),
114 werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
115 if (!W_ERROR_IS_OK(werr)) {
116 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
124 TALLOC_FREE(tmp_ctx);
128 static WERROR registry_enumkey(struct registry_key *parent, const char *keyname,
132 TALLOC_CTX *ctx = talloc_stackframe();
136 char *valname = NULL;
137 struct registry_value *valvalue = NULL;
138 struct registry_key *key = NULL;
140 werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
141 if (!W_ERROR_IS_OK(werr)) {
146 printf("[%s]\n\n", key->key->name);
149 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
153 print_registry_key(subkey_name, &modtime);
155 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
161 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
165 print_registry_value_with_name(valname, valvalue);
167 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
177 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
181 werr = registry_enumkey(key, subkey_name, recursive);
182 if (!W_ERROR_IS_OK(werr)) {
186 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
201 * the main "net registry" function implementations
204 static int net_registry_enumerate(struct net_context *c, int argc,
208 struct registry_key *key = NULL;
210 TALLOC_CTX *ctx = talloc_stackframe();
213 if (argc != 1 || c->display_usage) {
216 _("net registry enumerate <path>\n"));
219 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
223 werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
224 if (!W_ERROR_IS_OK(werr)) {
225 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
229 werr = registry_enumkey(key, name, c->opt_reboot);
230 if (W_ERROR_IS_OK(werr)) {
238 static int net_registry_enumerate_recursive(struct net_context *c, int argc,
242 struct registry_key *key = NULL;
244 TALLOC_CTX *ctx = talloc_stackframe();
247 if (argc != 1 || c->display_usage) {
250 _("net registry enumerate <path>\n"));
253 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
257 werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
258 if (!W_ERROR_IS_OK(werr)) {
259 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
263 werr = registry_enumkey(key, name, true);
264 if (W_ERROR_IS_OK(werr)) {
273 static int net_registry_createkey(struct net_context *c, int argc,
277 enum winreg_CreateAction action;
278 char *subkeyname = NULL;
279 struct registry_key *hivekey = NULL;
280 struct registry_key *subkey = NULL;
281 TALLOC_CTX *ctx = talloc_stackframe();
284 if (argc != 1 || c->display_usage) {
287 _("net registry createkey <path>\n"));
290 _("net registry createkey "
291 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
294 if (strlen(argv[0]) == 0) {
295 d_fprintf(stderr, _("error: zero length key name given\n"));
299 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
300 if (!W_ERROR_IS_OK(werr)) {
301 d_fprintf(stderr, _("open_hive failed: %s\n"),
306 werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
308 if (!W_ERROR_IS_OK(werr)) {
309 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
314 case REG_ACTION_NONE:
315 d_printf(_("createkey did nothing -- huh?\n"));
317 case REG_CREATED_NEW_KEY:
318 d_printf(_("createkey created %s\n"), argv[0]);
320 case REG_OPENED_EXISTING_KEY:
321 d_printf(_("createkey opened existing %s\n"), argv[0]);
332 static int net_registry_deletekey_internal(struct net_context *c, int argc,
337 char *subkeyname = NULL;
338 struct registry_key *hivekey = NULL;
339 TALLOC_CTX *ctx = talloc_stackframe();
342 if (argc != 1 || c->display_usage) {
345 _("net registry deletekey <path>\n"));
348 _("net registry deletekey "
349 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
352 if (strlen(argv[0]) == 0) {
353 d_fprintf(stderr, _("error: zero length key name given\n"));
357 werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
358 if (!W_ERROR_IS_OK(werr)) {
359 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
365 werr = reg_deletekey_recursive(hivekey, subkeyname);
367 werr = reg_deletekey(hivekey, subkeyname);
369 if (!W_ERROR_IS_OK(werr) &&
370 !(c->opt_force && W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)))
372 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
384 static int net_registry_deletekey(struct net_context *c, int argc,
387 return net_registry_deletekey_internal(c, argc, argv, false);
390 static int net_registry_deletekey_recursive(struct net_context *c, int argc,
393 return net_registry_deletekey_internal(c, argc, argv, true);
396 static int net_registry_getvalue_internal(struct net_context *c, int argc,
397 const char **argv, bool raw)
401 struct registry_key *key = NULL;
402 struct registry_value *value = NULL;
403 TALLOC_CTX *ctx = talloc_stackframe();
405 if (argc != 2 || c->display_usage) {
406 d_fprintf(stderr, "%s\n%s",
408 _("net registry getvalue <key> <valuename>\n"));
412 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
413 if (!W_ERROR_IS_OK(werr)) {
414 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
418 werr = reg_queryvalue(ctx, key, argv[1], &value);
419 if (!W_ERROR_IS_OK(werr)) {
420 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
425 print_registry_value(value, raw);
434 static int net_registry_getvalue(struct net_context *c, int argc,
437 return net_registry_getvalue_internal(c, argc, argv, false);
440 static int net_registry_getvalueraw(struct net_context *c, int argc,
443 return net_registry_getvalue_internal(c, argc, argv, true);
446 static int net_registry_getvaluesraw(struct net_context *c, int argc,
451 struct registry_key *key = NULL;
452 TALLOC_CTX *ctx = talloc_stackframe();
455 if (argc != 1 || c->display_usage) {
456 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
461 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
462 if (!W_ERROR_IS_OK(werr)) {
463 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
469 struct registry_value *val;
471 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
473 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
477 if (!W_ERROR_IS_OK(werr)) {
480 print_registry_value(val, true);
489 static int net_registry_setvalue(struct net_context *c, int argc,
493 struct registry_value value;
494 struct registry_key *key = NULL;
496 TALLOC_CTX *ctx = talloc_stackframe();
498 if (argc < 4 || c->display_usage) {
499 d_fprintf(stderr, "%s\n%s",
501 _("net registry setvalue <key> <valuename> "
502 "<type> [<val>]+\n"));
506 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
507 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
511 if (strequal(argv[2], "dword")) {
515 v = strtoul_err(argv[3], NULL, 10, &error);
520 value.type = REG_DWORD;
521 value.data = data_blob_talloc(ctx, NULL, 4);
522 SIVAL(value.data.data, 0, v);
523 } else if (strequal(argv[2], "sz")) {
525 if (!push_reg_sz(ctx, &value.data, argv[3])) {
528 } else if (strequal(argv[2], "multi_sz")) {
530 int count = argc - 3;
532 value.type = REG_MULTI_SZ;
533 array = talloc_zero_array(ctx, const char *, count + 1);
537 for (i=0; i < count; i++) {
538 array[i] = talloc_strdup(array, argv[count+i]);
539 if (array[i] == NULL) {
543 if (!push_reg_multi_sz(ctx, &value.data, array)) {
547 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
551 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
552 if (!W_ERROR_IS_OK(werr)) {
553 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
557 werr = reg_setvalue(key, argv[1], &value);
558 if (!W_ERROR_IS_OK(werr)) {
559 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
571 struct net_registry_increment_state {
573 const char *valuename;
579 static void net_registry_increment_fn(void *private_data)
581 struct net_registry_increment_state *state =
582 (struct net_registry_increment_state *)private_data;
583 struct registry_value *value;
584 struct registry_key *key = NULL;
587 state->werr = open_key(talloc_tos(), state->keyname,
588 REG_KEY_READ|REG_KEY_WRITE, &key);
589 if (!W_ERROR_IS_OK(state->werr)) {
590 d_fprintf(stderr, _("open_key failed: %s\n"),
591 win_errstr(state->werr));
595 state->werr = reg_queryvalue(key, key, state->valuename, &value);
596 if (!W_ERROR_IS_OK(state->werr)) {
597 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
598 win_errstr(state->werr));
602 if (value->type != REG_DWORD) {
603 d_fprintf(stderr, _("value not a DWORD: %s\n"),
604 str_regtype(value->type));
608 if (value->data.length < 4) {
609 d_fprintf(stderr, _("value too short for regular DWORD\n"));
613 v = IVAL(value->data.data, 0);
614 v += state->increment;
617 SIVAL(value->data.data, 0, v);
619 state->werr = reg_setvalue(key, state->valuename, value);
620 if (!W_ERROR_IS_OK(state->werr)) {
621 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
622 win_errstr(state->werr));
631 static int net_registry_increment(struct net_context *c, int argc,
634 struct net_registry_increment_state state;
638 if (argc < 2 || c->display_usage) {
639 d_fprintf(stderr, "%s\n%s",
641 _("net registry increment <key> <valuename> "
646 state.keyname = argv[0];
647 state.valuename = argv[1];
653 state.increment = strtoul_err(argv[2], NULL, 10, &error);
659 status = g_lock_do(string_term_tdb_data("registry_increment_lock"),
660 G_LOCK_WRITE, timeval_set(600, 0),
661 net_registry_increment_fn, &state);
662 if (!NT_STATUS_IS_OK(status)) {
663 d_fprintf(stderr, _("g_lock_do failed: %s\n"),
667 if (!W_ERROR_IS_OK(state.werr)) {
668 d_fprintf(stderr, _("increment failed: %s\n"),
669 win_errstr(state.werr));
673 d_printf(_("%u\n"), (unsigned)state.newvalue);
681 static int net_registry_deletevalue(struct net_context *c, int argc,
685 struct registry_key *key = NULL;
686 TALLOC_CTX *ctx = talloc_stackframe();
689 if (argc != 2 || c->display_usage) {
690 d_fprintf(stderr, "%s\n%s",
692 _("net registry deletevalue <key> <valuename>\n"));
696 werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
697 if (!W_ERROR_IS_OK(werr)) {
698 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
702 werr = reg_deletevalue(key, argv[1]);
703 if (!W_ERROR_IS_OK(werr)) {
704 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
716 static WERROR net_registry_getsd_internal(struct net_context *c,
719 struct security_descriptor **sd)
722 struct registry_key *key = NULL;
723 TALLOC_CTX *ctx = talloc_stackframe();
724 uint32_t access_mask = REG_KEY_READ |
725 SEC_FLAG_MAXIMUM_ALLOWED |
726 SEC_FLAG_SYSTEM_SECURITY;
729 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
730 * is denied with these perms right now...
732 access_mask = REG_KEY_READ;
735 d_fprintf(stderr, _("internal error: invalid argument\n"));
736 werr = WERR_INVALID_PARAMETER;
740 if (strlen(keyname) == 0) {
741 d_fprintf(stderr, _("error: zero length key name given\n"));
742 werr = WERR_INVALID_PARAMETER;
746 werr = open_key(ctx, keyname, access_mask, &key);
747 if (!W_ERROR_IS_OK(werr)) {
748 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
753 werr = reg_getkeysecurity(mem_ctx, key, sd);
754 if (!W_ERROR_IS_OK(werr)) {
755 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
767 static int net_registry_getsd(struct net_context *c, int argc,
772 struct security_descriptor *secdesc = NULL;
773 TALLOC_CTX *ctx = talloc_stackframe();
775 if (argc != 1 || c->display_usage) {
778 _("net registry getsd <path>\n"));
781 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
785 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
786 if (!W_ERROR_IS_OK(werr)) {
790 display_sec_desc(secdesc);
799 static int net_registry_getsd_sddl(struct net_context *c,
800 int argc, const char **argv)
804 struct security_descriptor *secdesc = NULL;
805 TALLOC_CTX *ctx = talloc_stackframe();
807 if (argc != 1 || c->display_usage) {
810 _("net registry getsd_sddl <path>\n"));
813 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
817 werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
818 if (!W_ERROR_IS_OK(werr)) {
822 d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
831 static WERROR net_registry_setsd_internal(struct net_context *c,
834 struct security_descriptor *sd)
837 struct registry_key *key = NULL;
838 TALLOC_CTX *ctx = talloc_stackframe();
839 uint32_t access_mask = REG_KEY_WRITE |
840 SEC_FLAG_MAXIMUM_ALLOWED |
841 SEC_FLAG_SYSTEM_SECURITY;
844 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
845 * is denied with these perms right now...
847 access_mask = REG_KEY_WRITE;
849 if (strlen(keyname) == 0) {
850 d_fprintf(stderr, _("error: zero length key name given\n"));
851 werr = WERR_INVALID_PARAMETER;
855 werr = open_key(ctx, keyname, access_mask, &key);
856 if (!W_ERROR_IS_OK(werr)) {
857 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
862 werr = reg_setkeysecurity(key, sd);
863 if (!W_ERROR_IS_OK(werr)) {
864 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
876 static int net_registry_setsd_sddl(struct net_context *c,
877 int argc, const char **argv)
881 struct security_descriptor *secdesc = NULL;
882 TALLOC_CTX *ctx = talloc_stackframe();
884 if (argc != 2 || c->display_usage) {
887 _("net registry setsd_sddl <path> <security_descriptor>\n"));
890 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
894 secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
895 if (secdesc == NULL) {
899 werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
900 if (!W_ERROR_IS_OK(werr)) {
911 /******************************************************************************/
913 * @defgroup net_registry net registry
917 * @defgroup net_registry_import Import
918 * @ingroup net_registry
927 static WERROR import_create_key(struct import_ctx *ctx,
928 struct registry_key *parent,
929 const char *name, void **pkey, bool *existing)
932 TALLOC_CTX *mem_ctx = talloc_new(ctx->mem_ctx);
934 struct registry_key *key = NULL;
935 enum winreg_CreateAction action;
937 if (parent == NULL) {
938 char *subkeyname = NULL;
939 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
940 &parent, &subkeyname);
941 if (!W_ERROR_IS_OK(werr)) {
942 d_fprintf(stderr, _("open_hive failed: %s\n"),
949 action = REG_ACTION_NONE;
950 werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
952 if (!W_ERROR_IS_OK(werr)) {
953 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
958 if (action == REG_ACTION_NONE) {
959 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
960 werr = WERR_CREATE_FAILED;
964 if (existing != NULL) {
965 *existing = (action == REG_OPENED_EXISTING_KEY);
969 *pkey = talloc_steal(ctx->mem_ctx, key);
973 talloc_free(mem_ctx);
977 static WERROR import_close_key(struct import_ctx *ctx,
978 struct registry_key *key)
983 static WERROR import_delete_key(struct import_ctx *ctx,
984 struct registry_key *parent, const char *name)
987 TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
989 if (parent == NULL) {
990 char *subkeyname = NULL;
991 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
992 &parent, &subkeyname);
993 if (!W_ERROR_IS_OK(werr)) {
994 d_fprintf(stderr, _("open_hive failed: %s\n"),
1001 werr = reg_deletekey_recursive(parent, name);
1002 if (!W_ERROR_IS_OK(werr)) {
1003 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n",
1004 _("failed"), win_errstr(werr));
1009 talloc_free(mem_ctx);
1013 static WERROR import_create_val (struct import_ctx *ctx,
1014 struct registry_key *parent, const char *name,
1015 const struct registry_value *value)
1019 if (parent == NULL) {
1020 return WERR_INVALID_PARAMETER;
1023 werr = reg_setvalue(parent, name, value);
1024 if (!W_ERROR_IS_OK(werr)) {
1025 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
1031 static WERROR import_delete_val (struct import_ctx *ctx,
1032 struct registry_key *parent, const char *name)
1036 if (parent == NULL) {
1037 return WERR_INVALID_PARAMETER;
1040 werr = reg_deletevalue(parent, name);
1041 if (!W_ERROR_IS_OK(werr)) {
1042 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
1049 struct precheck_ctx {
1050 TALLOC_CTX *mem_ctx;
1054 static WERROR precheck_create_key(struct precheck_ctx *ctx,
1055 struct registry_key *parent,
1056 const char *name, void **pkey, bool *existing)
1059 TALLOC_CTX *frame = talloc_stackframe();
1060 struct registry_key *key = NULL;
1062 if (parent == NULL) {
1063 char *subkeyname = NULL;
1064 werr = open_hive(frame, name, REG_KEY_READ,
1065 &parent, &subkeyname);
1066 if (!W_ERROR_IS_OK(werr)) {
1067 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1068 name, win_errstr(werr));
1074 werr = reg_openkey(frame, parent, name, 0, &key);
1075 if (!W_ERROR_IS_OK(werr)) {
1076 d_printf("Precheck: openkey [%s] failed: %s\n",
1077 name, win_errstr(werr));
1081 if (existing != NULL) {
1086 *pkey = talloc_steal(ctx->mem_ctx, key);
1091 ctx->failed = !W_ERROR_IS_OK(werr);
1095 static WERROR precheck_close_key(struct precheck_ctx *ctx,
1096 struct registry_key *key)
1102 static WERROR precheck_delete_key(struct precheck_ctx *ctx,
1103 struct registry_key *parent, const char *name)
1106 TALLOC_CTX *frame = talloc_stackframe();
1107 struct registry_key *key;
1109 if (parent == NULL) {
1110 char *subkeyname = NULL;
1111 werr = open_hive(frame, name, REG_KEY_READ,
1112 &parent, &subkeyname);
1113 if (!W_ERROR_IS_OK(werr)) {
1114 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1115 name, win_errstr(werr));
1121 werr = reg_openkey(ctx->mem_ctx, parent, name, 0, &key);
1122 if (W_ERROR_IS_OK(werr)) {
1123 d_printf("Precheck: key [%s\\%s] should not exist\n",
1124 parent->key->name, name);
1125 werr = WERR_FILE_EXISTS;
1126 } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1129 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1130 parent->key->name, name, win_errstr(werr));
1135 ctx->failed = !W_ERROR_IS_OK(werr);
1139 static WERROR precheck_create_val(struct precheck_ctx *ctx,
1140 struct registry_key *parent,
1142 const struct registry_value *value)
1144 TALLOC_CTX *frame = talloc_stackframe();
1145 struct registry_value *old;
1150 werr = reg_queryvalue(frame, parent, name, &old);
1151 if (!W_ERROR_IS_OK(werr)) {
1152 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1153 name, parent->key->name, win_errstr(werr));
1156 if (registry_value_cmp(value, old) != 0) {
1157 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1158 name, parent->key->name);
1166 static WERROR precheck_delete_val(struct precheck_ctx *ctx,
1167 struct registry_key *parent,
1170 TALLOC_CTX *frame = talloc_stackframe();
1171 struct registry_value *old;
1176 werr = reg_queryvalue(frame, parent, name, &old);
1177 if (W_ERROR_IS_OK(werr)) {
1178 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1179 name, parent->key->name);
1180 werr = WERR_FILE_EXISTS;
1181 } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
1184 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1185 name, parent->key->name, win_errstr(werr));
1189 ctx->failed = !W_ERROR_IS_OK(werr);
1193 static bool import_precheck(const char *fname, const char *parse_options)
1195 TALLOC_CTX *mem_ctx = talloc_tos();
1196 struct precheck_ctx precheck_ctx = {
1200 struct reg_import_callback precheck_callback = {
1202 .closekey = (reg_import_callback_closekey_t)&precheck_close_key,
1203 .createkey = (reg_import_callback_createkey_t)&precheck_create_key,
1204 .deletekey = (reg_import_callback_deletekey_t)&precheck_delete_key,
1205 .deleteval = (reg_import_callback_deleteval_t)&precheck_delete_val,
1207 .registry_value = (reg_import_callback_setval_registry_value_t)
1208 &precheck_create_val,
1210 .setval_type = REGISTRY_VALUE,
1211 .data = &precheck_ctx
1213 struct reg_parse_callback *parse_callback;
1220 parse_callback = reg_import_adapter(mem_ctx, precheck_callback);
1221 if (parse_callback == NULL) {
1222 d_printf("talloc failed\n");
1226 ret = reg_parse_file(fname, parse_callback, parse_options);
1228 if (ret < 0 || precheck_ctx.failed) {
1229 d_printf("Precheck failed\n");
1235 static int import_with_precheck_action(const char *import_fname,
1236 const char *precheck_fname,
1237 const char *parse_options)
1239 TALLOC_CTX *frame = talloc_stackframe();
1240 struct import_ctx import_ctx = {
1243 struct reg_import_callback import_callback = {
1245 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1246 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1247 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1248 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1250 .registry_value = (reg_import_callback_setval_registry_value_t)
1253 .setval_type = REGISTRY_VALUE,
1256 struct reg_parse_callback *parse_callback;
1260 precheck_ok = import_precheck(precheck_fname, parse_options);
1265 parse_callback = reg_import_adapter(frame, import_callback);
1266 if (parse_callback == NULL) {
1267 d_printf("talloc failed\n");
1271 ret = reg_parse_file(import_fname, parse_callback, parse_options);
1278 static int net_registry_import(struct net_context *c, int argc,
1281 const char *parse_options = (argc > 1) ? argv[1] : NULL;
1285 if (argc < 1 || argc > 2 || c->display_usage) {
1288 _("net registry import <reg> [options]\n"));
1291 _("net registry import file.reg enc=CP1252\n"));
1295 werr = regdb_open();
1296 if (!W_ERROR_IS_OK(werr)) {
1297 d_printf("Failed to open regdb: %s\n", win_errstr(werr));
1301 werr = regdb_transaction_start();
1302 if (!W_ERROR_IS_OK(werr)) {
1303 d_printf("Failed to start transaction on regdb: %s\n",
1308 ret = import_with_precheck_action(argv[0], c->opt_precheck,
1312 d_printf("Transaction canceled!\n");
1313 regdb_transaction_cancel();
1317 SMB_ASSERT(ret == 0);
1319 if (c->opt_testmode) {
1320 d_printf("Testmode: not committing changes.\n");
1321 regdb_transaction_cancel();
1325 werr = regdb_transaction_commit();
1326 if (!W_ERROR_IS_OK(werr)) {
1327 d_printf("Failed to commit transaction on regdb: %s\n",
1338 /******************************************************************************/
1341 * @defgroup net_registry_export Export
1342 * @ingroup net_registry
1346 static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key *key,
1347 struct reg_format *f)
1353 struct registry_value *valvalue = NULL;
1354 char *valname = NULL;
1356 char *subkey_name = NULL;
1359 reg_format_registry_key(f, key, false);
1363 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
1364 W_ERROR_IS_OK(werr);
1367 reg_format_registry_value(f, valname, valvalue);
1369 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1370 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
1375 /* recurse on subkeys */
1377 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
1378 W_ERROR_IS_OK(werr);
1381 struct registry_key *subkey = NULL;
1383 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
1385 if (!W_ERROR_IS_OK(werr)) {
1386 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
1391 registry_export(ctx, subkey, f);
1392 TALLOC_FREE(subkey);
1394 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
1395 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
1404 static int net_registry_export(struct net_context *c, int argc,
1409 struct registry_key *key = NULL;
1410 TALLOC_CTX *ctx = talloc_stackframe();
1411 struct reg_format *f=NULL;
1413 if (argc < 2 || argc > 3 || c->display_usage) {
1416 _("net registry export <path> <file> [opt]\n"));
1419 _("net registry export 'HKLM\\Software\\Samba' "
1420 "samba.reg regedit5\n"));
1424 werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
1425 if (!W_ERROR_IS_OK(werr)) {
1426 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
1430 f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1432 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1436 ret = registry_export(ctx, key, f);
1444 /******************************************************************************/
1446 * @defgroup net_registry_convert Convert
1447 * @ingroup net_registry
1451 static int net_registry_convert(struct net_context *c, int argc,
1455 TALLOC_CTX *mem_ctx;
1456 const char *in_opt = NULL;
1457 const char *out_opt = NULL;
1459 if (argc < 2 || argc > 4|| c->display_usage) {
1462 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1463 "net registry convert <in> <out> [out_opt]\n"));
1466 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1470 mem_ctx = talloc_stackframe();
1487 ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
1488 reg_format_file(mem_ctx, argv[1], out_opt),
1491 talloc_free(mem_ctx);
1497 static int net_registry_check(struct net_context *c, int argc,
1501 struct check_options opts;
1504 if (argc > 1|| c->display_usage) {
1507 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1508 " Check a registry database.\n"
1509 " -v|--verbose\t be verbose\n"
1510 " -r|--repair\t\t interactive repair mode\n"
1511 " -a|--auto\t\t noninteractive repair mode\n"
1512 " -T|--test\t\t dry run\n"
1513 " -f|--force\t\t force\n"
1514 " -l|--lock\t\t lock <TDB> while doing the check\n"
1515 " -o|--output=<ODB>\t output database\n"
1516 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1517 " --wipe\t\t create a new database from scratch\n"
1518 " --db=<TDB>\t\t registry database to open\n"));
1519 return c->display_usage ? 0 : -1;
1522 if (c->opt_db != NULL) {
1523 dbfile = talloc_strdup(talloc_tos(), c->opt_db);
1524 } else if (argc > 0) {
1525 dbfile = talloc_strdup(talloc_tos(), argv[0]);
1527 dbfile = state_path(talloc_tos(), "registry.tdb");
1529 if (dbfile == NULL) {
1533 opts = (struct check_options) {
1534 .lock = c->opt_lock || c->opt_long_list_entries,
1535 .test = c->opt_testmode,
1536 .automatic = c->opt_auto,
1537 .verbose = c->opt_verbose,
1538 .force = c->opt_force,
1539 .repair = c->opt_repair || c->opt_reboot,
1540 .version = c->opt_reg_version,
1541 .output = c->opt_output,
1542 .wipe = c->opt_wipe,
1543 .implicit_db = (c->opt_db == NULL) && (argc == 0),
1546 ret = net_registry_check_db(dbfile, &opts);
1547 talloc_free(dbfile);
1552 /******************************************************************************/
1554 int net_registry(struct net_context *c, int argc, const char **argv)
1558 struct functable func[] = {
1561 net_registry_enumerate,
1562 NET_TRANSPORT_LOCAL,
1563 N_("Enumerate registry keys and values"),
1564 N_("net registry enumerate\n"
1565 " Enumerate registry keys and values")
1568 "enumerate_recursive",
1569 net_registry_enumerate_recursive,
1570 NET_TRANSPORT_LOCAL,
1571 N_("Enumerate registry keys and values"),
1572 N_("net registry enumerate_recursive\n"
1573 " Enumerate registry keys and values")
1577 net_registry_createkey,
1578 NET_TRANSPORT_LOCAL,
1579 N_("Create a new registry key"),
1580 N_("net registry createkey\n"
1581 " Create a new registry key")
1585 net_registry_deletekey,
1586 NET_TRANSPORT_LOCAL,
1587 N_("Delete a registry key"),
1588 N_("net registry deletekey\n"
1589 " Delete a registry key")
1592 "deletekey_recursive",
1593 net_registry_deletekey_recursive,
1594 NET_TRANSPORT_LOCAL,
1595 N_("Delete a registry key with subkeys"),
1596 N_("net registry deletekey_recursive\n"
1597 " Delete a registry key with subkeys")
1601 net_registry_getvalue,
1602 NET_TRANSPORT_LOCAL,
1603 N_("Print a registry value"),
1604 N_("net registry getvalue\n"
1605 " Print a registry value")
1609 net_registry_getvalueraw,
1610 NET_TRANSPORT_LOCAL,
1611 N_("Print a registry value (raw format)"),
1612 N_("net registry getvalueraw\n"
1613 " Print a registry value (raw format)")
1617 net_registry_getvaluesraw,
1618 NET_TRANSPORT_LOCAL,
1619 "Print all values of a key in raw format",
1620 "net registry getvaluesraw <key>\n"
1621 " Print a registry value (raw format)"
1625 net_registry_setvalue,
1626 NET_TRANSPORT_LOCAL,
1627 N_("Set a new registry value"),
1628 N_("net registry setvalue\n"
1629 " Set a new registry value")
1633 net_registry_increment,
1634 NET_TRANSPORT_LOCAL,
1635 N_("Increment a DWORD registry value under a lock"),
1636 N_("net registry increment\n"
1637 " Increment a DWORD registry value under a lock")
1641 net_registry_deletevalue,
1642 NET_TRANSPORT_LOCAL,
1643 N_("Delete a registry value"),
1644 N_("net registry deletevalue\n"
1645 " Delete a registry value")
1650 NET_TRANSPORT_LOCAL,
1651 N_("Get security descriptor"),
1652 N_("net registry getsd\n"
1653 " Get security descriptor")
1657 net_registry_getsd_sddl,
1658 NET_TRANSPORT_LOCAL,
1659 N_("Get security descriptor in sddl format"),
1660 N_("net registry getsd_sddl\n"
1661 " Get security descriptor in sddl format")
1665 net_registry_setsd_sddl,
1666 NET_TRANSPORT_LOCAL,
1667 N_("Set security descriptor from sddl format string"),
1668 N_("net registry setsd_sddl\n"
1669 " Set security descriptor from sddl format string")
1673 net_registry_import,
1674 NET_TRANSPORT_LOCAL,
1675 N_("Import .reg file"),
1676 N_("net registry import\n"
1677 " Import .reg file")
1681 net_registry_export,
1682 NET_TRANSPORT_LOCAL,
1683 N_("Export .reg file"),
1684 N_("net registry export\n"
1685 " Export .reg file")
1689 net_registry_convert,
1690 NET_TRANSPORT_LOCAL,
1691 N_("Convert .reg file"),
1692 N_("net registry convert\n"
1693 " Convert .reg file")
1698 NET_TRANSPORT_LOCAL,
1699 N_("Check a registry database"),
1700 N_("net registry check\n"
1701 " Check a registry database")
1703 { NULL, NULL, 0, NULL, NULL }
1706 if (!c->display_usage
1708 && (strcasecmp_m(argv[0], "convert") != 0)
1709 && (strcasecmp_m(argv[0], "check") != 0))
1711 if (!W_ERROR_IS_OK(registry_init_basic())) {
1716 ret = net_run_function(c, argc, argv, "net registry", func);