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"
41 #include "lib/util/smb_strtox.h"
50 * split given path into hive and remaining path and open the hive key
52 static WERROR
open_hive(TALLOC_CTX
*ctx
, const char *path
,
53 uint32_t desired_access
,
54 struct registry_key
**hive
,
58 struct security_token
*token
= NULL
;
59 char *hivename
= NULL
;
60 char *tmp_subkeyname
= NULL
;
61 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
63 if ((hive
== NULL
) || (subkeyname
== NULL
)) {
64 werr
= WERR_INVALID_PARAMETER
;
68 werr
= split_hive_key(tmp_ctx
, path
, &hivename
, &tmp_subkeyname
);
69 if (!W_ERROR_IS_OK(werr
)) {
72 *subkeyname
= talloc_strdup(ctx
, tmp_subkeyname
);
73 if (*subkeyname
== NULL
) {
74 werr
= WERR_NOT_ENOUGH_MEMORY
;
78 werr
= ntstatus_to_werror(registry_create_admin_token(tmp_ctx
, &token
));
79 if (!W_ERROR_IS_OK(werr
)) {
83 werr
= reg_openhive(ctx
, hivename
, desired_access
, token
, hive
);
84 if (!W_ERROR_IS_OK(werr
)) {
95 static WERROR
open_key(TALLOC_CTX
*ctx
, const char *path
,
96 uint32_t desired_access
,
97 struct registry_key
**key
)
100 char *subkey_name
= NULL
;
101 struct registry_key
*hive
= NULL
;
102 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
104 if ((path
== NULL
) || (key
== NULL
)) {
105 return WERR_INVALID_PARAMETER
;
108 werr
= open_hive(tmp_ctx
, path
, desired_access
, &hive
, &subkey_name
);
109 if (!W_ERROR_IS_OK(werr
)) {
110 d_fprintf(stderr
, _("open_hive failed: %s\n"),
115 werr
= reg_openkey(ctx
, hive
, subkey_name
, desired_access
, key
);
116 if (!W_ERROR_IS_OK(werr
)) {
117 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
125 TALLOC_FREE(tmp_ctx
);
129 static WERROR
registry_enumkey(struct registry_key
*parent
, const char *keyname
,
133 TALLOC_CTX
*ctx
= talloc_stackframe();
137 char *valname
= NULL
;
138 struct registry_value
*valvalue
= NULL
;
139 struct registry_key
*key
= NULL
;
141 werr
= reg_openkey(ctx
, parent
, keyname
, REG_KEY_READ
, &key
);
142 if (!W_ERROR_IS_OK(werr
)) {
147 printf("[%s]\n\n", key
->key
->name
);
150 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
154 print_registry_key(subkey_name
, &modtime
);
156 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
162 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
166 print_registry_value_with_name(valname
, valvalue
);
168 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
178 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
182 werr
= registry_enumkey(key
, subkey_name
, recursive
);
183 if (!W_ERROR_IS_OK(werr
)) {
187 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
202 * the main "net registry" function implementations
205 static int net_registry_enumerate(struct net_context
*c
, int argc
,
209 struct registry_key
*key
= NULL
;
211 TALLOC_CTX
*ctx
= talloc_stackframe();
214 if (argc
!= 1 || c
->display_usage
) {
217 _("net registry enumerate <path>\n"));
220 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
224 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
225 if (!W_ERROR_IS_OK(werr
)) {
226 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
230 werr
= registry_enumkey(key
, name
, c
->opt_reboot
);
231 if (W_ERROR_IS_OK(werr
)) {
239 static int net_registry_enumerate_recursive(struct net_context
*c
, int argc
,
243 struct registry_key
*key
= NULL
;
245 TALLOC_CTX
*ctx
= talloc_stackframe();
248 if (argc
!= 1 || c
->display_usage
) {
251 _("net registry enumerate <path>\n"));
254 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
258 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
259 if (!W_ERROR_IS_OK(werr
)) {
260 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
264 werr
= registry_enumkey(key
, name
, true);
265 if (W_ERROR_IS_OK(werr
)) {
274 static int net_registry_createkey(struct net_context
*c
, int argc
,
278 enum winreg_CreateAction action
;
279 char *subkeyname
= NULL
;
280 struct registry_key
*hivekey
= NULL
;
281 struct registry_key
*subkey
= NULL
;
282 TALLOC_CTX
*ctx
= talloc_stackframe();
285 if (argc
!= 1 || c
->display_usage
) {
288 _("net registry createkey <path>\n"));
291 _("net registry createkey "
292 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
295 if (strlen(argv
[0]) == 0) {
296 d_fprintf(stderr
, _("error: zero length key name given\n"));
300 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
301 if (!W_ERROR_IS_OK(werr
)) {
302 d_fprintf(stderr
, _("open_hive failed: %s\n"),
307 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
309 if (!W_ERROR_IS_OK(werr
)) {
310 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
315 case REG_ACTION_NONE
:
316 d_printf(_("createkey did nothing -- huh?\n"));
318 case REG_CREATED_NEW_KEY
:
319 d_printf(_("createkey created %s\n"), argv
[0]);
321 case REG_OPENED_EXISTING_KEY
:
322 d_printf(_("createkey opened existing %s\n"), argv
[0]);
333 static int net_registry_deletekey_internal(struct net_context
*c
, int argc
,
338 char *subkeyname
= NULL
;
339 struct registry_key
*hivekey
= NULL
;
340 TALLOC_CTX
*ctx
= talloc_stackframe();
343 if (argc
!= 1 || c
->display_usage
) {
346 _("net registry deletekey <path>\n"));
349 _("net registry deletekey "
350 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
353 if (strlen(argv
[0]) == 0) {
354 d_fprintf(stderr
, _("error: zero length key name given\n"));
358 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
359 if (!W_ERROR_IS_OK(werr
)) {
360 d_fprintf(stderr
, "open_hive %s: %s\n", _("failed"),
366 werr
= reg_deletekey_recursive(hivekey
, subkeyname
);
368 werr
= reg_deletekey(hivekey
, subkeyname
);
370 if (!W_ERROR_IS_OK(werr
) &&
371 !(c
->opt_force
&& W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)))
373 d_fprintf(stderr
, "reg_deletekey %s: %s\n", _("failed"),
385 static int net_registry_deletekey(struct net_context
*c
, int argc
,
388 return net_registry_deletekey_internal(c
, argc
, argv
, false);
391 static int net_registry_deletekey_recursive(struct net_context
*c
, int argc
,
394 return net_registry_deletekey_internal(c
, argc
, argv
, true);
397 static int net_registry_getvalue_internal(struct net_context
*c
, int argc
,
398 const char **argv
, bool raw
)
402 struct registry_key
*key
= NULL
;
403 struct registry_value
*value
= NULL
;
404 TALLOC_CTX
*ctx
= talloc_stackframe();
406 if (argc
!= 2 || c
->display_usage
) {
407 d_fprintf(stderr
, "%s\n%s",
409 _("net registry getvalue <key> <valuename>\n"));
413 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
414 if (!W_ERROR_IS_OK(werr
)) {
415 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
419 werr
= reg_queryvalue(ctx
, key
, argv
[1], &value
);
420 if (!W_ERROR_IS_OK(werr
)) {
421 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
426 print_registry_value(value
, raw
);
435 static int net_registry_getvalue(struct net_context
*c
, int argc
,
438 return net_registry_getvalue_internal(c
, argc
, argv
, false);
441 static int net_registry_getvalueraw(struct net_context
*c
, int argc
,
444 return net_registry_getvalue_internal(c
, argc
, argv
, true);
447 static int net_registry_getvaluesraw(struct net_context
*c
, int argc
,
452 struct registry_key
*key
= NULL
;
453 TALLOC_CTX
*ctx
= talloc_stackframe();
456 if (argc
!= 1 || c
->display_usage
) {
457 d_fprintf(stderr
, "usage: net rpc registry getvaluesraw "
462 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
463 if (!W_ERROR_IS_OK(werr
)) {
464 d_fprintf(stderr
, "open_key failed: %s\n", win_errstr(werr
));
470 struct registry_value
*val
;
472 werr
= reg_enumvalue(talloc_tos(), key
, idx
, NULL
, &val
);
474 if (W_ERROR_EQUAL(werr
, WERR_NO_MORE_ITEMS
)) {
478 if (!W_ERROR_IS_OK(werr
)) {
481 print_registry_value(val
, true);
490 static int net_registry_setvalue(struct net_context
*c
, int argc
,
494 struct registry_value value
;
495 struct registry_key
*key
= NULL
;
497 TALLOC_CTX
*ctx
= talloc_stackframe();
499 if (argc
< 4 || c
->display_usage
) {
500 d_fprintf(stderr
, "%s\n%s",
502 _("net registry setvalue <key> <valuename> "
503 "<type> [<val>]+\n"));
507 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
508 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
512 if (strequal(argv
[2], "dword")) {
516 v
= smb_strtoul(argv
[3], NULL
, 10, &error
, SMB_STR_STANDARD
);
521 value
.type
= REG_DWORD
;
522 value
.data
= data_blob_talloc(ctx
, NULL
, 4);
523 SIVAL(value
.data
.data
, 0, v
);
524 } else if (strequal(argv
[2], "sz")) {
526 if (!push_reg_sz(ctx
, &value
.data
, argv
[3])) {
529 } else if (strequal(argv
[2], "multi_sz")) {
531 int count
= argc
- 3;
533 value
.type
= REG_MULTI_SZ
;
534 array
= talloc_zero_array(ctx
, const char *, count
+ 1);
538 for (i
=0; i
< count
; i
++) {
539 array
[i
] = talloc_strdup(array
, argv
[count
+i
]);
540 if (array
[i
] == NULL
) {
544 if (!push_reg_multi_sz(ctx
, &value
.data
, array
)) {
548 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
552 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
553 if (!W_ERROR_IS_OK(werr
)) {
554 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
558 werr
= reg_setvalue(key
, argv
[1], &value
);
559 if (!W_ERROR_IS_OK(werr
)) {
560 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
572 static int net_registry_increment(struct net_context
*c
, int argc
,
575 TDB_DATA lock_key
= string_term_tdb_data("registry_increment_lock");
576 struct g_lock_ctx
*ctx
= NULL
;
577 const char *keyname
= NULL
;
578 struct registry_key
*key
= NULL
;
579 const char *valuename
= NULL
;
580 struct registry_value
*value
= NULL
;
588 if (argc
< 2 || c
->display_usage
) {
589 d_fprintf(stderr
, "%s\n%s",
591 _("net registry increment <key> <valuename> "
603 increment
= smb_strtoul(
604 argv
[2], NULL
, 10, &error
, SMB_STR_STANDARD
);
610 ctx
= g_lock_ctx_init(c
, c
->msg_ctx
);
612 d_fprintf(stderr
, _("g_lock_ctx_init failed\n"));
616 status
= g_lock_lock(ctx
,
619 tevent_timeval_set(600, 0),
622 if (!NT_STATUS_IS_OK(status
)) {
623 d_fprintf(stderr
, _("g_lock_lock failed: %s\n"),
628 werr
= open_key(c
, keyname
, REG_KEY_READ
|REG_KEY_WRITE
, &key
);
629 if (!W_ERROR_IS_OK(werr
)) {
630 d_fprintf(stderr
, _("open_key failed: %s\n"),
635 werr
= reg_queryvalue(key
, key
, valuename
, &value
);
636 if (!W_ERROR_IS_OK(werr
)) {
637 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
642 if (value
->type
!= REG_DWORD
) {
643 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
644 str_regtype(value
->type
));
648 if (value
->data
.length
< 4) {
649 d_fprintf(stderr
, _("value too short for regular DWORD\n"));
653 v
= IVAL(value
->data
.data
, 0);
657 SIVAL(value
->data
.data
, 0, v
);
659 werr
= reg_setvalue(key
, valuename
, value
);
660 if (!W_ERROR_IS_OK(werr
)) {
661 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
666 if (!W_ERROR_IS_OK(werr
)) {
667 d_fprintf(stderr
, _("increment failed: %s\n"),
672 g_lock_unlock(ctx
, lock_key
);
674 d_printf(_("%"PRIu32
"\n"), newvalue
);
685 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
689 struct registry_key
*key
= NULL
;
690 TALLOC_CTX
*ctx
= talloc_stackframe();
693 if (argc
!= 2 || c
->display_usage
) {
694 d_fprintf(stderr
, "%s\n%s",
696 _("net registry deletevalue <key> <valuename>\n"));
700 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
701 if (!W_ERROR_IS_OK(werr
)) {
702 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
706 werr
= reg_deletevalue(key
, argv
[1]);
707 if (!W_ERROR_IS_OK(werr
)) {
708 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
720 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
723 struct security_descriptor
**sd
)
726 struct registry_key
*key
= NULL
;
727 TALLOC_CTX
*ctx
= talloc_stackframe();
728 uint32_t access_mask
= REG_KEY_READ
|
729 SEC_FLAG_MAXIMUM_ALLOWED
|
730 SEC_FLAG_SYSTEM_SECURITY
;
733 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
734 * is denied with these perms right now...
736 access_mask
= REG_KEY_READ
;
739 d_fprintf(stderr
, _("internal error: invalid argument\n"));
740 werr
= WERR_INVALID_PARAMETER
;
744 if (strlen(keyname
) == 0) {
745 d_fprintf(stderr
, _("error: zero length key name given\n"));
746 werr
= WERR_INVALID_PARAMETER
;
750 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
751 if (!W_ERROR_IS_OK(werr
)) {
752 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
757 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
758 if (!W_ERROR_IS_OK(werr
)) {
759 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
771 static int net_registry_getsd(struct net_context
*c
, int argc
,
776 struct security_descriptor
*secdesc
= NULL
;
777 TALLOC_CTX
*ctx
= talloc_stackframe();
779 if (argc
!= 1 || c
->display_usage
) {
782 _("net registry getsd <path>\n"));
785 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
789 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
790 if (!W_ERROR_IS_OK(werr
)) {
794 display_sec_desc(secdesc
);
803 static int net_registry_getsd_sddl(struct net_context
*c
,
804 int argc
, const char **argv
)
808 struct security_descriptor
*secdesc
= NULL
;
809 TALLOC_CTX
*ctx
= talloc_stackframe();
811 if (argc
!= 1 || c
->display_usage
) {
814 _("net registry getsd_sddl <path>\n"));
817 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
821 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
822 if (!W_ERROR_IS_OK(werr
)) {
826 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
835 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
838 struct security_descriptor
*sd
)
841 struct registry_key
*key
= NULL
;
842 TALLOC_CTX
*ctx
= talloc_stackframe();
843 uint32_t access_mask
= REG_KEY_WRITE
|
844 SEC_FLAG_MAXIMUM_ALLOWED
|
845 SEC_FLAG_SYSTEM_SECURITY
;
848 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
849 * is denied with these perms right now...
851 access_mask
= REG_KEY_WRITE
;
853 if (strlen(keyname
) == 0) {
854 d_fprintf(stderr
, _("error: zero length key name given\n"));
855 werr
= WERR_INVALID_PARAMETER
;
859 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
860 if (!W_ERROR_IS_OK(werr
)) {
861 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
866 werr
= reg_setkeysecurity(key
, sd
);
867 if (!W_ERROR_IS_OK(werr
)) {
868 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
880 static int net_registry_setsd_sddl(struct net_context
*c
,
881 int argc
, const char **argv
)
885 struct security_descriptor
*secdesc
= NULL
;
886 TALLOC_CTX
*ctx
= talloc_stackframe();
888 if (argc
!= 2 || c
->display_usage
) {
891 _("net registry setsd_sddl <path> <security_descriptor>\n"));
894 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
898 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
899 if (secdesc
== NULL
) {
903 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
904 if (!W_ERROR_IS_OK(werr
)) {
915 /******************************************************************************/
917 * @defgroup net_registry net registry
921 * @defgroup net_registry_import Import
922 * @ingroup net_registry
931 static WERROR
import_create_key(struct import_ctx
*ctx
,
932 struct registry_key
*parent
,
933 const char *name
, void **pkey
, bool *existing
)
936 TALLOC_CTX
*mem_ctx
= talloc_new(ctx
->mem_ctx
);
938 struct registry_key
*key
= NULL
;
939 enum winreg_CreateAction action
;
941 if (parent
== NULL
) {
942 char *subkeyname
= NULL
;
943 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
944 &parent
, &subkeyname
);
945 if (!W_ERROR_IS_OK(werr
)) {
946 d_fprintf(stderr
, _("open_hive failed: %s\n"),
953 action
= REG_ACTION_NONE
;
954 werr
= reg_createkey(mem_ctx
, parent
, name
, REG_KEY_WRITE
,
956 if (!W_ERROR_IS_OK(werr
)) {
957 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
962 if (action
== REG_ACTION_NONE
) {
963 d_fprintf(stderr
, _("createkey did nothing -- huh?\n"));
964 werr
= WERR_CREATE_FAILED
;
968 if (existing
!= NULL
) {
969 *existing
= (action
== REG_OPENED_EXISTING_KEY
);
973 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
977 talloc_free(mem_ctx
);
981 static WERROR
import_close_key(struct import_ctx
*ctx
,
982 struct registry_key
*key
)
987 static WERROR
import_delete_key(struct import_ctx
*ctx
,
988 struct registry_key
*parent
, const char *name
)
991 TALLOC_CTX
*mem_ctx
= talloc_new(talloc_tos());
993 if (parent
== NULL
) {
994 char *subkeyname
= NULL
;
995 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
996 &parent
, &subkeyname
);
997 if (!W_ERROR_IS_OK(werr
)) {
998 d_fprintf(stderr
, _("open_hive failed: %s\n"),
1005 werr
= reg_deletekey_recursive(parent
, name
);
1006 if (!W_ERROR_IS_OK(werr
)) {
1007 d_fprintf(stderr
, "reg_deletekey_recursive %s: %s\n",
1008 _("failed"), win_errstr(werr
));
1013 talloc_free(mem_ctx
);
1017 static WERROR
import_create_val (struct import_ctx
*ctx
,
1018 struct registry_key
*parent
, const char *name
,
1019 const struct registry_value
*value
)
1023 if (parent
== NULL
) {
1024 return WERR_INVALID_PARAMETER
;
1027 werr
= reg_setvalue(parent
, name
, value
);
1028 if (!W_ERROR_IS_OK(werr
)) {
1029 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
1035 static WERROR
import_delete_val (struct import_ctx
*ctx
,
1036 struct registry_key
*parent
, const char *name
)
1040 if (parent
== NULL
) {
1041 return WERR_INVALID_PARAMETER
;
1044 werr
= reg_deletevalue(parent
, name
);
1045 if (!W_ERROR_IS_OK(werr
)) {
1046 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
1053 struct precheck_ctx
{
1054 TALLOC_CTX
*mem_ctx
;
1058 static WERROR
precheck_create_key(struct precheck_ctx
*ctx
,
1059 struct registry_key
*parent
,
1060 const char *name
, void **pkey
, bool *existing
)
1063 TALLOC_CTX
*frame
= talloc_stackframe();
1064 struct registry_key
*key
= NULL
;
1066 if (parent
== NULL
) {
1067 char *subkeyname
= NULL
;
1068 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1069 &parent
, &subkeyname
);
1070 if (!W_ERROR_IS_OK(werr
)) {
1071 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1072 name
, win_errstr(werr
));
1078 werr
= reg_openkey(frame
, parent
, name
, 0, &key
);
1079 if (!W_ERROR_IS_OK(werr
)) {
1080 d_printf("Precheck: openkey [%s] failed: %s\n",
1081 name
, win_errstr(werr
));
1085 if (existing
!= NULL
) {
1090 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
1095 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1099 static WERROR
precheck_close_key(struct precheck_ctx
*ctx
,
1100 struct registry_key
*key
)
1106 static WERROR
precheck_delete_key(struct precheck_ctx
*ctx
,
1107 struct registry_key
*parent
, const char *name
)
1110 TALLOC_CTX
*frame
= talloc_stackframe();
1111 struct registry_key
*key
;
1113 if (parent
== NULL
) {
1114 char *subkeyname
= NULL
;
1115 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1116 &parent
, &subkeyname
);
1117 if (!W_ERROR_IS_OK(werr
)) {
1118 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1119 name
, win_errstr(werr
));
1125 werr
= reg_openkey(ctx
->mem_ctx
, parent
, name
, 0, &key
);
1126 if (W_ERROR_IS_OK(werr
)) {
1127 d_printf("Precheck: key [%s\\%s] should not exist\n",
1128 parent
->key
->name
, name
);
1129 werr
= WERR_FILE_EXISTS
;
1130 } else if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1133 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1134 parent
->key
->name
, name
, win_errstr(werr
));
1139 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1143 static int registry_value_cmp(
1144 const struct registry_value
* v1
, const struct registry_value
* v2
)
1146 if (v1
->type
== v2
->type
) {
1147 return data_blob_cmp(&v1
->data
, &v2
->data
);
1149 return NUMERIC_CMP(v1
->type
, v2
->type
);
1152 static WERROR
precheck_create_val(struct precheck_ctx
*ctx
,
1153 struct registry_key
*parent
,
1155 const struct registry_value
*value
)
1157 TALLOC_CTX
*frame
= talloc_stackframe();
1158 struct registry_value
*old
;
1163 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1164 if (!W_ERROR_IS_OK(werr
)) {
1165 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1166 name
, parent
->key
->name
, win_errstr(werr
));
1169 if (registry_value_cmp(value
, old
) != 0) {
1170 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1171 name
, parent
->key
->name
);
1179 static WERROR
precheck_delete_val(struct precheck_ctx
*ctx
,
1180 struct registry_key
*parent
,
1183 TALLOC_CTX
*frame
= talloc_stackframe();
1184 struct registry_value
*old
;
1189 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1190 if (W_ERROR_IS_OK(werr
)) {
1191 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1192 name
, parent
->key
->name
);
1193 werr
= WERR_FILE_EXISTS
;
1194 } else if (W_ERROR_EQUAL(werr
, WERR_FILE_NOT_FOUND
)) {
1197 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1198 name
, parent
->key
->name
, win_errstr(werr
));
1202 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1206 static bool import_precheck(const char *fname
, const char *parse_options
)
1208 TALLOC_CTX
*mem_ctx
= talloc_tos();
1209 struct precheck_ctx precheck_ctx
= {
1213 struct reg_import_callback precheck_callback
= {
1215 .closekey
= (reg_import_callback_closekey_t
)&precheck_close_key
,
1216 .createkey
= (reg_import_callback_createkey_t
)&precheck_create_key
,
1217 .deletekey
= (reg_import_callback_deletekey_t
)&precheck_delete_key
,
1218 .deleteval
= (reg_import_callback_deleteval_t
)&precheck_delete_val
,
1220 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1221 &precheck_create_val
,
1223 .setval_type
= REGISTRY_VALUE
,
1224 .data
= &precheck_ctx
1226 struct reg_parse_callback
*parse_callback
;
1233 parse_callback
= reg_import_adapter(mem_ctx
, precheck_callback
);
1234 if (parse_callback
== NULL
) {
1235 d_printf("talloc failed\n");
1239 ret
= reg_parse_file(fname
, parse_callback
, parse_options
);
1241 if (ret
< 0 || precheck_ctx
.failed
) {
1242 d_printf("Precheck failed\n");
1248 static int import_with_precheck_action(const char *import_fname
,
1249 const char *precheck_fname
,
1250 const char *parse_options
)
1252 TALLOC_CTX
*frame
= talloc_stackframe();
1253 struct import_ctx import_ctx
= {
1256 struct reg_import_callback import_callback
= {
1258 .closekey
= (reg_import_callback_closekey_t
)&import_close_key
,
1259 .createkey
= (reg_import_callback_createkey_t
)&import_create_key
,
1260 .deletekey
= (reg_import_callback_deletekey_t
)&import_delete_key
,
1261 .deleteval
= (reg_import_callback_deleteval_t
)&import_delete_val
,
1263 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1266 .setval_type
= REGISTRY_VALUE
,
1269 struct reg_parse_callback
*parse_callback
;
1273 precheck_ok
= import_precheck(precheck_fname
, parse_options
);
1278 parse_callback
= reg_import_adapter(frame
, import_callback
);
1279 if (parse_callback
== NULL
) {
1280 d_printf("talloc failed\n");
1284 ret
= reg_parse_file(import_fname
, parse_callback
, parse_options
);
1291 static int net_registry_import(struct net_context
*c
, int argc
,
1294 const char *parse_options
= (argc
> 1) ? argv
[1] : NULL
;
1298 if (argc
< 1 || argc
> 2 || c
->display_usage
) {
1301 _("net registry import <reg> [options]\n"));
1304 _("net registry import file.reg enc=CP1252\n"));
1308 werr
= regdb_open();
1309 if (!W_ERROR_IS_OK(werr
)) {
1310 d_printf("Failed to open regdb: %s\n", win_errstr(werr
));
1314 werr
= regdb_transaction_start();
1315 if (!W_ERROR_IS_OK(werr
)) {
1316 d_printf("Failed to start transaction on regdb: %s\n",
1321 ret
= import_with_precheck_action(argv
[0], c
->opt_precheck
,
1325 d_printf("Transaction canceled!\n");
1326 regdb_transaction_cancel();
1330 SMB_ASSERT(ret
== 0);
1332 if (c
->opt_testmode
) {
1333 d_printf("Testmode: not committing changes.\n");
1334 regdb_transaction_cancel();
1338 werr
= regdb_transaction_commit();
1339 if (!W_ERROR_IS_OK(werr
)) {
1340 d_printf("Failed to commit transaction on regdb: %s\n",
1351 /******************************************************************************/
1354 * @defgroup net_registry_export Export
1355 * @ingroup net_registry
1359 static int registry_export(TALLOC_CTX
*ctx
, /*const*/ struct registry_key
*key
,
1360 struct reg_format
*f
)
1366 struct registry_value
*valvalue
= NULL
;
1367 char *valname
= NULL
;
1369 char *subkey_name
= NULL
;
1372 reg_format_registry_key(f
, key
, false);
1376 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
1377 W_ERROR_IS_OK(werr
);
1380 reg_format_registry_value(f
, valname
, valvalue
);
1382 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1383 d_fprintf(stderr
, _("reg_enumvalue failed: %s\n"),
1388 /* recurse on subkeys */
1390 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
1391 W_ERROR_IS_OK(werr
);
1394 struct registry_key
*subkey
= NULL
;
1396 werr
= reg_openkey(ctx
, key
, subkey_name
, REG_KEY_READ
,
1398 if (!W_ERROR_IS_OK(werr
)) {
1399 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
1404 registry_export(ctx
, subkey
, f
);
1405 TALLOC_FREE(subkey
);
1407 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1408 d_fprintf(stderr
, _("reg_enumkey failed: %s\n"),
1417 static int net_registry_export(struct net_context
*c
, int argc
,
1422 struct registry_key
*key
= NULL
;
1423 TALLOC_CTX
*ctx
= talloc_stackframe();
1424 struct reg_format
*f
=NULL
;
1426 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1429 _("net registry export <path> <file> [opt]\n"));
1432 _("net registry export 'HKLM\\Software\\Samba' "
1433 "samba.reg regedit5\n"));
1437 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
1438 if (!W_ERROR_IS_OK(werr
)) {
1439 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
1443 f
= reg_format_file(ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1445 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1449 ret
= registry_export(ctx
, key
, f
);
1457 /******************************************************************************/
1459 * @defgroup net_registry_convert Convert
1460 * @ingroup net_registry
1464 static int net_registry_convert(struct net_context
*c
, int argc
,
1468 TALLOC_CTX
*mem_ctx
;
1469 const char *in_opt
= NULL
;
1470 const char *out_opt
= NULL
;
1472 if (argc
< 2 || argc
> 4|| c
->display_usage
) {
1475 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1476 "net registry convert <in> <out> [out_opt]\n"));
1479 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1483 mem_ctx
= talloc_stackframe();
1500 ret
= reg_parse_file(argv
[0], (struct reg_parse_callback
*)
1501 reg_format_file(mem_ctx
, argv
[1], out_opt
),
1504 talloc_free(mem_ctx
);
1510 static int net_registry_check(struct net_context
*c
, int argc
,
1514 struct check_options opts
;
1517 if (argc
> 1|| c
->display_usage
) {
1520 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1521 " Check a registry database.\n"
1522 " -v|--verbose\t be verbose\n"
1523 " -r|--repair\t\t interactive repair mode\n"
1524 " -a|--auto\t\t noninteractive repair mode\n"
1525 " -T|--test\t\t dry run\n"
1526 " -f|--force\t\t force\n"
1527 " -l|--lock\t\t lock <TDB> while doing the check\n"
1528 " -o|--output=<ODB>\t output database\n"
1529 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1530 " --wipe\t\t create a new database from scratch\n"
1531 " --db=<TDB>\t\t registry database to open\n"));
1532 return c
->display_usage
? 0 : -1;
1535 if (c
->opt_db
!= NULL
) {
1536 dbfile
= talloc_strdup(talloc_tos(), c
->opt_db
);
1537 } else if (argc
> 0) {
1538 dbfile
= talloc_strdup(talloc_tos(), argv
[0]);
1540 dbfile
= state_path(talloc_tos(), "registry.tdb");
1542 if (dbfile
== NULL
) {
1546 opts
= (struct check_options
) {
1547 .lock
= c
->opt_lock
|| c
->opt_long_list_entries
,
1548 .test
= c
->opt_testmode
,
1549 .automatic
= c
->opt_auto
,
1550 .verbose
= c
->opt_verbose
,
1551 .force
= c
->opt_force
,
1552 .repair
= c
->opt_repair
|| c
->opt_reboot
,
1553 .version
= c
->opt_reg_version
,
1554 .output
= c
->opt_output
,
1555 .wipe
= c
->opt_wipe
,
1556 .implicit_db
= (c
->opt_db
== NULL
) && (argc
== 0),
1559 ret
= net_registry_check_db(dbfile
, &opts
);
1560 talloc_free(dbfile
);
1565 /******************************************************************************/
1567 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
1571 struct functable func
[] = {
1574 net_registry_enumerate
,
1575 NET_TRANSPORT_LOCAL
,
1576 N_("Enumerate registry keys and values"),
1577 N_("net registry enumerate\n"
1578 " Enumerate registry keys and values")
1581 "enumerate_recursive",
1582 net_registry_enumerate_recursive
,
1583 NET_TRANSPORT_LOCAL
,
1584 N_("Enumerate registry keys and values"),
1585 N_("net registry enumerate_recursive\n"
1586 " Enumerate registry keys and values")
1590 net_registry_createkey
,
1591 NET_TRANSPORT_LOCAL
,
1592 N_("Create a new registry key"),
1593 N_("net registry createkey\n"
1594 " Create a new registry key")
1598 net_registry_deletekey
,
1599 NET_TRANSPORT_LOCAL
,
1600 N_("Delete a registry key"),
1601 N_("net registry deletekey\n"
1602 " Delete a registry key")
1605 "deletekey_recursive",
1606 net_registry_deletekey_recursive
,
1607 NET_TRANSPORT_LOCAL
,
1608 N_("Delete a registry key with subkeys"),
1609 N_("net registry deletekey_recursive\n"
1610 " Delete a registry key with subkeys")
1614 net_registry_getvalue
,
1615 NET_TRANSPORT_LOCAL
,
1616 N_("Print a registry value"),
1617 N_("net registry getvalue\n"
1618 " Print a registry value")
1622 net_registry_getvalueraw
,
1623 NET_TRANSPORT_LOCAL
,
1624 N_("Print a registry value (raw format)"),
1625 N_("net registry getvalueraw\n"
1626 " Print a registry value (raw format)")
1630 net_registry_getvaluesraw
,
1631 NET_TRANSPORT_LOCAL
,
1632 "Print all values of a key in raw format",
1633 "net registry getvaluesraw <key>\n"
1634 " Print a registry value (raw format)"
1638 net_registry_setvalue
,
1639 NET_TRANSPORT_LOCAL
,
1640 N_("Set a new registry value"),
1641 N_("net registry setvalue\n"
1642 " Set a new registry value")
1646 net_registry_increment
,
1647 NET_TRANSPORT_LOCAL
,
1648 N_("Increment a DWORD registry value under a lock"),
1649 N_("net registry increment\n"
1650 " Increment a DWORD registry value under a lock")
1654 net_registry_deletevalue
,
1655 NET_TRANSPORT_LOCAL
,
1656 N_("Delete a registry value"),
1657 N_("net registry deletevalue\n"
1658 " Delete a registry value")
1663 NET_TRANSPORT_LOCAL
,
1664 N_("Get security descriptor"),
1665 N_("net registry getsd\n"
1666 " Get security descriptor")
1670 net_registry_getsd_sddl
,
1671 NET_TRANSPORT_LOCAL
,
1672 N_("Get security descriptor in sddl format"),
1673 N_("net registry getsd_sddl\n"
1674 " Get security descriptor in sddl format")
1678 net_registry_setsd_sddl
,
1679 NET_TRANSPORT_LOCAL
,
1680 N_("Set security descriptor from sddl format string"),
1681 N_("net registry setsd_sddl\n"
1682 " Set security descriptor from sddl format string")
1686 net_registry_import
,
1687 NET_TRANSPORT_LOCAL
,
1688 N_("Import .reg file"),
1689 N_("net registry import\n"
1690 " Import .reg file")
1694 net_registry_export
,
1695 NET_TRANSPORT_LOCAL
,
1696 N_("Export .reg file"),
1697 N_("net registry export\n"
1698 " Export .reg file")
1702 net_registry_convert
,
1703 NET_TRANSPORT_LOCAL
,
1704 N_("Convert .reg file"),
1705 N_("net registry convert\n"
1706 " Convert .reg file")
1711 NET_TRANSPORT_LOCAL
,
1712 N_("Check a registry database"),
1713 N_("net registry check\n"
1714 " Check a registry database")
1716 { NULL
, NULL
, 0, NULL
, NULL
}
1719 if (!c
->display_usage
1721 && (strcasecmp_m(argv
[0], "convert") != 0)
1722 && (strcasecmp_m(argv
[0], "check") != 0))
1724 if (!W_ERROR_IS_OK(registry_init_basic())) {
1729 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);