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"
48 * split given path into hive and remaining path and open the hive key
50 static WERROR
open_hive(TALLOC_CTX
*ctx
, const char *path
,
51 uint32 desired_access
,
52 struct registry_key
**hive
,
56 struct security_token
*token
= NULL
;
57 char *hivename
= NULL
;
58 char *tmp_subkeyname
= NULL
;
59 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
61 if ((hive
== NULL
) || (subkeyname
== NULL
)) {
62 werr
= WERR_INVALID_PARAM
;
66 werr
= split_hive_key(tmp_ctx
, path
, &hivename
, &tmp_subkeyname
);
67 if (!W_ERROR_IS_OK(werr
)) {
70 *subkeyname
= talloc_strdup(ctx
, tmp_subkeyname
);
71 if (*subkeyname
== NULL
) {
76 werr
= ntstatus_to_werror(registry_create_admin_token(tmp_ctx
, &token
));
77 if (!W_ERROR_IS_OK(werr
)) {
81 werr
= reg_openhive(ctx
, hivename
, desired_access
, token
, hive
);
82 if (!W_ERROR_IS_OK(werr
)) {
93 static WERROR
open_key(TALLOC_CTX
*ctx
, const char *path
,
94 uint32 desired_access
,
95 struct registry_key
**key
)
98 char *subkey_name
= NULL
;
99 struct registry_key
*hive
= NULL
;
100 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
102 if ((path
== NULL
) || (key
== NULL
)) {
103 return WERR_INVALID_PARAM
;
106 werr
= open_hive(tmp_ctx
, path
, desired_access
, &hive
, &subkey_name
);
107 if (!W_ERROR_IS_OK(werr
)) {
108 d_fprintf(stderr
, _("open_hive failed: %s\n"),
113 werr
= reg_openkey(ctx
, hive
, subkey_name
, desired_access
, key
);
114 if (!W_ERROR_IS_OK(werr
)) {
115 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
123 TALLOC_FREE(tmp_ctx
);
127 static WERROR
registry_enumkey(struct registry_key
*parent
, const char *keyname
,
131 TALLOC_CTX
*ctx
= talloc_stackframe();
135 char *valname
= NULL
;
136 struct registry_value
*valvalue
= NULL
;
137 struct registry_key
*key
= NULL
;
139 werr
= reg_openkey(ctx
, parent
, keyname
, REG_KEY_READ
, &key
);
140 if (!W_ERROR_IS_OK(werr
)) {
145 printf("[%s]\n\n", key
->key
->name
);
148 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
152 print_registry_key(subkey_name
, &modtime
);
154 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
160 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
164 print_registry_value_with_name(valname
, valvalue
);
166 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
176 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
180 werr
= registry_enumkey(key
, subkey_name
, recursive
);
181 if (!W_ERROR_IS_OK(werr
)) {
185 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
200 * the main "net registry" function implementations
203 static int net_registry_enumerate(struct net_context
*c
, int argc
,
207 struct registry_key
*key
= NULL
;
209 TALLOC_CTX
*ctx
= talloc_stackframe();
212 if (argc
!= 1 || c
->display_usage
) {
215 _("net registry enumerate <path>\n"));
218 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
222 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
223 if (!W_ERROR_IS_OK(werr
)) {
224 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
228 werr
= registry_enumkey(key
, name
, c
->opt_reboot
);
229 if (W_ERROR_IS_OK(werr
)) {
237 static int net_registry_enumerate_recursive(struct net_context
*c
, int argc
,
241 struct registry_key
*key
= NULL
;
243 TALLOC_CTX
*ctx
= talloc_stackframe();
246 if (argc
!= 1 || c
->display_usage
) {
249 _("net registry enumerate <path>\n"));
252 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
256 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
257 if (!W_ERROR_IS_OK(werr
)) {
258 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
262 werr
= registry_enumkey(key
, name
, true);
263 if (W_ERROR_IS_OK(werr
)) {
272 static int net_registry_createkey(struct net_context
*c
, int argc
,
276 enum winreg_CreateAction action
;
278 struct registry_key
*hivekey
= NULL
;
279 struct registry_key
*subkey
= NULL
;
280 TALLOC_CTX
*ctx
= talloc_stackframe();
283 if (argc
!= 1 || c
->display_usage
) {
286 _("net registry createkey <path>\n"));
289 _("net registry createkey "
290 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
293 if (strlen(argv
[0]) == 0) {
294 d_fprintf(stderr
, _("error: zero length key name given\n"));
298 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
299 if (!W_ERROR_IS_OK(werr
)) {
300 d_fprintf(stderr
, _("open_hive failed: %s\n"),
305 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
307 if (!W_ERROR_IS_OK(werr
)) {
308 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
313 case REG_ACTION_NONE
:
314 d_printf(_("createkey did nothing -- huh?\n"));
316 case REG_CREATED_NEW_KEY
:
317 d_printf(_("createkey created %s\n"), argv
[0]);
319 case REG_OPENED_EXISTING_KEY
:
320 d_printf(_("createkey opened existing %s\n"), argv
[0]);
331 static int net_registry_deletekey_internal(struct net_context
*c
, int argc
,
337 struct registry_key
*hivekey
= NULL
;
338 TALLOC_CTX
*ctx
= talloc_stackframe();
341 if (argc
!= 1 || c
->display_usage
) {
344 _("net registry deletekey <path>\n"));
347 _("net registry deletekey "
348 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
351 if (strlen(argv
[0]) == 0) {
352 d_fprintf(stderr
, _("error: zero length key name given\n"));
356 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
357 if (!W_ERROR_IS_OK(werr
)) {
358 d_fprintf(stderr
, "open_hive %s: %s\n", _("failed"),
364 werr
= reg_deletekey_recursive(hivekey
, subkeyname
);
366 werr
= reg_deletekey(hivekey
, subkeyname
);
368 if (!W_ERROR_IS_OK(werr
) &&
369 !(c
->opt_force
&& W_ERROR_EQUAL(werr
, WERR_BADFILE
)))
371 d_fprintf(stderr
, "reg_deletekey %s: %s\n", _("failed"),
383 static int net_registry_deletekey(struct net_context
*c
, int argc
,
386 return net_registry_deletekey_internal(c
, argc
, argv
, false);
389 static int net_registry_deletekey_recursive(struct net_context
*c
, int argc
,
392 return net_registry_deletekey_internal(c
, argc
, argv
, true);
395 static int net_registry_getvalue_internal(struct net_context
*c
, int argc
,
396 const char **argv
, bool raw
)
400 struct registry_key
*key
= NULL
;
401 struct registry_value
*value
= NULL
;
402 TALLOC_CTX
*ctx
= talloc_stackframe();
404 if (argc
!= 2 || c
->display_usage
) {
405 d_fprintf(stderr
, "%s\n%s",
407 _("net registry getvalue <key> <valuename>\n"));
411 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
412 if (!W_ERROR_IS_OK(werr
)) {
413 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
417 werr
= reg_queryvalue(ctx
, key
, argv
[1], &value
);
418 if (!W_ERROR_IS_OK(werr
)) {
419 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
424 print_registry_value(value
, raw
);
433 static int net_registry_getvalue(struct net_context
*c
, int argc
,
436 return net_registry_getvalue_internal(c
, argc
, argv
, false);
439 static int net_registry_getvalueraw(struct net_context
*c
, int argc
,
442 return net_registry_getvalue_internal(c
, argc
, argv
, true);
445 static int net_registry_getvaluesraw(struct net_context
*c
, int argc
,
450 struct registry_key
*key
= NULL
;
451 TALLOC_CTX
*ctx
= talloc_stackframe();
454 if (argc
!= 1 || c
->display_usage
) {
455 d_fprintf(stderr
, "usage: net rpc registry getvaluesraw "
460 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
461 if (!W_ERROR_IS_OK(werr
)) {
462 d_fprintf(stderr
, "open_key failed: %s\n", win_errstr(werr
));
468 struct registry_value
*val
;
470 werr
= reg_enumvalue(talloc_tos(), key
, idx
, NULL
, &val
);
472 if (W_ERROR_EQUAL(werr
, WERR_NO_MORE_ITEMS
)) {
476 if (!W_ERROR_IS_OK(werr
)) {
479 print_registry_value(val
, true);
488 static int net_registry_setvalue(struct net_context
*c
, int argc
,
492 struct registry_value value
;
493 struct registry_key
*key
= NULL
;
495 TALLOC_CTX
*ctx
= talloc_stackframe();
497 if (argc
< 4 || c
->display_usage
) {
498 d_fprintf(stderr
, "%s\n%s",
500 _("net registry setvalue <key> <valuename> "
501 "<type> [<val>]+\n"));
505 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
506 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
510 if (strequal(argv
[2], "dword")) {
511 uint32_t v
= strtoul(argv
[3], NULL
, 10);
512 value
.type
= REG_DWORD
;
513 value
.data
= data_blob_talloc(ctx
, NULL
, 4);
514 SIVAL(value
.data
.data
, 0, v
);
515 } else if (strequal(argv
[2], "sz")) {
517 if (!push_reg_sz(ctx
, &value
.data
, argv
[3])) {
520 } else if (strequal(argv
[2], "multi_sz")) {
522 int count
= argc
- 3;
524 value
.type
= REG_MULTI_SZ
;
525 array
= talloc_zero_array(ctx
, const char *, count
+ 1);
529 for (i
=0; i
< count
; i
++) {
530 array
[i
] = talloc_strdup(array
, argv
[count
+i
]);
531 if (array
[i
] == NULL
) {
535 if (!push_reg_multi_sz(ctx
, &value
.data
, array
)) {
539 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
543 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
544 if (!W_ERROR_IS_OK(werr
)) {
545 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
549 werr
= reg_setvalue(key
, argv
[1], &value
);
550 if (!W_ERROR_IS_OK(werr
)) {
551 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
563 struct net_registry_increment_state
{
565 const char *valuename
;
571 static void net_registry_increment_fn(void *private_data
)
573 struct net_registry_increment_state
*state
=
574 (struct net_registry_increment_state
*)private_data
;
575 struct registry_value
*value
;
576 struct registry_key
*key
= NULL
;
579 state
->werr
= open_key(talloc_tos(), state
->keyname
,
580 REG_KEY_READ
|REG_KEY_WRITE
, &key
);
581 if (!W_ERROR_IS_OK(state
->werr
)) {
582 d_fprintf(stderr
, _("open_key failed: %s\n"),
583 win_errstr(state
->werr
));
587 state
->werr
= reg_queryvalue(key
, key
, state
->valuename
, &value
);
588 if (!W_ERROR_IS_OK(state
->werr
)) {
589 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
590 win_errstr(state
->werr
));
594 if (value
->type
!= REG_DWORD
) {
595 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
596 str_regtype(value
->type
));
600 if (value
->data
.length
< 4) {
601 d_fprintf(stderr
, _("value too short for regular DWORD\n"));
605 v
= IVAL(value
->data
.data
, 0);
606 v
+= state
->increment
;
609 SIVAL(value
->data
.data
, 0, v
);
611 state
->werr
= reg_setvalue(key
, state
->valuename
, value
);
612 if (!W_ERROR_IS_OK(state
->werr
)) {
613 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
614 win_errstr(state
->werr
));
623 static int net_registry_increment(struct net_context
*c
, int argc
,
626 struct net_registry_increment_state state
;
630 if (argc
< 2 || c
->display_usage
) {
631 d_fprintf(stderr
, "%s\n%s",
633 _("net registry increment <key> <valuename> "
638 state
.keyname
= argv
[0];
639 state
.valuename
= argv
[1];
643 state
.increment
= strtoul(argv
[2], NULL
, 10);
646 status
= g_lock_do("registry_increment_lock", G_LOCK_WRITE
,
648 net_registry_increment_fn
, &state
);
649 if (!NT_STATUS_IS_OK(status
)) {
650 d_fprintf(stderr
, _("g_lock_do failed: %s\n"),
654 if (!W_ERROR_IS_OK(state
.werr
)) {
655 d_fprintf(stderr
, _("increment failed: %s\n"),
656 win_errstr(state
.werr
));
660 d_printf(_("%u\n"), (unsigned)state
.newvalue
);
668 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
672 struct registry_key
*key
= NULL
;
673 TALLOC_CTX
*ctx
= talloc_stackframe();
676 if (argc
!= 2 || c
->display_usage
) {
677 d_fprintf(stderr
, "%s\n%s",
679 _("net registry deletevalue <key> <valuename>\n"));
683 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
684 if (!W_ERROR_IS_OK(werr
)) {
685 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
689 werr
= reg_deletevalue(key
, argv
[1]);
690 if (!W_ERROR_IS_OK(werr
)) {
691 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
703 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
706 struct security_descriptor
**sd
)
709 struct registry_key
*key
= NULL
;
710 TALLOC_CTX
*ctx
= talloc_stackframe();
711 uint32_t access_mask
= REG_KEY_READ
|
712 SEC_FLAG_MAXIMUM_ALLOWED
|
713 SEC_FLAG_SYSTEM_SECURITY
;
716 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
717 * is denied with these perms right now...
719 access_mask
= REG_KEY_READ
;
722 d_fprintf(stderr
, _("internal error: invalid argument\n"));
723 werr
= WERR_INVALID_PARAM
;
727 if (strlen(keyname
) == 0) {
728 d_fprintf(stderr
, _("error: zero length key name given\n"));
729 werr
= WERR_INVALID_PARAM
;
733 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
734 if (!W_ERROR_IS_OK(werr
)) {
735 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
740 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
741 if (!W_ERROR_IS_OK(werr
)) {
742 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
754 static int net_registry_getsd(struct net_context
*c
, int argc
,
759 struct security_descriptor
*secdesc
= NULL
;
760 TALLOC_CTX
*ctx
= talloc_stackframe();
762 if (argc
!= 1 || c
->display_usage
) {
765 _("net registry getsd <path>\n"));
768 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
772 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
773 if (!W_ERROR_IS_OK(werr
)) {
777 display_sec_desc(secdesc
);
786 static int net_registry_getsd_sddl(struct net_context
*c
,
787 int argc
, const char **argv
)
791 struct security_descriptor
*secdesc
= NULL
;
792 TALLOC_CTX
*ctx
= talloc_stackframe();
794 if (argc
!= 1 || c
->display_usage
) {
797 _("net registry getsd_sddl <path>\n"));
800 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
804 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
805 if (!W_ERROR_IS_OK(werr
)) {
809 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
818 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
821 struct security_descriptor
*sd
)
824 struct registry_key
*key
= NULL
;
825 TALLOC_CTX
*ctx
= talloc_stackframe();
826 uint32_t access_mask
= REG_KEY_WRITE
|
827 SEC_FLAG_MAXIMUM_ALLOWED
|
828 SEC_FLAG_SYSTEM_SECURITY
;
831 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
832 * is denied with these perms right now...
834 access_mask
= REG_KEY_WRITE
;
836 if (strlen(keyname
) == 0) {
837 d_fprintf(stderr
, _("error: zero length key name given\n"));
838 werr
= WERR_INVALID_PARAM
;
842 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
843 if (!W_ERROR_IS_OK(werr
)) {
844 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
849 werr
= reg_setkeysecurity(key
, sd
);
850 if (!W_ERROR_IS_OK(werr
)) {
851 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
863 static int net_registry_setsd_sddl(struct net_context
*c
,
864 int argc
, const char **argv
)
868 struct security_descriptor
*secdesc
= NULL
;
869 TALLOC_CTX
*ctx
= talloc_stackframe();
871 if (argc
!= 2 || c
->display_usage
) {
874 _("net registry setsd_sddl <path> <security_descriptor>\n"));
877 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
881 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
882 if (secdesc
== NULL
) {
886 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
887 if (!W_ERROR_IS_OK(werr
)) {
898 /******************************************************************************/
900 * @defgroup net_registry net registry
904 * @defgroup net_registry_import Import
905 * @ingroup net_registry
914 static WERROR
import_create_key(struct import_ctx
*ctx
,
915 struct registry_key
*parent
,
916 const char *name
, void **pkey
, bool *existing
)
919 TALLOC_CTX
*mem_ctx
= talloc_new(ctx
->mem_ctx
);
921 struct registry_key
*key
= NULL
;
922 enum winreg_CreateAction action
;
924 if (parent
== NULL
) {
925 char *subkeyname
= NULL
;
926 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
927 &parent
, &subkeyname
);
928 if (!W_ERROR_IS_OK(werr
)) {
929 d_fprintf(stderr
, _("open_hive failed: %s\n"),
936 action
= REG_ACTION_NONE
;
937 werr
= reg_createkey(mem_ctx
, parent
, name
, REG_KEY_WRITE
,
939 if (!W_ERROR_IS_OK(werr
)) {
940 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
945 if (action
== REG_ACTION_NONE
) {
946 d_fprintf(stderr
, _("createkey did nothing -- huh?\n"));
947 werr
= WERR_CREATE_FAILED
;
951 if (existing
!= NULL
) {
952 *existing
= (action
== REG_OPENED_EXISTING_KEY
);
956 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
960 talloc_free(mem_ctx
);
964 static WERROR
import_close_key(struct import_ctx
*ctx
,
965 struct registry_key
*key
)
970 static WERROR
import_delete_key(struct import_ctx
*ctx
,
971 struct registry_key
*parent
, const char *name
)
974 TALLOC_CTX
*mem_ctx
= talloc_new(talloc_tos());
976 if (parent
== NULL
) {
977 char *subkeyname
= NULL
;
978 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
979 &parent
, &subkeyname
);
980 if (!W_ERROR_IS_OK(werr
)) {
981 d_fprintf(stderr
, _("open_hive failed: %s\n"),
988 werr
= reg_deletekey_recursive(parent
, name
);
989 if (!W_ERROR_IS_OK(werr
)) {
990 d_fprintf(stderr
, "reg_deletekey_recursive %s: %s\n",
991 _("failed"), win_errstr(werr
));
996 talloc_free(mem_ctx
);
1000 static WERROR
import_create_val (struct import_ctx
*ctx
,
1001 struct registry_key
*parent
, const char *name
,
1002 const struct registry_value
*value
)
1006 if (parent
== NULL
) {
1007 return WERR_INVALID_PARAM
;
1010 werr
= reg_setvalue(parent
, name
, value
);
1011 if (!W_ERROR_IS_OK(werr
)) {
1012 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
1018 static WERROR
import_delete_val (struct import_ctx
*ctx
,
1019 struct registry_key
*parent
, const char *name
)
1023 if (parent
== NULL
) {
1024 return WERR_INVALID_PARAM
;
1027 werr
= reg_deletevalue(parent
, name
);
1028 if (!W_ERROR_IS_OK(werr
)) {
1029 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
1036 struct precheck_ctx
{
1037 TALLOC_CTX
*mem_ctx
;
1041 static WERROR
precheck_create_key(struct precheck_ctx
*ctx
,
1042 struct registry_key
*parent
,
1043 const char *name
, void **pkey
, bool *existing
)
1046 TALLOC_CTX
*frame
= talloc_stackframe();
1047 struct registry_key
*key
= NULL
;
1049 if (parent
== NULL
) {
1050 char *subkeyname
= NULL
;
1051 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1052 &parent
, &subkeyname
);
1053 if (!W_ERROR_IS_OK(werr
)) {
1054 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1055 name
, win_errstr(werr
));
1061 werr
= reg_openkey(frame
, parent
, name
, 0, &key
);
1062 if (!W_ERROR_IS_OK(werr
)) {
1063 d_printf("Precheck: openkey [%s] failed: %s\n",
1064 name
, win_errstr(werr
));
1068 if (existing
!= NULL
) {
1073 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
1078 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1082 static WERROR
precheck_close_key(struct precheck_ctx
*ctx
,
1083 struct registry_key
*key
)
1089 static WERROR
precheck_delete_key(struct precheck_ctx
*ctx
,
1090 struct registry_key
*parent
, const char *name
)
1093 TALLOC_CTX
*frame
= talloc_stackframe();
1094 struct registry_key
*key
;
1096 if (parent
== NULL
) {
1097 char *subkeyname
= NULL
;
1098 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1099 &parent
, &subkeyname
);
1100 if (!W_ERROR_IS_OK(werr
)) {
1101 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1102 name
, win_errstr(werr
));
1108 werr
= reg_openkey(ctx
->mem_ctx
, parent
, name
, 0, &key
);
1109 if (W_ERROR_IS_OK(werr
)) {
1110 d_printf("Precheck: key [%s\\%s] should not exist\n",
1111 parent
->key
->name
, name
);
1112 werr
= WERR_FILE_EXISTS
;
1113 } else if (W_ERROR_EQUAL(werr
, WERR_BADFILE
)) {
1116 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1117 parent
->key
->name
, name
, win_errstr(werr
));
1122 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1126 static WERROR
precheck_create_val(struct precheck_ctx
*ctx
,
1127 struct registry_key
*parent
,
1129 const struct registry_value
*value
)
1131 TALLOC_CTX
*frame
= talloc_stackframe();
1132 struct registry_value
*old
;
1137 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1138 if (!W_ERROR_IS_OK(werr
)) {
1139 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1140 name
, parent
->key
->name
, win_errstr(werr
));
1143 if (registry_value_cmp(value
, old
) != 0) {
1144 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1145 name
, parent
->key
->name
);
1153 static WERROR
precheck_delete_val(struct precheck_ctx
*ctx
,
1154 struct registry_key
*parent
,
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: value \"%s\" of key [%s] should not exist\n",
1166 name
, parent
->key
->name
);
1167 werr
= WERR_FILE_EXISTS
;
1168 } else if (W_ERROR_EQUAL(werr
, WERR_BADFILE
)) {
1171 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1172 name
, parent
->key
->name
, win_errstr(werr
));
1176 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1180 static bool import_precheck(const char *fname
, const char *parse_options
)
1182 TALLOC_CTX
*mem_ctx
= talloc_tos();
1183 struct precheck_ctx precheck_ctx
= {
1187 struct reg_import_callback precheck_callback
= {
1189 .closekey
= (reg_import_callback_closekey_t
)&precheck_close_key
,
1190 .createkey
= (reg_import_callback_createkey_t
)&precheck_create_key
,
1191 .deletekey
= (reg_import_callback_deletekey_t
)&precheck_delete_key
,
1192 .deleteval
= (reg_import_callback_deleteval_t
)&precheck_delete_val
,
1194 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1195 &precheck_create_val
,
1197 .setval_type
= REGISTRY_VALUE
,
1198 .data
= &precheck_ctx
1200 struct reg_parse_callback
*parse_callback
;
1207 parse_callback
= reg_import_adapter(mem_ctx
, precheck_callback
);
1208 if (parse_callback
== NULL
) {
1209 d_printf("talloc failed\n");
1213 ret
= reg_parse_file(fname
, parse_callback
, parse_options
);
1215 if (ret
< 0 || precheck_ctx
.failed
) {
1216 d_printf("Precheck failed\n");
1222 static int import_with_precheck_action(const char *import_fname
,
1223 const char *precheck_fname
,
1224 const char *parse_options
)
1226 TALLOC_CTX
*frame
= talloc_stackframe();
1227 struct import_ctx import_ctx
= {
1230 struct reg_import_callback import_callback
= {
1232 .closekey
= (reg_import_callback_closekey_t
)&import_close_key
,
1233 .createkey
= (reg_import_callback_createkey_t
)&import_create_key
,
1234 .deletekey
= (reg_import_callback_deletekey_t
)&import_delete_key
,
1235 .deleteval
= (reg_import_callback_deleteval_t
)&import_delete_val
,
1237 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1240 .setval_type
= REGISTRY_VALUE
,
1243 struct reg_parse_callback
*parse_callback
;
1247 precheck_ok
= import_precheck(precheck_fname
, parse_options
);
1252 parse_callback
= reg_import_adapter(frame
, import_callback
);
1253 if (parse_callback
== NULL
) {
1254 d_printf("talloc failed\n");
1258 ret
= reg_parse_file(import_fname
, parse_callback
, parse_options
);
1265 static int net_registry_import(struct net_context
*c
, int argc
,
1268 const char *parse_options
= (argc
> 1) ? argv
[1] : NULL
;
1272 if (argc
< 1 || argc
> 2 || c
->display_usage
) {
1275 _("net registry import <reg> [options]\n"));
1278 _("net registry import file.reg enc=CP1252\n"));
1282 werr
= regdb_open();
1283 if (!W_ERROR_IS_OK(werr
)) {
1284 d_printf("Failed to open regdb: %s\n", win_errstr(werr
));
1288 werr
= regdb_transaction_start();
1289 if (!W_ERROR_IS_OK(werr
)) {
1290 d_printf("Failed to start transaction on regdb: %s\n",
1295 ret
= import_with_precheck_action(argv
[0], c
->opt_precheck
,
1299 d_printf("Transaction canceled!\n");
1300 regdb_transaction_cancel();
1304 SMB_ASSERT(ret
== 0);
1306 if (c
->opt_testmode
) {
1307 d_printf("Testmode: not committing changes.\n");
1308 regdb_transaction_cancel();
1312 werr
= regdb_transaction_commit();
1313 if (!W_ERROR_IS_OK(werr
)) {
1314 d_printf("Failed to commit transaction on regdb: %s\n",
1325 /******************************************************************************/
1328 * @defgroup net_registry_export Export
1329 * @ingroup net_registry
1333 static int registry_export(TALLOC_CTX
*ctx
, /*const*/ struct registry_key
*key
,
1334 struct reg_format
*f
)
1340 struct registry_value
*valvalue
= NULL
;
1341 char *valname
= NULL
;
1343 char *subkey_name
= NULL
;
1346 reg_format_registry_key(f
, key
, false);
1350 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
1351 W_ERROR_IS_OK(werr
);
1354 reg_format_registry_value(f
, valname
, valvalue
);
1356 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1357 d_fprintf(stderr
, _("reg_enumvalue failed: %s\n"),
1362 /* recurse on subkeys */
1364 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
1365 W_ERROR_IS_OK(werr
);
1368 struct registry_key
*subkey
= NULL
;
1370 werr
= reg_openkey(ctx
, key
, subkey_name
, REG_KEY_READ
,
1372 if (!W_ERROR_IS_OK(werr
)) {
1373 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
1378 registry_export(ctx
, subkey
, f
);
1379 TALLOC_FREE(subkey
);
1381 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1382 d_fprintf(stderr
, _("reg_enumkey failed: %s\n"),
1391 static int net_registry_export(struct net_context
*c
, int argc
,
1396 struct registry_key
*key
= NULL
;
1397 TALLOC_CTX
*ctx
= talloc_stackframe();
1398 struct reg_format
*f
=NULL
;
1400 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1403 _("net registry export <path> <file> [opt]\n"));
1406 _("net registry export 'HKLM\\Software\\Samba' "
1407 "samba.reg regedit5\n"));
1411 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
1412 if (!W_ERROR_IS_OK(werr
)) {
1413 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
1417 f
= reg_format_file(ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1419 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1423 ret
= registry_export(ctx
, key
, f
);
1431 /******************************************************************************/
1433 * @defgroup net_registry_convert Convert
1434 * @ingroup net_registry
1438 static int net_registry_convert(struct net_context
*c
, int argc
,
1442 TALLOC_CTX
*mem_ctx
;
1443 const char *in_opt
= NULL
;
1444 const char *out_opt
= NULL
;
1446 if (argc
< 2 || argc
> 4|| c
->display_usage
) {
1449 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1450 "net registry convert <in> <out> [out_opt]\n"));
1453 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1457 mem_ctx
= talloc_stackframe();
1474 ret
= reg_parse_file(argv
[0], (struct reg_parse_callback
*)
1475 reg_format_file(mem_ctx
, argv
[1], out_opt
),
1478 talloc_free(mem_ctx
);
1484 static int net_registry_check(struct net_context
*c
, int argc
,
1488 struct check_options opts
;
1490 if (argc
> 1|| c
->display_usage
) {
1493 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1494 " Check a registry database.\n"
1495 " -v|--verbose\t be verbose\n"
1496 " -r|--repair\t\t interactive repair mode\n"
1497 " -a|--auto\t\t noninteractive repair mode\n"
1498 " -T|--test\t\t dry run\n"
1499 " -f|--force\t\t force\n"
1500 " -l|--lock\t\t lock <TDB> while doing the check\n"
1501 " -o|--output=<ODB>\t output database\n"
1502 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1503 " --wipe\t\t create a new database from scratch\n"
1504 " --db=<TDB>\t\t registry database to open\n"));
1505 return c
->display_usage
? 0 : -1;
1508 dbfile
= c
->opt_db
? c
->opt_db
: (
1509 (argc
> 0) ? argv
[0] :
1510 state_path("registry.tdb"));
1511 if (dbfile
== NULL
) {
1515 opts
= (struct check_options
) {
1516 .lock
= c
->opt_lock
|| c
->opt_long_list_entries
,
1517 .test
= c
->opt_testmode
,
1518 .automatic
= c
->opt_auto
,
1519 .verbose
= c
->opt_verbose
,
1520 .force
= c
->opt_force
,
1521 .repair
= c
->opt_repair
|| c
->opt_reboot
,
1522 .version
= c
->opt_reg_version
,
1523 .output
= c
->opt_output
,
1524 .wipe
= c
->opt_wipe
,
1525 .implicit_db
= (c
->opt_db
== NULL
) && (argc
== 0),
1528 return net_registry_check_db(dbfile
, &opts
);
1532 /******************************************************************************/
1534 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
1538 struct functable func
[] = {
1541 net_registry_enumerate
,
1542 NET_TRANSPORT_LOCAL
,
1543 N_("Enumerate registry keys and values"),
1544 N_("net registry enumerate\n"
1545 " Enumerate registry keys and values")
1548 "enumerate_recursive",
1549 net_registry_enumerate_recursive
,
1550 NET_TRANSPORT_LOCAL
,
1551 N_("Enumerate registry keys and values"),
1552 N_("net registry enumerate_recursive\n"
1553 " Enumerate registry keys and values")
1557 net_registry_createkey
,
1558 NET_TRANSPORT_LOCAL
,
1559 N_("Create a new registry key"),
1560 N_("net registry createkey\n"
1561 " Create a new registry key")
1565 net_registry_deletekey
,
1566 NET_TRANSPORT_LOCAL
,
1567 N_("Delete a registry key"),
1568 N_("net registry deletekey\n"
1569 " Delete a registry key")
1572 "deletekey_recursive",
1573 net_registry_deletekey_recursive
,
1574 NET_TRANSPORT_LOCAL
,
1575 N_("Delete a registry key with subkeys"),
1576 N_("net registry deletekey_recursive\n"
1577 " Delete a registry key with subkeys")
1581 net_registry_getvalue
,
1582 NET_TRANSPORT_LOCAL
,
1583 N_("Print a registry value"),
1584 N_("net registry getvalue\n"
1585 " Print a registry value")
1589 net_registry_getvalueraw
,
1590 NET_TRANSPORT_LOCAL
,
1591 N_("Print a registry value (raw format)"),
1592 N_("net registry getvalueraw\n"
1593 " Print a registry value (raw format)")
1597 net_registry_getvaluesraw
,
1598 NET_TRANSPORT_LOCAL
,
1599 "Print all values of a key in raw format",
1600 "net registry getvaluesraw <key>\n"
1601 " Print a registry value (raw format)"
1605 net_registry_setvalue
,
1606 NET_TRANSPORT_LOCAL
,
1607 N_("Set a new registry value"),
1608 N_("net registry setvalue\n"
1609 " Set a new registry value")
1613 net_registry_increment
,
1614 NET_TRANSPORT_LOCAL
,
1615 N_("Increment a DWORD registry value under a lock"),
1616 N_("net registry increment\n"
1617 " Increment a DWORD registry value under a lock")
1621 net_registry_deletevalue
,
1622 NET_TRANSPORT_LOCAL
,
1623 N_("Delete a registry value"),
1624 N_("net registry deletevalue\n"
1625 " Delete a registry value")
1630 NET_TRANSPORT_LOCAL
,
1631 N_("Get security descriptor"),
1632 N_("net registry getsd\n"
1633 " Get security descriptor")
1637 net_registry_getsd_sddl
,
1638 NET_TRANSPORT_LOCAL
,
1639 N_("Get security descriptor in sddl format"),
1640 N_("net registry getsd_sddl\n"
1641 " Get security descriptor in sddl format")
1645 net_registry_setsd_sddl
,
1646 NET_TRANSPORT_LOCAL
,
1647 N_("Set security descriptor from sddl format string"),
1648 N_("net registry setsd_sddl\n"
1649 " Set security descriptor from sddl format string")
1653 net_registry_import
,
1654 NET_TRANSPORT_LOCAL
,
1655 N_("Import .reg file"),
1656 N_("net registry import\n"
1657 " Import .reg file")
1661 net_registry_export
,
1662 NET_TRANSPORT_LOCAL
,
1663 N_("Export .reg file"),
1664 N_("net registry export\n"
1665 " Export .reg file")
1669 net_registry_convert
,
1670 NET_TRANSPORT_LOCAL
,
1671 N_("Convert .reg file"),
1672 N_("net registry convert\n"
1673 " Convert .reg file")
1678 NET_TRANSPORT_LOCAL
,
1679 N_("Check a registry database"),
1680 N_("net registry check\n"
1681 " Check a registry database")
1683 { NULL
, NULL
, 0, NULL
, NULL
}
1686 if (!c
->display_usage
1688 && (strcasecmp_m(argv
[0], "convert") != 0)
1689 && (strcasecmp_m(argv
[0], "check") != 0))
1691 if (!W_ERROR_IS_OK(registry_init_basic())) {
1696 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);