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")) {
512 uint32_t v
= strtoul(argv
[3], NULL
, 10);
513 value
.type
= REG_DWORD
;
514 value
.data
= data_blob_talloc(ctx
, NULL
, 4);
515 SIVAL(value
.data
.data
, 0, v
);
516 } else if (strequal(argv
[2], "sz")) {
518 if (!push_reg_sz(ctx
, &value
.data
, argv
[3])) {
521 } else if (strequal(argv
[2], "multi_sz")) {
523 int count
= argc
- 3;
525 value
.type
= REG_MULTI_SZ
;
526 array
= talloc_zero_array(ctx
, const char *, count
+ 1);
530 for (i
=0; i
< count
; i
++) {
531 array
[i
] = talloc_strdup(array
, argv
[count
+i
]);
532 if (array
[i
] == NULL
) {
536 if (!push_reg_multi_sz(ctx
, &value
.data
, array
)) {
540 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
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
));
550 werr
= reg_setvalue(key
, argv
[1], &value
);
551 if (!W_ERROR_IS_OK(werr
)) {
552 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
564 struct net_registry_increment_state
{
566 const char *valuename
;
572 static void net_registry_increment_fn(void *private_data
)
574 struct net_registry_increment_state
*state
=
575 (struct net_registry_increment_state
*)private_data
;
576 struct registry_value
*value
;
577 struct registry_key
*key
= NULL
;
580 state
->werr
= open_key(talloc_tos(), state
->keyname
,
581 REG_KEY_READ
|REG_KEY_WRITE
, &key
);
582 if (!W_ERROR_IS_OK(state
->werr
)) {
583 d_fprintf(stderr
, _("open_key failed: %s\n"),
584 win_errstr(state
->werr
));
588 state
->werr
= reg_queryvalue(key
, key
, state
->valuename
, &value
);
589 if (!W_ERROR_IS_OK(state
->werr
)) {
590 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
591 win_errstr(state
->werr
));
595 if (value
->type
!= REG_DWORD
) {
596 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
597 str_regtype(value
->type
));
601 if (value
->data
.length
< 4) {
602 d_fprintf(stderr
, _("value too short for regular DWORD\n"));
606 v
= IVAL(value
->data
.data
, 0);
607 v
+= state
->increment
;
610 SIVAL(value
->data
.data
, 0, v
);
612 state
->werr
= reg_setvalue(key
, state
->valuename
, value
);
613 if (!W_ERROR_IS_OK(state
->werr
)) {
614 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
615 win_errstr(state
->werr
));
624 static int net_registry_increment(struct net_context
*c
, int argc
,
627 struct net_registry_increment_state state
;
631 if (argc
< 2 || c
->display_usage
) {
632 d_fprintf(stderr
, "%s\n%s",
634 _("net registry increment <key> <valuename> "
639 state
.keyname
= argv
[0];
640 state
.valuename
= argv
[1];
644 state
.increment
= strtoul(argv
[2], NULL
, 10);
647 status
= g_lock_do(string_term_tdb_data("registry_increment_lock"),
648 G_LOCK_WRITE
, timeval_set(600, 0),
649 net_registry_increment_fn
, &state
);
650 if (!NT_STATUS_IS_OK(status
)) {
651 d_fprintf(stderr
, _("g_lock_do failed: %s\n"),
655 if (!W_ERROR_IS_OK(state
.werr
)) {
656 d_fprintf(stderr
, _("increment failed: %s\n"),
657 win_errstr(state
.werr
));
661 d_printf(_("%u\n"), (unsigned)state
.newvalue
);
669 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
673 struct registry_key
*key
= NULL
;
674 TALLOC_CTX
*ctx
= talloc_stackframe();
677 if (argc
!= 2 || c
->display_usage
) {
678 d_fprintf(stderr
, "%s\n%s",
680 _("net registry deletevalue <key> <valuename>\n"));
684 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
685 if (!W_ERROR_IS_OK(werr
)) {
686 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
690 werr
= reg_deletevalue(key
, argv
[1]);
691 if (!W_ERROR_IS_OK(werr
)) {
692 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
704 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
707 struct security_descriptor
**sd
)
710 struct registry_key
*key
= NULL
;
711 TALLOC_CTX
*ctx
= talloc_stackframe();
712 uint32_t access_mask
= REG_KEY_READ
|
713 SEC_FLAG_MAXIMUM_ALLOWED
|
714 SEC_FLAG_SYSTEM_SECURITY
;
717 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
718 * is denied with these perms right now...
720 access_mask
= REG_KEY_READ
;
723 d_fprintf(stderr
, _("internal error: invalid argument\n"));
724 werr
= WERR_INVALID_PARAMETER
;
728 if (strlen(keyname
) == 0) {
729 d_fprintf(stderr
, _("error: zero length key name given\n"));
730 werr
= WERR_INVALID_PARAMETER
;
734 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
735 if (!W_ERROR_IS_OK(werr
)) {
736 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
741 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
742 if (!W_ERROR_IS_OK(werr
)) {
743 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
755 static int net_registry_getsd(struct net_context
*c
, int argc
,
760 struct security_descriptor
*secdesc
= NULL
;
761 TALLOC_CTX
*ctx
= talloc_stackframe();
763 if (argc
!= 1 || c
->display_usage
) {
766 _("net registry getsd <path>\n"));
769 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
773 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
774 if (!W_ERROR_IS_OK(werr
)) {
778 display_sec_desc(secdesc
);
787 static int net_registry_getsd_sddl(struct net_context
*c
,
788 int argc
, const char **argv
)
792 struct security_descriptor
*secdesc
= NULL
;
793 TALLOC_CTX
*ctx
= talloc_stackframe();
795 if (argc
!= 1 || c
->display_usage
) {
798 _("net registry getsd_sddl <path>\n"));
801 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
805 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
806 if (!W_ERROR_IS_OK(werr
)) {
810 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
819 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
822 struct security_descriptor
*sd
)
825 struct registry_key
*key
= NULL
;
826 TALLOC_CTX
*ctx
= talloc_stackframe();
827 uint32_t access_mask
= REG_KEY_WRITE
|
828 SEC_FLAG_MAXIMUM_ALLOWED
|
829 SEC_FLAG_SYSTEM_SECURITY
;
832 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
833 * is denied with these perms right now...
835 access_mask
= REG_KEY_WRITE
;
837 if (strlen(keyname
) == 0) {
838 d_fprintf(stderr
, _("error: zero length key name given\n"));
839 werr
= WERR_INVALID_PARAMETER
;
843 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
844 if (!W_ERROR_IS_OK(werr
)) {
845 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
850 werr
= reg_setkeysecurity(key
, sd
);
851 if (!W_ERROR_IS_OK(werr
)) {
852 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
864 static int net_registry_setsd_sddl(struct net_context
*c
,
865 int argc
, const char **argv
)
869 struct security_descriptor
*secdesc
= NULL
;
870 TALLOC_CTX
*ctx
= talloc_stackframe();
872 if (argc
!= 2 || c
->display_usage
) {
875 _("net registry setsd_sddl <path> <security_descriptor>\n"));
878 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
882 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
883 if (secdesc
== NULL
) {
887 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
888 if (!W_ERROR_IS_OK(werr
)) {
899 /******************************************************************************/
901 * @defgroup net_registry net registry
905 * @defgroup net_registry_import Import
906 * @ingroup net_registry
915 static WERROR
import_create_key(struct import_ctx
*ctx
,
916 struct registry_key
*parent
,
917 const char *name
, void **pkey
, bool *existing
)
920 TALLOC_CTX
*mem_ctx
= talloc_new(ctx
->mem_ctx
);
922 struct registry_key
*key
= NULL
;
923 enum winreg_CreateAction action
;
925 if (parent
== NULL
) {
926 char *subkeyname
= NULL
;
927 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
928 &parent
, &subkeyname
);
929 if (!W_ERROR_IS_OK(werr
)) {
930 d_fprintf(stderr
, _("open_hive failed: %s\n"),
937 action
= REG_ACTION_NONE
;
938 werr
= reg_createkey(mem_ctx
, parent
, name
, REG_KEY_WRITE
,
940 if (!W_ERROR_IS_OK(werr
)) {
941 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
946 if (action
== REG_ACTION_NONE
) {
947 d_fprintf(stderr
, _("createkey did nothing -- huh?\n"));
948 werr
= WERR_CREATE_FAILED
;
952 if (existing
!= NULL
) {
953 *existing
= (action
== REG_OPENED_EXISTING_KEY
);
957 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
961 talloc_free(mem_ctx
);
965 static WERROR
import_close_key(struct import_ctx
*ctx
,
966 struct registry_key
*key
)
971 static WERROR
import_delete_key(struct import_ctx
*ctx
,
972 struct registry_key
*parent
, const char *name
)
975 TALLOC_CTX
*mem_ctx
= talloc_new(talloc_tos());
977 if (parent
== NULL
) {
978 char *subkeyname
= NULL
;
979 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
980 &parent
, &subkeyname
);
981 if (!W_ERROR_IS_OK(werr
)) {
982 d_fprintf(stderr
, _("open_hive failed: %s\n"),
989 werr
= reg_deletekey_recursive(parent
, name
);
990 if (!W_ERROR_IS_OK(werr
)) {
991 d_fprintf(stderr
, "reg_deletekey_recursive %s: %s\n",
992 _("failed"), win_errstr(werr
));
997 talloc_free(mem_ctx
);
1001 static WERROR
import_create_val (struct import_ctx
*ctx
,
1002 struct registry_key
*parent
, const char *name
,
1003 const struct registry_value
*value
)
1007 if (parent
== NULL
) {
1008 return WERR_INVALID_PARAMETER
;
1011 werr
= reg_setvalue(parent
, name
, value
);
1012 if (!W_ERROR_IS_OK(werr
)) {
1013 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
1019 static WERROR
import_delete_val (struct import_ctx
*ctx
,
1020 struct registry_key
*parent
, const char *name
)
1024 if (parent
== NULL
) {
1025 return WERR_INVALID_PARAMETER
;
1028 werr
= reg_deletevalue(parent
, name
);
1029 if (!W_ERROR_IS_OK(werr
)) {
1030 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
1037 struct precheck_ctx
{
1038 TALLOC_CTX
*mem_ctx
;
1042 static WERROR
precheck_create_key(struct precheck_ctx
*ctx
,
1043 struct registry_key
*parent
,
1044 const char *name
, void **pkey
, bool *existing
)
1047 TALLOC_CTX
*frame
= talloc_stackframe();
1048 struct registry_key
*key
= NULL
;
1050 if (parent
== NULL
) {
1051 char *subkeyname
= NULL
;
1052 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1053 &parent
, &subkeyname
);
1054 if (!W_ERROR_IS_OK(werr
)) {
1055 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1056 name
, win_errstr(werr
));
1062 werr
= reg_openkey(frame
, parent
, name
, 0, &key
);
1063 if (!W_ERROR_IS_OK(werr
)) {
1064 d_printf("Precheck: openkey [%s] failed: %s\n",
1065 name
, win_errstr(werr
));
1069 if (existing
!= NULL
) {
1074 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
1079 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1083 static WERROR
precheck_close_key(struct precheck_ctx
*ctx
,
1084 struct registry_key
*key
)
1090 static WERROR
precheck_delete_key(struct precheck_ctx
*ctx
,
1091 struct registry_key
*parent
, const char *name
)
1094 TALLOC_CTX
*frame
= talloc_stackframe();
1095 struct registry_key
*key
;
1097 if (parent
== NULL
) {
1098 char *subkeyname
= NULL
;
1099 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1100 &parent
, &subkeyname
);
1101 if (!W_ERROR_IS_OK(werr
)) {
1102 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1103 name
, win_errstr(werr
));
1109 werr
= reg_openkey(ctx
->mem_ctx
, parent
, name
, 0, &key
);
1110 if (W_ERROR_IS_OK(werr
)) {
1111 d_printf("Precheck: key [%s\\%s] should not exist\n",
1112 parent
->key
->name
, name
);
1113 werr
= WERR_FILE_EXISTS
;
1114 } else if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1117 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1118 parent
->key
->name
, name
, win_errstr(werr
));
1123 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1127 static WERROR
precheck_create_val(struct precheck_ctx
*ctx
,
1128 struct registry_key
*parent
,
1130 const struct registry_value
*value
)
1132 TALLOC_CTX
*frame
= talloc_stackframe();
1133 struct registry_value
*old
;
1138 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1139 if (!W_ERROR_IS_OK(werr
)) {
1140 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1141 name
, parent
->key
->name
, win_errstr(werr
));
1144 if (registry_value_cmp(value
, old
) != 0) {
1145 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1146 name
, parent
->key
->name
);
1154 static WERROR
precheck_delete_val(struct precheck_ctx
*ctx
,
1155 struct registry_key
*parent
,
1158 TALLOC_CTX
*frame
= talloc_stackframe();
1159 struct registry_value
*old
;
1164 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1165 if (W_ERROR_IS_OK(werr
)) {
1166 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1167 name
, parent
->key
->name
);
1168 werr
= WERR_FILE_EXISTS
;
1169 } else if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1172 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1173 name
, parent
->key
->name
, win_errstr(werr
));
1177 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1181 static bool import_precheck(const char *fname
, const char *parse_options
)
1183 TALLOC_CTX
*mem_ctx
= talloc_tos();
1184 struct precheck_ctx precheck_ctx
= {
1188 struct reg_import_callback precheck_callback
= {
1190 .closekey
= (reg_import_callback_closekey_t
)&precheck_close_key
,
1191 .createkey
= (reg_import_callback_createkey_t
)&precheck_create_key
,
1192 .deletekey
= (reg_import_callback_deletekey_t
)&precheck_delete_key
,
1193 .deleteval
= (reg_import_callback_deleteval_t
)&precheck_delete_val
,
1195 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1196 &precheck_create_val
,
1198 .setval_type
= REGISTRY_VALUE
,
1199 .data
= &precheck_ctx
1201 struct reg_parse_callback
*parse_callback
;
1208 parse_callback
= reg_import_adapter(mem_ctx
, precheck_callback
);
1209 if (parse_callback
== NULL
) {
1210 d_printf("talloc failed\n");
1214 ret
= reg_parse_file(fname
, parse_callback
, parse_options
);
1216 if (ret
< 0 || precheck_ctx
.failed
) {
1217 d_printf("Precheck failed\n");
1223 static int import_with_precheck_action(const char *import_fname
,
1224 const char *precheck_fname
,
1225 const char *parse_options
)
1227 TALLOC_CTX
*frame
= talloc_stackframe();
1228 struct import_ctx import_ctx
= {
1231 struct reg_import_callback import_callback
= {
1233 .closekey
= (reg_import_callback_closekey_t
)&import_close_key
,
1234 .createkey
= (reg_import_callback_createkey_t
)&import_create_key
,
1235 .deletekey
= (reg_import_callback_deletekey_t
)&import_delete_key
,
1236 .deleteval
= (reg_import_callback_deleteval_t
)&import_delete_val
,
1238 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1241 .setval_type
= REGISTRY_VALUE
,
1244 struct reg_parse_callback
*parse_callback
;
1248 precheck_ok
= import_precheck(precheck_fname
, parse_options
);
1253 parse_callback
= reg_import_adapter(frame
, import_callback
);
1254 if (parse_callback
== NULL
) {
1255 d_printf("talloc failed\n");
1259 ret
= reg_parse_file(import_fname
, parse_callback
, parse_options
);
1266 static int net_registry_import(struct net_context
*c
, int argc
,
1269 const char *parse_options
= (argc
> 1) ? argv
[1] : NULL
;
1273 if (argc
< 1 || argc
> 2 || c
->display_usage
) {
1276 _("net registry import <reg> [options]\n"));
1279 _("net registry import file.reg enc=CP1252\n"));
1283 werr
= regdb_open();
1284 if (!W_ERROR_IS_OK(werr
)) {
1285 d_printf("Failed to open regdb: %s\n", win_errstr(werr
));
1289 werr
= regdb_transaction_start();
1290 if (!W_ERROR_IS_OK(werr
)) {
1291 d_printf("Failed to start transaction on regdb: %s\n",
1296 ret
= import_with_precheck_action(argv
[0], c
->opt_precheck
,
1300 d_printf("Transaction canceled!\n");
1301 regdb_transaction_cancel();
1305 SMB_ASSERT(ret
== 0);
1307 if (c
->opt_testmode
) {
1308 d_printf("Testmode: not committing changes.\n");
1309 regdb_transaction_cancel();
1313 werr
= regdb_transaction_commit();
1314 if (!W_ERROR_IS_OK(werr
)) {
1315 d_printf("Failed to commit transaction on regdb: %s\n",
1326 /******************************************************************************/
1329 * @defgroup net_registry_export Export
1330 * @ingroup net_registry
1334 static int registry_export(TALLOC_CTX
*ctx
, /*const*/ struct registry_key
*key
,
1335 struct reg_format
*f
)
1341 struct registry_value
*valvalue
= NULL
;
1342 char *valname
= NULL
;
1344 char *subkey_name
= NULL
;
1347 reg_format_registry_key(f
, key
, false);
1351 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
1352 W_ERROR_IS_OK(werr
);
1355 reg_format_registry_value(f
, valname
, valvalue
);
1357 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1358 d_fprintf(stderr
, _("reg_enumvalue failed: %s\n"),
1363 /* recurse on subkeys */
1365 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
1366 W_ERROR_IS_OK(werr
);
1369 struct registry_key
*subkey
= NULL
;
1371 werr
= reg_openkey(ctx
, key
, subkey_name
, REG_KEY_READ
,
1373 if (!W_ERROR_IS_OK(werr
)) {
1374 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
1379 registry_export(ctx
, subkey
, f
);
1380 TALLOC_FREE(subkey
);
1382 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1383 d_fprintf(stderr
, _("reg_enumkey failed: %s\n"),
1392 static int net_registry_export(struct net_context
*c
, int argc
,
1397 struct registry_key
*key
= NULL
;
1398 TALLOC_CTX
*ctx
= talloc_stackframe();
1399 struct reg_format
*f
=NULL
;
1401 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1404 _("net registry export <path> <file> [opt]\n"));
1407 _("net registry export 'HKLM\\Software\\Samba' "
1408 "samba.reg regedit5\n"));
1412 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
1413 if (!W_ERROR_IS_OK(werr
)) {
1414 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
1418 f
= reg_format_file(ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1420 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1424 ret
= registry_export(ctx
, key
, f
);
1432 /******************************************************************************/
1434 * @defgroup net_registry_convert Convert
1435 * @ingroup net_registry
1439 static int net_registry_convert(struct net_context
*c
, int argc
,
1443 TALLOC_CTX
*mem_ctx
;
1444 const char *in_opt
= NULL
;
1445 const char *out_opt
= NULL
;
1447 if (argc
< 2 || argc
> 4|| c
->display_usage
) {
1450 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1451 "net registry convert <in> <out> [out_opt]\n"));
1454 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1458 mem_ctx
= talloc_stackframe();
1475 ret
= reg_parse_file(argv
[0], (struct reg_parse_callback
*)
1476 reg_format_file(mem_ctx
, argv
[1], out_opt
),
1479 talloc_free(mem_ctx
);
1485 static int net_registry_check(struct net_context
*c
, int argc
,
1489 struct check_options opts
;
1492 if (argc
> 1|| c
->display_usage
) {
1495 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1496 " Check a registry database.\n"
1497 " -v|--verbose\t be verbose\n"
1498 " -r|--repair\t\t interactive repair mode\n"
1499 " -a|--auto\t\t noninteractive repair mode\n"
1500 " -T|--test\t\t dry run\n"
1501 " -f|--force\t\t force\n"
1502 " -l|--lock\t\t lock <TDB> while doing the check\n"
1503 " -o|--output=<ODB>\t output database\n"
1504 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1505 " --wipe\t\t create a new database from scratch\n"
1506 " --db=<TDB>\t\t registry database to open\n"));
1507 return c
->display_usage
? 0 : -1;
1510 if (c
->opt_db
!= NULL
) {
1511 dbfile
= talloc_strdup(talloc_tos(), c
->opt_db
);
1512 } else if (argc
> 0) {
1513 dbfile
= talloc_strdup(talloc_tos(), argv
[0]);
1515 dbfile
= state_path("registry.tdb");
1517 if (dbfile
== NULL
) {
1521 opts
= (struct check_options
) {
1522 .lock
= c
->opt_lock
|| c
->opt_long_list_entries
,
1523 .test
= c
->opt_testmode
,
1524 .automatic
= c
->opt_auto
,
1525 .verbose
= c
->opt_verbose
,
1526 .force
= c
->opt_force
,
1527 .repair
= c
->opt_repair
|| c
->opt_reboot
,
1528 .version
= c
->opt_reg_version
,
1529 .output
= c
->opt_output
,
1530 .wipe
= c
->opt_wipe
,
1531 .implicit_db
= (c
->opt_db
== NULL
) && (argc
== 0),
1534 ret
= net_registry_check_db(dbfile
, &opts
);
1535 talloc_free(dbfile
);
1540 /******************************************************************************/
1542 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
1546 struct functable func
[] = {
1549 net_registry_enumerate
,
1550 NET_TRANSPORT_LOCAL
,
1551 N_("Enumerate registry keys and values"),
1552 N_("net registry enumerate\n"
1553 " Enumerate registry keys and values")
1556 "enumerate_recursive",
1557 net_registry_enumerate_recursive
,
1558 NET_TRANSPORT_LOCAL
,
1559 N_("Enumerate registry keys and values"),
1560 N_("net registry enumerate_recursive\n"
1561 " Enumerate registry keys and values")
1565 net_registry_createkey
,
1566 NET_TRANSPORT_LOCAL
,
1567 N_("Create a new registry key"),
1568 N_("net registry createkey\n"
1569 " Create a new registry key")
1573 net_registry_deletekey
,
1574 NET_TRANSPORT_LOCAL
,
1575 N_("Delete a registry key"),
1576 N_("net registry deletekey\n"
1577 " Delete a registry key")
1580 "deletekey_recursive",
1581 net_registry_deletekey_recursive
,
1582 NET_TRANSPORT_LOCAL
,
1583 N_("Delete a registry key with subkeys"),
1584 N_("net registry deletekey_recursive\n"
1585 " Delete a registry key with subkeys")
1589 net_registry_getvalue
,
1590 NET_TRANSPORT_LOCAL
,
1591 N_("Print a registry value"),
1592 N_("net registry getvalue\n"
1593 " Print a registry value")
1597 net_registry_getvalueraw
,
1598 NET_TRANSPORT_LOCAL
,
1599 N_("Print a registry value (raw format)"),
1600 N_("net registry getvalueraw\n"
1601 " Print a registry value (raw format)")
1605 net_registry_getvaluesraw
,
1606 NET_TRANSPORT_LOCAL
,
1607 "Print all values of a key in raw format",
1608 "net registry getvaluesraw <key>\n"
1609 " Print a registry value (raw format)"
1613 net_registry_setvalue
,
1614 NET_TRANSPORT_LOCAL
,
1615 N_("Set a new registry value"),
1616 N_("net registry setvalue\n"
1617 " Set a new registry value")
1621 net_registry_increment
,
1622 NET_TRANSPORT_LOCAL
,
1623 N_("Increment a DWORD registry value under a lock"),
1624 N_("net registry increment\n"
1625 " Increment a DWORD registry value under a lock")
1629 net_registry_deletevalue
,
1630 NET_TRANSPORT_LOCAL
,
1631 N_("Delete a registry value"),
1632 N_("net registry deletevalue\n"
1633 " Delete a registry value")
1638 NET_TRANSPORT_LOCAL
,
1639 N_("Get security descriptor"),
1640 N_("net registry getsd\n"
1641 " Get security descriptor")
1645 net_registry_getsd_sddl
,
1646 NET_TRANSPORT_LOCAL
,
1647 N_("Get security descriptor in sddl format"),
1648 N_("net registry getsd_sddl\n"
1649 " Get security descriptor in sddl format")
1653 net_registry_setsd_sddl
,
1654 NET_TRANSPORT_LOCAL
,
1655 N_("Set security descriptor from sddl format string"),
1656 N_("net registry setsd_sddl\n"
1657 " Set security descriptor from sddl format string")
1661 net_registry_import
,
1662 NET_TRANSPORT_LOCAL
,
1663 N_("Import .reg file"),
1664 N_("net registry import\n"
1665 " Import .reg file")
1669 net_registry_export
,
1670 NET_TRANSPORT_LOCAL
,
1671 N_("Export .reg file"),
1672 N_("net registry export\n"
1673 " Export .reg file")
1677 net_registry_convert
,
1678 NET_TRANSPORT_LOCAL
,
1679 N_("Convert .reg file"),
1680 N_("net registry convert\n"
1681 " Convert .reg file")
1686 NET_TRANSPORT_LOCAL
,
1687 N_("Check a registry database"),
1688 N_("net registry check\n"
1689 " Check a registry database")
1691 { NULL
, NULL
, 0, NULL
, NULL
}
1694 if (!c
->display_usage
1696 && (strcasecmp_m(argv
[0], "convert") != 0)
1697 && (strcasecmp_m(argv
[0], "check") != 0))
1699 if (!W_ERROR_IS_OK(registry_init_basic())) {
1704 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);