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"
34 #include "../libcli/security/display_sec.h"
35 #include "../libcli/security/sddl.h"
36 #include "../libcli/registry/util_reg.h"
37 #include "passdb/machine_sid.h"
38 #include "net_registry_check.h"
47 * split given path into hive and remaining path and open the hive key
49 static WERROR
open_hive(TALLOC_CTX
*ctx
, const char *path
,
50 uint32 desired_access
,
51 struct registry_key
**hive
,
55 struct security_token
*token
= NULL
;
56 char *hivename
= NULL
;
57 char *tmp_subkeyname
= NULL
;
58 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
60 if ((hive
== NULL
) || (subkeyname
== NULL
)) {
61 werr
= WERR_INVALID_PARAM
;
65 werr
= split_hive_key(tmp_ctx
, path
, &hivename
, &tmp_subkeyname
);
66 if (!W_ERROR_IS_OK(werr
)) {
69 *subkeyname
= talloc_strdup(ctx
, tmp_subkeyname
);
70 if (*subkeyname
== NULL
) {
75 werr
= ntstatus_to_werror(registry_create_admin_token(tmp_ctx
, &token
));
76 if (!W_ERROR_IS_OK(werr
)) {
80 werr
= reg_openhive(ctx
, hivename
, desired_access
, token
, hive
);
81 if (!W_ERROR_IS_OK(werr
)) {
92 static WERROR
open_key(TALLOC_CTX
*ctx
, const char *path
,
93 uint32 desired_access
,
94 struct registry_key
**key
)
97 char *subkey_name
= NULL
;
98 struct registry_key
*hive
= NULL
;
99 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
101 if ((path
== NULL
) || (key
== NULL
)) {
102 return WERR_INVALID_PARAM
;
105 werr
= open_hive(tmp_ctx
, path
, desired_access
, &hive
, &subkey_name
);
106 if (!W_ERROR_IS_OK(werr
)) {
107 d_fprintf(stderr
, _("open_hive failed: %s\n"),
112 werr
= reg_openkey(ctx
, hive
, subkey_name
, desired_access
, key
);
113 if (!W_ERROR_IS_OK(werr
)) {
114 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
122 TALLOC_FREE(tmp_ctx
);
126 static WERROR
registry_enumkey(struct registry_key
* parent
, const char* keyname
, bool recursive
)
129 TALLOC_CTX
*ctx
= talloc_stackframe();
133 char* valname
= NULL
;
134 struct registry_value
*valvalue
= NULL
;
135 struct registry_key
* key
= NULL
;
137 werr
= reg_openkey(ctx
, parent
, keyname
, REG_KEY_READ
, &key
);
138 if (!W_ERROR_IS_OK(werr
)) {
143 printf("[%s]\n\n", key
->key
->name
);
146 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
150 print_registry_key(subkey_name
, &modtime
);
152 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
158 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
162 print_registry_value_with_name(valname
, valvalue
);
164 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
174 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
178 werr
= registry_enumkey(key
, subkey_name
, recursive
);
179 if (!W_ERROR_IS_OK(werr
)) {
183 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
198 * the main "net registry" function implementations
201 static int net_registry_enumerate(struct net_context
*c
, int argc
,
205 struct registry_key
*key
= NULL
;
207 TALLOC_CTX
*ctx
= talloc_stackframe();
210 if (argc
!= 1 || c
->display_usage
) {
213 _("net registry enumerate <path>\n"));
216 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
220 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
221 if (!W_ERROR_IS_OK(werr
)) {
222 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
226 werr
= registry_enumkey(key
, name
, c
->opt_reboot
);
227 if (W_ERROR_IS_OK(werr
)) {
235 static int net_registry_enumerate_recursive(struct net_context
*c
, int argc
,
239 struct registry_key
*key
= NULL
;
241 TALLOC_CTX
*ctx
= talloc_stackframe();
244 if (argc
!= 1 || c
->display_usage
) {
247 _("net registry enumerate <path>\n"));
250 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
254 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
255 if (!W_ERROR_IS_OK(werr
)) {
256 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
260 werr
= registry_enumkey(key
, name
, true);
261 if (W_ERROR_IS_OK(werr
)) {
270 static int net_registry_createkey(struct net_context
*c
, int argc
,
274 enum winreg_CreateAction action
;
276 struct registry_key
*hivekey
= NULL
;
277 struct registry_key
*subkey
= NULL
;
278 TALLOC_CTX
*ctx
= talloc_stackframe();
281 if (argc
!= 1 || c
->display_usage
) {
284 _("net registry createkey <path>\n"));
287 _("net registry createkey "
288 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
291 if (strlen(argv
[0]) == 0) {
292 d_fprintf(stderr
, _("error: zero length key name given\n"));
296 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
297 if (!W_ERROR_IS_OK(werr
)) {
298 d_fprintf(stderr
, _("open_hive failed: %s\n"),
303 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
305 if (!W_ERROR_IS_OK(werr
)) {
306 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
311 case REG_ACTION_NONE
:
312 d_printf(_("createkey did nothing -- huh?\n"));
314 case REG_CREATED_NEW_KEY
:
315 d_printf(_("createkey created %s\n"), argv
[0]);
317 case REG_OPENED_EXISTING_KEY
:
318 d_printf(_("createkey opened existing %s\n"), argv
[0]);
329 static int net_registry_deletekey_internal(struct net_context
*c
, int argc
,
335 struct registry_key
*hivekey
= NULL
;
336 TALLOC_CTX
*ctx
= talloc_stackframe();
339 if (argc
!= 1 || c
->display_usage
) {
342 _("net registry deletekey <path>\n"));
345 _("net registry deletekey "
346 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
349 if (strlen(argv
[0]) == 0) {
350 d_fprintf(stderr
, _("error: zero length key name given\n"));
354 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
355 if (!W_ERROR_IS_OK(werr
)) {
356 d_fprintf(stderr
, "open_hive %s: %s\n", _("failed"),
362 werr
= reg_deletekey_recursive(hivekey
, subkeyname
);
364 werr
= reg_deletekey(hivekey
, subkeyname
);
366 if (!W_ERROR_IS_OK(werr
) &&
367 !(c
->opt_force
&& W_ERROR_EQUAL(werr
, WERR_BADFILE
)))
369 d_fprintf(stderr
, "reg_deletekey %s: %s\n", _("failed"),
381 static int net_registry_deletekey(struct net_context
*c
, int argc
,
384 return net_registry_deletekey_internal(c
, argc
, argv
, false);
387 static int net_registry_deletekey_recursive(struct net_context
*c
, int argc
,
390 return net_registry_deletekey_internal(c
, argc
, argv
, true);
393 static int net_registry_getvalue_internal(struct net_context
*c
, int argc
,
394 const char **argv
, bool raw
)
398 struct registry_key
*key
= NULL
;
399 struct registry_value
*value
= NULL
;
400 TALLOC_CTX
*ctx
= talloc_stackframe();
402 if (argc
!= 2 || c
->display_usage
) {
403 d_fprintf(stderr
, "%s\n%s",
405 _("net registry getvalue <key> <valuename>\n"));
409 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
410 if (!W_ERROR_IS_OK(werr
)) {
411 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
415 werr
= reg_queryvalue(ctx
, key
, argv
[1], &value
);
416 if (!W_ERROR_IS_OK(werr
)) {
417 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
422 print_registry_value(value
, raw
);
431 static int net_registry_getvalue(struct net_context
*c
, int argc
,
434 return net_registry_getvalue_internal(c
, argc
, argv
, false);
437 static int net_registry_getvalueraw(struct net_context
*c
, int argc
,
440 return net_registry_getvalue_internal(c
, argc
, argv
, true);
443 static int net_registry_getvaluesraw(struct net_context
*c
, int argc
,
448 struct registry_key
*key
= NULL
;
449 TALLOC_CTX
*ctx
= talloc_stackframe();
452 if (argc
!= 1 || c
->display_usage
) {
453 d_fprintf(stderr
, "usage: net rpc registry getvaluesraw "
458 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
459 if (!W_ERROR_IS_OK(werr
)) {
460 d_fprintf(stderr
, "open_key failed: %s\n", win_errstr(werr
));
466 struct registry_value
*val
;
468 werr
= reg_enumvalue(talloc_tos(), key
, idx
, NULL
, &val
);
470 if (W_ERROR_EQUAL(werr
, WERR_NO_MORE_ITEMS
)) {
474 if (!W_ERROR_IS_OK(werr
)) {
477 print_registry_value(val
, true);
486 static int net_registry_setvalue(struct net_context
*c
, int argc
,
490 struct registry_value value
;
491 struct registry_key
*key
= NULL
;
493 TALLOC_CTX
*ctx
= talloc_stackframe();
495 if (argc
< 4 || c
->display_usage
) {
496 d_fprintf(stderr
, "%s\n%s",
498 _("net registry setvalue <key> <valuename> "
499 "<type> [<val>]+\n"));
503 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
504 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
508 if (strequal(argv
[2], "dword")) {
509 uint32_t v
= strtoul(argv
[3], NULL
, 10);
510 value
.type
= REG_DWORD
;
511 value
.data
= data_blob_talloc(ctx
, NULL
, 4);
512 SIVAL(value
.data
.data
, 0, v
);
513 } else if (strequal(argv
[2], "sz")) {
515 if (!push_reg_sz(ctx
, &value
.data
, argv
[3])) {
518 } else if (strequal(argv
[2], "multi_sz")) {
520 int count
= argc
- 3;
522 value
.type
= REG_MULTI_SZ
;
523 array
= talloc_zero_array(ctx
, const char *, count
+ 1);
527 for (i
=0; i
< count
; i
++) {
528 array
[i
] = talloc_strdup(array
, argv
[count
+i
]);
529 if (array
[i
] == NULL
) {
533 if (!push_reg_multi_sz(ctx
, &value
.data
, array
)) {
537 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
541 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
542 if (!W_ERROR_IS_OK(werr
)) {
543 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
547 werr
= reg_setvalue(key
, argv
[1], &value
);
548 if (!W_ERROR_IS_OK(werr
)) {
549 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
561 struct net_registry_increment_state
{
563 const char *valuename
;
569 static void net_registry_increment_fn(void *private_data
)
571 struct net_registry_increment_state
*state
=
572 (struct net_registry_increment_state
*)private_data
;
573 struct registry_value
*value
;
574 struct registry_key
*key
= NULL
;
577 state
->werr
= open_key(talloc_tos(), state
->keyname
,
578 REG_KEY_READ
|REG_KEY_WRITE
, &key
);
579 if (!W_ERROR_IS_OK(state
->werr
)) {
580 d_fprintf(stderr
, _("open_key failed: %s\n"),
581 win_errstr(state
->werr
));
585 state
->werr
= reg_queryvalue(key
, key
, state
->valuename
, &value
);
586 if (!W_ERROR_IS_OK(state
->werr
)) {
587 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
588 win_errstr(state
->werr
));
592 if (value
->type
!= REG_DWORD
) {
593 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
594 str_regtype(value
->type
));
598 if (value
->data
.length
< 4) {
599 d_fprintf(stderr
, _("value too short for regular DWORD\n"));
603 v
= IVAL(value
->data
.data
, 0);
604 v
+= state
->increment
;
607 SIVAL(value
->data
.data
, 0, v
);
609 state
->werr
= reg_setvalue(key
, state
->valuename
, value
);
610 if (!W_ERROR_IS_OK(state
->werr
)) {
611 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
612 win_errstr(state
->werr
));
621 static int net_registry_increment(struct net_context
*c
, int argc
,
624 struct net_registry_increment_state state
;
628 if (argc
< 2 || c
->display_usage
) {
629 d_fprintf(stderr
, "%s\n%s",
631 _("net registry increment <key> <valuename> "
636 state
.keyname
= argv
[0];
637 state
.valuename
= argv
[1];
641 state
.increment
= strtoul(argv
[2], NULL
, 10);
644 status
= g_lock_do("registry_increment_lock", G_LOCK_WRITE
,
645 timeval_set(600, 0), procid_self(),
646 net_registry_increment_fn
, &state
);
647 if (!NT_STATUS_IS_OK(status
)) {
648 d_fprintf(stderr
, _("g_lock_do failed: %s\n"),
652 if (!W_ERROR_IS_OK(state
.werr
)) {
653 d_fprintf(stderr
, _("increment failed: %s\n"),
654 win_errstr(state
.werr
));
658 d_printf(_("%u\n"), (unsigned)state
.newvalue
);
666 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
670 struct registry_key
*key
= NULL
;
671 TALLOC_CTX
*ctx
= talloc_stackframe();
674 if (argc
!= 2 || c
->display_usage
) {
675 d_fprintf(stderr
, "%s\n%s",
677 _("net registry deletevalue <key> <valuename>\n"));
681 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
682 if (!W_ERROR_IS_OK(werr
)) {
683 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
687 werr
= reg_deletevalue(key
, argv
[1]);
688 if (!W_ERROR_IS_OK(werr
)) {
689 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
701 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
704 struct security_descriptor
**sd
)
707 struct registry_key
*key
= NULL
;
708 TALLOC_CTX
*ctx
= talloc_stackframe();
709 uint32_t access_mask
= REG_KEY_READ
|
710 SEC_FLAG_MAXIMUM_ALLOWED
|
711 SEC_FLAG_SYSTEM_SECURITY
;
714 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
715 * is denied with these perms right now...
717 access_mask
= REG_KEY_READ
;
720 d_fprintf(stderr
, _("internal error: invalid argument\n"));
721 werr
= WERR_INVALID_PARAM
;
725 if (strlen(keyname
) == 0) {
726 d_fprintf(stderr
, _("error: zero length key name given\n"));
727 werr
= WERR_INVALID_PARAM
;
731 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
732 if (!W_ERROR_IS_OK(werr
)) {
733 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
738 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
739 if (!W_ERROR_IS_OK(werr
)) {
740 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
752 static int net_registry_getsd(struct net_context
*c
, int argc
,
757 struct security_descriptor
*secdesc
= NULL
;
758 TALLOC_CTX
*ctx
= talloc_stackframe();
760 if (argc
!= 1 || c
->display_usage
) {
763 _("net registry getsd <path>\n"));
766 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
770 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
771 if (!W_ERROR_IS_OK(werr
)) {
775 display_sec_desc(secdesc
);
784 static int net_registry_getsd_sddl(struct net_context
*c
,
785 int argc
, const char **argv
)
789 struct security_descriptor
*secdesc
= NULL
;
790 TALLOC_CTX
*ctx
= talloc_stackframe();
792 if (argc
!= 1 || c
->display_usage
) {
795 _("net registry getsd_sddl <path>\n"));
798 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
802 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
803 if (!W_ERROR_IS_OK(werr
)) {
807 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
816 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
819 struct security_descriptor
*sd
)
822 struct registry_key
*key
= NULL
;
823 TALLOC_CTX
*ctx
= talloc_stackframe();
824 uint32_t access_mask
= REG_KEY_WRITE
|
825 SEC_FLAG_MAXIMUM_ALLOWED
|
826 SEC_FLAG_SYSTEM_SECURITY
;
829 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
830 * is denied with these perms right now...
832 access_mask
= REG_KEY_WRITE
;
834 if (strlen(keyname
) == 0) {
835 d_fprintf(stderr
, _("error: zero length key name given\n"));
836 werr
= WERR_INVALID_PARAM
;
840 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
841 if (!W_ERROR_IS_OK(werr
)) {
842 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
847 werr
= reg_setkeysecurity(key
, sd
);
848 if (!W_ERROR_IS_OK(werr
)) {
849 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
861 static int net_registry_setsd_sddl(struct net_context
*c
,
862 int argc
, const char **argv
)
866 struct security_descriptor
*secdesc
= NULL
;
867 TALLOC_CTX
*ctx
= talloc_stackframe();
869 if (argc
!= 2 || c
->display_usage
) {
872 _("net registry setsd_sddl <path> <security_descriptor>\n"));
875 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
879 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
880 if (secdesc
== NULL
) {
884 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
885 if (!W_ERROR_IS_OK(werr
)) {
896 /******************************************************************************/
898 * @defgroup net_registry net registry
902 * @defgroup net_registry_import Import
903 * @ingroup net_registry
912 static WERROR
import_create_key(struct import_ctx
* ctx
,
913 struct registry_key
* parent
,
914 const char* name
, void** pkey
, bool* existing
)
917 void* mem_ctx
= talloc_new(ctx
->mem_ctx
);
919 struct registry_key
* key
= NULL
;
920 enum winreg_CreateAction action
;
922 if (parent
== NULL
) {
923 char* subkeyname
= NULL
;
924 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
925 &parent
, &subkeyname
);
926 if (!W_ERROR_IS_OK(werr
)) {
927 d_fprintf(stderr
, _("open_hive failed: %s\n"),
934 action
= REG_ACTION_NONE
;
935 werr
= reg_createkey(mem_ctx
, parent
, name
, REG_KEY_WRITE
,
937 if (!W_ERROR_IS_OK(werr
)) {
938 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
943 if (action
== REG_ACTION_NONE
) {
944 d_fprintf(stderr
, _("createkey did nothing -- huh?\n"));
945 werr
= WERR_CREATE_FAILED
;
949 if (existing
!= NULL
) {
950 *existing
= (action
== REG_OPENED_EXISTING_KEY
);
954 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
958 talloc_free(mem_ctx
);
962 static WERROR
import_close_key(struct import_ctx
* ctx
,
963 struct registry_key
* key
)
968 static WERROR
import_delete_key(struct import_ctx
* ctx
,
969 struct registry_key
* parent
, const char* name
)
972 void* mem_ctx
= talloc_new(talloc_tos());
974 if (parent
== NULL
) {
975 char* subkeyname
= NULL
;
976 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
977 &parent
, &subkeyname
);
978 if (!W_ERROR_IS_OK(werr
)) {
979 d_fprintf(stderr
, _("open_hive failed: %s\n"),
986 werr
= reg_deletekey_recursive(parent
, name
);
987 if (!W_ERROR_IS_OK(werr
)) {
988 d_fprintf(stderr
, "reg_deletekey_recursive %s: %s\n", _("failed"),
994 talloc_free(mem_ctx
);
998 static WERROR
import_create_val (struct import_ctx
* ctx
,
999 struct registry_key
* parent
, const char* name
,
1000 const struct registry_value
* value
)
1004 if (parent
== NULL
) {
1005 return WERR_INVALID_PARAM
;
1008 werr
= reg_setvalue(parent
, name
, value
);
1009 if (!W_ERROR_IS_OK(werr
)) {
1010 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
1016 static WERROR
import_delete_val (struct import_ctx
* ctx
, struct registry_key
* parent
, const char* name
) {
1019 if (parent
== NULL
) {
1020 return WERR_INVALID_PARAM
;
1023 werr
= reg_deletevalue(parent
, name
);
1024 if (!W_ERROR_IS_OK(werr
)) {
1025 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
1033 static int net_registry_import(struct net_context
*c
, int argc
,
1036 struct import_ctx import_ctx
;
1037 struct reg_import_callback import_callback
= {
1039 .closekey
= (reg_import_callback_closekey_t
)&import_close_key
,
1040 .createkey
= (reg_import_callback_createkey_t
)&import_create_key
,
1041 .deletekey
= (reg_import_callback_deletekey_t
)&import_delete_key
,
1042 .deleteval
= (reg_import_callback_deleteval_t
)&import_delete_val
,
1044 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1047 .setval_type
= REGISTRY_VALUE
,
1053 if (argc
< 1 || argc
> 2 || c
->display_usage
) {
1056 _("net registry import <reg> [options]\n"));
1059 _("net registry import file.reg enc=CP1252\n"));
1063 ZERO_STRUCT(import_ctx
);
1064 import_ctx
.mem_ctx
= talloc_stackframe();
1067 regdb_transaction_start();
1069 ret
= reg_parse_file(argv
[0],
1070 reg_import_adapter(import_ctx
.mem_ctx
,
1072 (argc
> 1) ? argv
[1] : NULL
1075 d_printf("reg_parse_file failed: transaction canceled\n");
1076 regdb_transaction_cancel();
1078 regdb_transaction_commit();
1082 talloc_free(import_ctx
.mem_ctx
);
1088 /******************************************************************************/
1091 * @defgroup net_registry_export Export
1092 * @ingroup net_registry
1096 static int registry_export(TALLOC_CTX
*ctx
, /*const*/ struct registry_key
* key
,
1097 struct reg_format
* f
)
1103 struct registry_value
*valvalue
= NULL
;
1104 char *valname
= NULL
;
1106 char *subkey_name
= NULL
;
1109 reg_format_registry_key(f
, key
, false);
1113 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
1114 W_ERROR_IS_OK(werr
);
1117 reg_format_registry_value(f
, valname
, valvalue
);
1119 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1120 d_fprintf(stderr
, _("reg_enumvalue failed: %s\n"),
1125 /* recurse on subkeys */
1127 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
1128 W_ERROR_IS_OK(werr
);
1131 struct registry_key
* subkey
= NULL
;
1133 werr
= reg_openkey(ctx
, key
, subkey_name
, REG_KEY_READ
,
1135 if (!W_ERROR_IS_OK(werr
)) {
1136 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
1141 registry_export(ctx
, subkey
, f
);
1142 TALLOC_FREE(subkey
);
1144 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1145 d_fprintf(stderr
, _("reg_enumkey failed: %s\n"),
1154 static int net_registry_export(struct net_context
*c
, int argc
,
1159 struct registry_key
*key
= NULL
;
1160 TALLOC_CTX
*ctx
= talloc_stackframe();
1161 struct reg_format
* f
=NULL
;
1163 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1166 _("net registry export <path> <file> [opt]\n"));
1169 _("net registry export 'HKLM\\Software\\Samba' "
1170 "samba.reg regedit5\n"));
1174 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
1175 if (!W_ERROR_IS_OK(werr
)) {
1176 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
1180 f
= reg_format_file(ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1182 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1186 ret
= registry_export(ctx
, key
, f
);
1194 /******************************************************************************/
1196 * @defgroup net_registry_convert Convert
1197 * @ingroup net_registry
1201 static int net_registry_convert(struct net_context
*c
, int argc
,
1206 const char* in_opt
= NULL
;
1207 const char* out_opt
= NULL
;
1209 if (argc
< 2 || argc
> 4|| c
->display_usage
) {
1212 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1213 "net registry convert <in> <out> [out_opt]\n"));
1216 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1220 mem_ctx
= talloc_stackframe();
1237 ret
= reg_parse_file(argv
[0], (struct reg_parse_callback
*)
1238 reg_format_file(mem_ctx
, argv
[1], out_opt
),
1241 talloc_free(mem_ctx
);
1247 static int net_registry_check(struct net_context
*c
, int argc
,
1251 struct check_options opts
;
1253 if (argc
> 1|| c
->display_usage
) {
1256 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1257 " Check a registry database.\n"
1258 " -v|--verbose\t be verbose\n"
1259 " -r|--repair\t\t interactive repair mode\n"
1260 " -a|--auto\t\t noninteractive repair mode\n"
1261 " -T|--test\t\t dry run\n"
1262 " -f|--force\t\t force\n"
1263 " -l|--lock\t\t lock <TDB> while doing the check\n"
1264 " -o|--output=<ODB>\t output database\n"
1265 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1266 " --wipe\t\t create a new database from scratch\n"
1267 " --db=<TDB>\t\t registry database to open\n"));
1268 return c
->display_usage
? 0 : -1;
1271 dbfile
= c
->opt_db
? c
->opt_db
: (
1272 (argc
> 0) ? argv
[0] :
1273 state_path("registry.tdb"));
1274 if (dbfile
== NULL
) {
1278 opts
= (struct check_options
) {
1279 .lock
= c
->opt_lock
|| c
->opt_long_list_entries
,
1280 .test
= c
->opt_testmode
,
1281 .automatic
= c
->opt_auto
,
1282 .verbose
= c
->opt_verbose
,
1283 .force
= c
->opt_force
,
1284 .repair
= c
->opt_repair
|| c
->opt_reboot
,
1285 .version
= c
->opt_reg_version
,
1286 .output
= c
->opt_output
,
1287 .wipe
= c
->opt_wipe
,
1288 .implicit_db
= (c
->opt_db
== NULL
) && (argc
== 0),
1291 return net_registry_check_db(dbfile
, &opts
);
1295 /******************************************************************************/
1297 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
1301 struct functable func
[] = {
1304 net_registry_enumerate
,
1305 NET_TRANSPORT_LOCAL
,
1306 N_("Enumerate registry keys and values"),
1307 N_("net registry enumerate\n"
1308 " Enumerate registry keys and values")
1311 "enumerate_recursive",
1312 net_registry_enumerate_recursive
,
1313 NET_TRANSPORT_LOCAL
,
1314 N_("Enumerate registry keys and values"),
1315 N_("net registry enumerate_recursive\n"
1316 " Enumerate registry keys and values")
1320 net_registry_createkey
,
1321 NET_TRANSPORT_LOCAL
,
1322 N_("Create a new registry key"),
1323 N_("net registry createkey\n"
1324 " Create a new registry key")
1328 net_registry_deletekey
,
1329 NET_TRANSPORT_LOCAL
,
1330 N_("Delete a registry key"),
1331 N_("net registry deletekey\n"
1332 " Delete a registry key")
1335 "deletekey_recursive",
1336 net_registry_deletekey_recursive
,
1337 NET_TRANSPORT_LOCAL
,
1338 N_("Delete a registry key with subkeys"),
1339 N_("net registry deletekey_recursive\n"
1340 " Delete a registry key with subkeys")
1344 net_registry_getvalue
,
1345 NET_TRANSPORT_LOCAL
,
1346 N_("Print a registry value"),
1347 N_("net registry getvalue\n"
1348 " Print a registry value")
1352 net_registry_getvalueraw
,
1353 NET_TRANSPORT_LOCAL
,
1354 N_("Print a registry value (raw format)"),
1355 N_("net registry getvalueraw\n"
1356 " Print a registry value (raw format)")
1360 net_registry_getvaluesraw
,
1361 NET_TRANSPORT_LOCAL
,
1362 "Print all values of a key in raw format",
1363 "net registry getvaluesraw <key>\n"
1364 " Print a registry value (raw format)"
1368 net_registry_setvalue
,
1369 NET_TRANSPORT_LOCAL
,
1370 N_("Set a new registry value"),
1371 N_("net registry setvalue\n"
1372 " Set a new registry value")
1376 net_registry_increment
,
1377 NET_TRANSPORT_LOCAL
,
1378 N_("Increment a DWORD registry value under a lock"),
1379 N_("net registry increment\n"
1380 " Increment a DWORD registry value under a lock")
1384 net_registry_deletevalue
,
1385 NET_TRANSPORT_LOCAL
,
1386 N_("Delete a registry value"),
1387 N_("net registry deletevalue\n"
1388 " Delete a registry value")
1393 NET_TRANSPORT_LOCAL
,
1394 N_("Get security descriptor"),
1395 N_("net registry getsd\n"
1396 " Get security descriptor")
1400 net_registry_getsd_sddl
,
1401 NET_TRANSPORT_LOCAL
,
1402 N_("Get security descriptor in sddl format"),
1403 N_("net registry getsd_sddl\n"
1404 " Get security descriptor in sddl format")
1408 net_registry_setsd_sddl
,
1409 NET_TRANSPORT_LOCAL
,
1410 N_("Set security descriptor from sddl format string"),
1411 N_("net registry setsd_sddl\n"
1412 " Set security descriptor from sddl format string")
1416 net_registry_import
,
1417 NET_TRANSPORT_LOCAL
,
1418 N_("Import .reg file"),
1419 N_("net registry import\n"
1420 " Import .reg file")
1424 net_registry_export
,
1425 NET_TRANSPORT_LOCAL
,
1426 N_("Export .reg file"),
1427 N_("net registry export\n"
1428 " Export .reg file")
1432 net_registry_convert
,
1433 NET_TRANSPORT_LOCAL
,
1434 N_("Convert .reg file"),
1435 N_("net registry convert\n"
1436 " Convert .reg file")
1441 NET_TRANSPORT_LOCAL
,
1442 N_("Check .reg file"),
1443 N_("net registry check\n"
1446 { NULL
, NULL
, 0, NULL
, NULL
}
1449 if (!c
->display_usage
1451 && (strcasecmp_m(argv
[0], "convert") != 0)
1452 && (strcasecmp_m(argv
[0], "check") != 0))
1454 if (!W_ERROR_IS_OK(registry_init_basic())) {
1459 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);