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
, bool recursive
)
130 TALLOC_CTX
*ctx
= talloc_stackframe();
134 char* valname
= NULL
;
135 struct registry_value
*valvalue
= NULL
;
136 struct registry_key
* key
= NULL
;
138 werr
= reg_openkey(ctx
, parent
, keyname
, REG_KEY_READ
, &key
);
139 if (!W_ERROR_IS_OK(werr
)) {
144 printf("[%s]\n\n", key
->key
->name
);
147 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
151 print_registry_key(subkey_name
, &modtime
);
153 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
159 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
163 print_registry_value_with_name(valname
, valvalue
);
165 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
175 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
179 werr
= registry_enumkey(key
, subkey_name
, recursive
);
180 if (!W_ERROR_IS_OK(werr
)) {
184 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
199 * the main "net registry" function implementations
202 static int net_registry_enumerate(struct net_context
*c
, int argc
,
206 struct registry_key
*key
= NULL
;
208 TALLOC_CTX
*ctx
= talloc_stackframe();
211 if (argc
!= 1 || c
->display_usage
) {
214 _("net registry enumerate <path>\n"));
217 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
221 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
222 if (!W_ERROR_IS_OK(werr
)) {
223 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
227 werr
= registry_enumkey(key
, name
, c
->opt_reboot
);
228 if (W_ERROR_IS_OK(werr
)) {
236 static int net_registry_enumerate_recursive(struct net_context
*c
, int argc
,
240 struct registry_key
*key
= NULL
;
242 TALLOC_CTX
*ctx
= talloc_stackframe();
245 if (argc
!= 1 || c
->display_usage
) {
248 _("net registry enumerate <path>\n"));
251 _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
255 werr
= open_hive(ctx
, argv
[0], REG_KEY_READ
, &key
, &name
);
256 if (!W_ERROR_IS_OK(werr
)) {
257 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
261 werr
= registry_enumkey(key
, name
, true);
262 if (W_ERROR_IS_OK(werr
)) {
271 static int net_registry_createkey(struct net_context
*c
, int argc
,
275 enum winreg_CreateAction action
;
277 struct registry_key
*hivekey
= NULL
;
278 struct registry_key
*subkey
= NULL
;
279 TALLOC_CTX
*ctx
= talloc_stackframe();
282 if (argc
!= 1 || c
->display_usage
) {
285 _("net registry createkey <path>\n"));
288 _("net registry createkey "
289 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
292 if (strlen(argv
[0]) == 0) {
293 d_fprintf(stderr
, _("error: zero length key name given\n"));
297 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
298 if (!W_ERROR_IS_OK(werr
)) {
299 d_fprintf(stderr
, _("open_hive failed: %s\n"),
304 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
306 if (!W_ERROR_IS_OK(werr
)) {
307 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
312 case REG_ACTION_NONE
:
313 d_printf(_("createkey did nothing -- huh?\n"));
315 case REG_CREATED_NEW_KEY
:
316 d_printf(_("createkey created %s\n"), argv
[0]);
318 case REG_OPENED_EXISTING_KEY
:
319 d_printf(_("createkey opened existing %s\n"), argv
[0]);
330 static int net_registry_deletekey_internal(struct net_context
*c
, int argc
,
336 struct registry_key
*hivekey
= NULL
;
337 TALLOC_CTX
*ctx
= talloc_stackframe();
340 if (argc
!= 1 || c
->display_usage
) {
343 _("net registry deletekey <path>\n"));
346 _("net registry deletekey "
347 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
350 if (strlen(argv
[0]) == 0) {
351 d_fprintf(stderr
, _("error: zero length key name given\n"));
355 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
356 if (!W_ERROR_IS_OK(werr
)) {
357 d_fprintf(stderr
, "open_hive %s: %s\n", _("failed"),
363 werr
= reg_deletekey_recursive(hivekey
, subkeyname
);
365 werr
= reg_deletekey(hivekey
, subkeyname
);
367 if (!W_ERROR_IS_OK(werr
) &&
368 !(c
->opt_force
&& W_ERROR_EQUAL(werr
, WERR_BADFILE
)))
370 d_fprintf(stderr
, "reg_deletekey %s: %s\n", _("failed"),
382 static int net_registry_deletekey(struct net_context
*c
, int argc
,
385 return net_registry_deletekey_internal(c
, argc
, argv
, false);
388 static int net_registry_deletekey_recursive(struct net_context
*c
, int argc
,
391 return net_registry_deletekey_internal(c
, argc
, argv
, true);
394 static int net_registry_getvalue_internal(struct net_context
*c
, int argc
,
395 const char **argv
, bool raw
)
399 struct registry_key
*key
= NULL
;
400 struct registry_value
*value
= NULL
;
401 TALLOC_CTX
*ctx
= talloc_stackframe();
403 if (argc
!= 2 || c
->display_usage
) {
404 d_fprintf(stderr
, "%s\n%s",
406 _("net registry getvalue <key> <valuename>\n"));
410 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
411 if (!W_ERROR_IS_OK(werr
)) {
412 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
416 werr
= reg_queryvalue(ctx
, key
, argv
[1], &value
);
417 if (!W_ERROR_IS_OK(werr
)) {
418 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
423 print_registry_value(value
, raw
);
432 static int net_registry_getvalue(struct net_context
*c
, int argc
,
435 return net_registry_getvalue_internal(c
, argc
, argv
, false);
438 static int net_registry_getvalueraw(struct net_context
*c
, int argc
,
441 return net_registry_getvalue_internal(c
, argc
, argv
, true);
444 static int net_registry_getvaluesraw(struct net_context
*c
, int argc
,
449 struct registry_key
*key
= NULL
;
450 TALLOC_CTX
*ctx
= talloc_stackframe();
453 if (argc
!= 1 || c
->display_usage
) {
454 d_fprintf(stderr
, "usage: net rpc registry getvaluesraw "
459 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
460 if (!W_ERROR_IS_OK(werr
)) {
461 d_fprintf(stderr
, "open_key failed: %s\n", win_errstr(werr
));
467 struct registry_value
*val
;
469 werr
= reg_enumvalue(talloc_tos(), key
, idx
, NULL
, &val
);
471 if (W_ERROR_EQUAL(werr
, WERR_NO_MORE_ITEMS
)) {
475 if (!W_ERROR_IS_OK(werr
)) {
478 print_registry_value(val
, true);
487 static int net_registry_setvalue(struct net_context
*c
, int argc
,
491 struct registry_value value
;
492 struct registry_key
*key
= NULL
;
494 TALLOC_CTX
*ctx
= talloc_stackframe();
496 if (argc
< 4 || c
->display_usage
) {
497 d_fprintf(stderr
, "%s\n%s",
499 _("net registry setvalue <key> <valuename> "
500 "<type> [<val>]+\n"));
504 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
505 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
509 if (strequal(argv
[2], "dword")) {
510 uint32_t v
= strtoul(argv
[3], NULL
, 10);
511 value
.type
= REG_DWORD
;
512 value
.data
= data_blob_talloc(ctx
, NULL
, 4);
513 SIVAL(value
.data
.data
, 0, v
);
514 } else if (strequal(argv
[2], "sz")) {
516 if (!push_reg_sz(ctx
, &value
.data
, argv
[3])) {
519 } else if (strequal(argv
[2], "multi_sz")) {
521 int count
= argc
- 3;
523 value
.type
= REG_MULTI_SZ
;
524 array
= talloc_zero_array(ctx
, const char *, count
+ 1);
528 for (i
=0; i
< count
; i
++) {
529 array
[i
] = talloc_strdup(array
, argv
[count
+i
]);
530 if (array
[i
] == NULL
) {
534 if (!push_reg_multi_sz(ctx
, &value
.data
, array
)) {
538 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
542 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
543 if (!W_ERROR_IS_OK(werr
)) {
544 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
548 werr
= reg_setvalue(key
, argv
[1], &value
);
549 if (!W_ERROR_IS_OK(werr
)) {
550 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
562 struct net_registry_increment_state
{
564 const char *valuename
;
570 static void net_registry_increment_fn(void *private_data
)
572 struct net_registry_increment_state
*state
=
573 (struct net_registry_increment_state
*)private_data
;
574 struct registry_value
*value
;
575 struct registry_key
*key
= NULL
;
578 state
->werr
= open_key(talloc_tos(), state
->keyname
,
579 REG_KEY_READ
|REG_KEY_WRITE
, &key
);
580 if (!W_ERROR_IS_OK(state
->werr
)) {
581 d_fprintf(stderr
, _("open_key failed: %s\n"),
582 win_errstr(state
->werr
));
586 state
->werr
= reg_queryvalue(key
, key
, state
->valuename
, &value
);
587 if (!W_ERROR_IS_OK(state
->werr
)) {
588 d_fprintf(stderr
, _("reg_queryvalue failed: %s\n"),
589 win_errstr(state
->werr
));
593 if (value
->type
!= REG_DWORD
) {
594 d_fprintf(stderr
, _("value not a DWORD: %s\n"),
595 str_regtype(value
->type
));
599 if (value
->data
.length
< 4) {
600 d_fprintf(stderr
, _("value too short for regular DWORD\n"));
604 v
= IVAL(value
->data
.data
, 0);
605 v
+= state
->increment
;
608 SIVAL(value
->data
.data
, 0, v
);
610 state
->werr
= reg_setvalue(key
, state
->valuename
, value
);
611 if (!W_ERROR_IS_OK(state
->werr
)) {
612 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
613 win_errstr(state
->werr
));
622 static int net_registry_increment(struct net_context
*c
, int argc
,
625 struct net_registry_increment_state state
;
629 if (argc
< 2 || c
->display_usage
) {
630 d_fprintf(stderr
, "%s\n%s",
632 _("net registry increment <key> <valuename> "
637 state
.keyname
= argv
[0];
638 state
.valuename
= argv
[1];
642 state
.increment
= strtoul(argv
[2], NULL
, 10);
645 status
= g_lock_do("registry_increment_lock", G_LOCK_WRITE
,
647 net_registry_increment_fn
, &state
);
648 if (!NT_STATUS_IS_OK(status
)) {
649 d_fprintf(stderr
, _("g_lock_do failed: %s\n"),
653 if (!W_ERROR_IS_OK(state
.werr
)) {
654 d_fprintf(stderr
, _("increment failed: %s\n"),
655 win_errstr(state
.werr
));
659 d_printf(_("%u\n"), (unsigned)state
.newvalue
);
667 static int net_registry_deletevalue(struct net_context
*c
, int argc
,
671 struct registry_key
*key
= NULL
;
672 TALLOC_CTX
*ctx
= talloc_stackframe();
675 if (argc
!= 2 || c
->display_usage
) {
676 d_fprintf(stderr
, "%s\n%s",
678 _("net registry deletevalue <key> <valuename>\n"));
682 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
683 if (!W_ERROR_IS_OK(werr
)) {
684 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
688 werr
= reg_deletevalue(key
, argv
[1]);
689 if (!W_ERROR_IS_OK(werr
)) {
690 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
702 static WERROR
net_registry_getsd_internal(struct net_context
*c
,
705 struct security_descriptor
**sd
)
708 struct registry_key
*key
= NULL
;
709 TALLOC_CTX
*ctx
= talloc_stackframe();
710 uint32_t access_mask
= REG_KEY_READ
|
711 SEC_FLAG_MAXIMUM_ALLOWED
|
712 SEC_FLAG_SYSTEM_SECURITY
;
715 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
716 * is denied with these perms right now...
718 access_mask
= REG_KEY_READ
;
721 d_fprintf(stderr
, _("internal error: invalid argument\n"));
722 werr
= WERR_INVALID_PARAM
;
726 if (strlen(keyname
) == 0) {
727 d_fprintf(stderr
, _("error: zero length key name given\n"));
728 werr
= WERR_INVALID_PARAM
;
732 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
733 if (!W_ERROR_IS_OK(werr
)) {
734 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
739 werr
= reg_getkeysecurity(mem_ctx
, key
, sd
);
740 if (!W_ERROR_IS_OK(werr
)) {
741 d_fprintf(stderr
, "%s%s\n", _("reg_getkeysecurity failed: "),
753 static int net_registry_getsd(struct net_context
*c
, int argc
,
758 struct security_descriptor
*secdesc
= NULL
;
759 TALLOC_CTX
*ctx
= talloc_stackframe();
761 if (argc
!= 1 || c
->display_usage
) {
764 _("net registry getsd <path>\n"));
767 _("net registry getsd 'HKLM\\Software\\Samba'\n"));
771 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
772 if (!W_ERROR_IS_OK(werr
)) {
776 display_sec_desc(secdesc
);
785 static int net_registry_getsd_sddl(struct net_context
*c
,
786 int argc
, const char **argv
)
790 struct security_descriptor
*secdesc
= NULL
;
791 TALLOC_CTX
*ctx
= talloc_stackframe();
793 if (argc
!= 1 || c
->display_usage
) {
796 _("net registry getsd_sddl <path>\n"));
799 _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
803 werr
= net_registry_getsd_internal(c
, ctx
, argv
[0], &secdesc
);
804 if (!W_ERROR_IS_OK(werr
)) {
808 d_printf("%s\n", sddl_encode(ctx
, secdesc
, get_global_sam_sid()));
817 static WERROR
net_registry_setsd_internal(struct net_context
*c
,
820 struct security_descriptor
*sd
)
823 struct registry_key
*key
= NULL
;
824 TALLOC_CTX
*ctx
= talloc_stackframe();
825 uint32_t access_mask
= REG_KEY_WRITE
|
826 SEC_FLAG_MAXIMUM_ALLOWED
|
827 SEC_FLAG_SYSTEM_SECURITY
;
830 * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
831 * is denied with these perms right now...
833 access_mask
= REG_KEY_WRITE
;
835 if (strlen(keyname
) == 0) {
836 d_fprintf(stderr
, _("error: zero length key name given\n"));
837 werr
= WERR_INVALID_PARAM
;
841 werr
= open_key(ctx
, keyname
, access_mask
, &key
);
842 if (!W_ERROR_IS_OK(werr
)) {
843 d_fprintf(stderr
, "%s%s\n", _("open_key failed: "),
848 werr
= reg_setkeysecurity(key
, sd
);
849 if (!W_ERROR_IS_OK(werr
)) {
850 d_fprintf(stderr
, "%s%s\n", _("reg_setkeysecurity failed: "),
862 static int net_registry_setsd_sddl(struct net_context
*c
,
863 int argc
, const char **argv
)
867 struct security_descriptor
*secdesc
= NULL
;
868 TALLOC_CTX
*ctx
= talloc_stackframe();
870 if (argc
!= 2 || c
->display_usage
) {
873 _("net registry setsd_sddl <path> <security_descriptor>\n"));
876 _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
880 secdesc
= sddl_decode(ctx
, argv
[1], get_global_sam_sid());
881 if (secdesc
== NULL
) {
885 werr
= net_registry_setsd_internal(c
, ctx
, argv
[0], secdesc
);
886 if (!W_ERROR_IS_OK(werr
)) {
897 /******************************************************************************/
899 * @defgroup net_registry net registry
903 * @defgroup net_registry_import Import
904 * @ingroup net_registry
913 static WERROR
import_create_key(struct import_ctx
* ctx
,
914 struct registry_key
* parent
,
915 const char* name
, void** pkey
, bool* existing
)
918 void* mem_ctx
= talloc_new(ctx
->mem_ctx
);
920 struct registry_key
* key
= NULL
;
921 enum winreg_CreateAction action
;
923 if (parent
== NULL
) {
924 char* subkeyname
= NULL
;
925 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
926 &parent
, &subkeyname
);
927 if (!W_ERROR_IS_OK(werr
)) {
928 d_fprintf(stderr
, _("open_hive failed: %s\n"),
935 action
= REG_ACTION_NONE
;
936 werr
= reg_createkey(mem_ctx
, parent
, name
, REG_KEY_WRITE
,
938 if (!W_ERROR_IS_OK(werr
)) {
939 d_fprintf(stderr
, _("reg_createkey failed: %s\n"),
944 if (action
== REG_ACTION_NONE
) {
945 d_fprintf(stderr
, _("createkey did nothing -- huh?\n"));
946 werr
= WERR_CREATE_FAILED
;
950 if (existing
!= NULL
) {
951 *existing
= (action
== REG_OPENED_EXISTING_KEY
);
955 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
959 talloc_free(mem_ctx
);
963 static WERROR
import_close_key(struct import_ctx
* ctx
,
964 struct registry_key
* key
)
969 static WERROR
import_delete_key(struct import_ctx
* ctx
,
970 struct registry_key
* parent
, const char* name
)
973 void* mem_ctx
= talloc_new(talloc_tos());
975 if (parent
== NULL
) {
976 char* subkeyname
= NULL
;
977 werr
= open_hive(mem_ctx
, name
, REG_KEY_WRITE
,
978 &parent
, &subkeyname
);
979 if (!W_ERROR_IS_OK(werr
)) {
980 d_fprintf(stderr
, _("open_hive failed: %s\n"),
987 werr
= reg_deletekey_recursive(parent
, name
);
988 if (!W_ERROR_IS_OK(werr
)) {
989 d_fprintf(stderr
, "reg_deletekey_recursive %s: %s\n", _("failed"),
995 talloc_free(mem_ctx
);
999 static WERROR
import_create_val (struct import_ctx
* ctx
,
1000 struct registry_key
* parent
, const char* name
,
1001 const struct registry_value
* value
)
1005 if (parent
== NULL
) {
1006 return WERR_INVALID_PARAM
;
1009 werr
= reg_setvalue(parent
, name
, value
);
1010 if (!W_ERROR_IS_OK(werr
)) {
1011 d_fprintf(stderr
, _("reg_setvalue failed: %s\n"),
1017 static WERROR
import_delete_val (struct import_ctx
* ctx
, struct registry_key
* parent
, const char* name
) {
1020 if (parent
== NULL
) {
1021 return WERR_INVALID_PARAM
;
1024 werr
= reg_deletevalue(parent
, name
);
1025 if (!W_ERROR_IS_OK(werr
)) {
1026 d_fprintf(stderr
, _("reg_deletevalue failed: %s\n"),
1033 struct precheck_ctx
{
1034 TALLOC_CTX
*mem_ctx
;
1038 static WERROR
precheck_create_key(struct precheck_ctx
*ctx
,
1039 struct registry_key
*parent
,
1040 const char *name
, void **pkey
, bool *existing
)
1043 TALLOC_CTX
*frame
= talloc_stackframe();
1044 struct registry_key
*key
= NULL
;
1046 if (parent
== NULL
) {
1047 char *subkeyname
= NULL
;
1048 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1049 &parent
, &subkeyname
);
1050 if (!W_ERROR_IS_OK(werr
)) {
1051 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1052 name
, win_errstr(werr
));
1058 werr
= reg_openkey(frame
, parent
, name
, 0, &key
);
1059 if (!W_ERROR_IS_OK(werr
)) {
1060 d_printf("Precheck: openkey [%s] failed: %s\n",
1061 name
, win_errstr(werr
));
1065 if (existing
!= NULL
) {
1070 *pkey
= talloc_steal(ctx
->mem_ctx
, key
);
1075 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1079 static WERROR
precheck_close_key(struct precheck_ctx
*ctx
,
1080 struct registry_key
*key
)
1086 static WERROR
precheck_delete_key(struct precheck_ctx
*ctx
,
1087 struct registry_key
*parent
, const char *name
)
1090 TALLOC_CTX
*frame
= talloc_stackframe();
1091 struct registry_key
*key
;
1093 if (parent
== NULL
) {
1094 char *subkeyname
= NULL
;
1095 werr
= open_hive(frame
, name
, REG_KEY_READ
,
1096 &parent
, &subkeyname
);
1097 if (!W_ERROR_IS_OK(werr
)) {
1098 d_printf("Precheck: open_hive of [%s] failed: %s\n",
1099 name
, win_errstr(werr
));
1105 werr
= reg_openkey(ctx
->mem_ctx
, parent
, name
, 0, &key
);
1106 if (W_ERROR_IS_OK(werr
)) {
1107 d_printf("Precheck: key [%s\\%s] should not exist\n",
1108 parent
->key
->name
, name
);
1109 werr
= WERR_FILE_EXISTS
;
1110 } else if (W_ERROR_EQUAL(werr
, WERR_BADFILE
)) {
1113 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
1114 parent
->key
->name
, name
, win_errstr(werr
));
1119 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1123 static WERROR
precheck_create_val(struct precheck_ctx
*ctx
,
1124 struct registry_key
*parent
,
1126 const struct registry_value
*value
)
1128 TALLOC_CTX
*frame
= talloc_stackframe();
1129 struct registry_value
*old
;
1134 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1135 if (!W_ERROR_IS_OK(werr
)) {
1136 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
1137 name
, parent
->key
->name
, win_errstr(werr
));
1140 if (registry_value_cmp(value
, old
) != 0) {
1141 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
1142 name
, parent
->key
->name
);
1150 static WERROR
precheck_delete_val(struct precheck_ctx
*ctx
,
1151 struct registry_key
*parent
,
1154 TALLOC_CTX
*frame
= talloc_stackframe();
1155 struct registry_value
*old
;
1160 werr
= reg_queryvalue(frame
, parent
, name
, &old
);
1161 if (W_ERROR_IS_OK(werr
)) {
1162 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
1163 name
, parent
->key
->name
);
1164 werr
= WERR_FILE_EXISTS
;
1165 } else if (W_ERROR_EQUAL(werr
, WERR_BADFILE
)) {
1168 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
1169 name
, parent
->key
->name
, win_errstr(werr
));
1173 ctx
->failed
= !W_ERROR_IS_OK(werr
);
1177 static bool import_precheck(const char *fname
, const char *parse_options
)
1179 TALLOC_CTX
*mem_ctx
= talloc_tos();
1180 struct precheck_ctx precheck_ctx
= {
1184 struct reg_import_callback precheck_callback
= {
1186 .closekey
= (reg_import_callback_closekey_t
)&precheck_close_key
,
1187 .createkey
= (reg_import_callback_createkey_t
)&precheck_create_key
,
1188 .deletekey
= (reg_import_callback_deletekey_t
)&precheck_delete_key
,
1189 .deleteval
= (reg_import_callback_deleteval_t
)&precheck_delete_val
,
1191 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1192 &precheck_create_val
,
1194 .setval_type
= REGISTRY_VALUE
,
1195 .data
= &precheck_ctx
1197 struct reg_parse_callback
*parse_callback
;
1204 parse_callback
= reg_import_adapter(mem_ctx
, precheck_callback
);
1205 if (parse_callback
== NULL
) {
1206 d_printf("talloc failed\n");
1210 ret
= reg_parse_file(fname
, parse_callback
, parse_options
);
1212 if (ret
< 0 || precheck_ctx
.failed
) {
1213 d_printf("Precheck failed\n");
1220 static int net_registry_import(struct net_context
*c
, int argc
,
1223 TALLOC_CTX
*frame
= talloc_stackframe();
1224 struct import_ctx import_ctx
= {
1227 struct reg_import_callback import_callback
= {
1229 .closekey
= (reg_import_callback_closekey_t
)&import_close_key
,
1230 .createkey
= (reg_import_callback_createkey_t
)&import_create_key
,
1231 .deletekey
= (reg_import_callback_deletekey_t
)&import_delete_key
,
1232 .deleteval
= (reg_import_callback_deleteval_t
)&import_delete_val
,
1234 .registry_value
= (reg_import_callback_setval_registry_value_t
)
1237 .setval_type
= REGISTRY_VALUE
,
1240 const char *parse_options
= (argc
> 1) ? argv
[1] : NULL
;
1244 if (argc
< 1 || argc
> 2 || c
->display_usage
) {
1247 _("net registry import <reg> [options]\n"));
1250 _("net registry import file.reg enc=CP1252\n"));
1254 werr
= regdb_open();
1255 if (!W_ERROR_IS_OK(werr
)) {
1256 d_printf("Failed to open regdb: %s\n", win_errstr(werr
));
1259 werr
= regdb_transaction_start();
1260 if (!W_ERROR_IS_OK(werr
)) {
1261 d_printf("Failed to start transaction on regdb: %s\n",
1266 if (import_precheck(c
->opt_precheck
, parse_options
)) {
1267 ret
= reg_parse_file(argv
[0],
1268 reg_import_adapter(frame
, import_callback
),
1273 d_printf("Transaction canceled!\n");
1274 regdb_transaction_cancel();
1276 werr
= regdb_transaction_commit();
1277 if (!W_ERROR_IS_OK(werr
)) {
1278 d_printf("Failed to commit transaction on regdb: %s\n",
1291 /******************************************************************************/
1294 * @defgroup net_registry_export Export
1295 * @ingroup net_registry
1299 static int registry_export(TALLOC_CTX
*ctx
, /*const*/ struct registry_key
* key
,
1300 struct reg_format
* f
)
1306 struct registry_value
*valvalue
= NULL
;
1307 char *valname
= NULL
;
1309 char *subkey_name
= NULL
;
1312 reg_format_registry_key(f
, key
, false);
1316 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
1317 W_ERROR_IS_OK(werr
);
1320 reg_format_registry_value(f
, valname
, valvalue
);
1322 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1323 d_fprintf(stderr
, _("reg_enumvalue failed: %s\n"),
1328 /* recurse on subkeys */
1330 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, &modtime
),
1331 W_ERROR_IS_OK(werr
);
1334 struct registry_key
* subkey
= NULL
;
1336 werr
= reg_openkey(ctx
, key
, subkey_name
, REG_KEY_READ
,
1338 if (!W_ERROR_IS_OK(werr
)) {
1339 d_fprintf(stderr
, _("reg_openkey failed: %s\n"),
1344 registry_export(ctx
, subkey
, f
);
1345 TALLOC_FREE(subkey
);
1347 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
1348 d_fprintf(stderr
, _("reg_enumkey failed: %s\n"),
1357 static int net_registry_export(struct net_context
*c
, int argc
,
1362 struct registry_key
*key
= NULL
;
1363 TALLOC_CTX
*ctx
= talloc_stackframe();
1364 struct reg_format
* f
=NULL
;
1366 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1369 _("net registry export <path> <file> [opt]\n"));
1372 _("net registry export 'HKLM\\Software\\Samba' "
1373 "samba.reg regedit5\n"));
1377 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
1378 if (!W_ERROR_IS_OK(werr
)) {
1379 d_fprintf(stderr
, _("open_key failed: %s\n"), win_errstr(werr
));
1383 f
= reg_format_file(ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1385 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1389 ret
= registry_export(ctx
, key
, f
);
1397 /******************************************************************************/
1399 * @defgroup net_registry_convert Convert
1400 * @ingroup net_registry
1404 static int net_registry_convert(struct net_context
*c
, int argc
,
1409 const char* in_opt
= NULL
;
1410 const char* out_opt
= NULL
;
1412 if (argc
< 2 || argc
> 4|| c
->display_usage
) {
1415 _("net registry convert <in> <out> [in_opt] [out_opt]\n"
1416 "net registry convert <in> <out> [out_opt]\n"));
1419 _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
1423 mem_ctx
= talloc_stackframe();
1440 ret
= reg_parse_file(argv
[0], (struct reg_parse_callback
*)
1441 reg_format_file(mem_ctx
, argv
[1], out_opt
),
1444 talloc_free(mem_ctx
);
1450 static int net_registry_check(struct net_context
*c
, int argc
,
1454 struct check_options opts
;
1456 if (argc
> 1|| c
->display_usage
) {
1459 _("net registry check [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
1460 " Check a registry database.\n"
1461 " -v|--verbose\t be verbose\n"
1462 " -r|--repair\t\t interactive repair mode\n"
1463 " -a|--auto\t\t noninteractive repair mode\n"
1464 " -T|--test\t\t dry run\n"
1465 " -f|--force\t\t force\n"
1466 " -l|--lock\t\t lock <TDB> while doing the check\n"
1467 " -o|--output=<ODB>\t output database\n"
1468 " --reg-version=n\t assume database format version {n|1,2,3}\n"
1469 " --wipe\t\t create a new database from scratch\n"
1470 " --db=<TDB>\t\t registry database to open\n"));
1471 return c
->display_usage
? 0 : -1;
1474 dbfile
= c
->opt_db
? c
->opt_db
: (
1475 (argc
> 0) ? argv
[0] :
1476 state_path("registry.tdb"));
1477 if (dbfile
== NULL
) {
1481 opts
= (struct check_options
) {
1482 .lock
= c
->opt_lock
|| c
->opt_long_list_entries
,
1483 .test
= c
->opt_testmode
,
1484 .automatic
= c
->opt_auto
,
1485 .verbose
= c
->opt_verbose
,
1486 .force
= c
->opt_force
,
1487 .repair
= c
->opt_repair
|| c
->opt_reboot
,
1488 .version
= c
->opt_reg_version
,
1489 .output
= c
->opt_output
,
1490 .wipe
= c
->opt_wipe
,
1491 .implicit_db
= (c
->opt_db
== NULL
) && (argc
== 0),
1494 return net_registry_check_db(dbfile
, &opts
);
1498 /******************************************************************************/
1500 int net_registry(struct net_context
*c
, int argc
, const char **argv
)
1504 struct functable func
[] = {
1507 net_registry_enumerate
,
1508 NET_TRANSPORT_LOCAL
,
1509 N_("Enumerate registry keys and values"),
1510 N_("net registry enumerate\n"
1511 " Enumerate registry keys and values")
1514 "enumerate_recursive",
1515 net_registry_enumerate_recursive
,
1516 NET_TRANSPORT_LOCAL
,
1517 N_("Enumerate registry keys and values"),
1518 N_("net registry enumerate_recursive\n"
1519 " Enumerate registry keys and values")
1523 net_registry_createkey
,
1524 NET_TRANSPORT_LOCAL
,
1525 N_("Create a new registry key"),
1526 N_("net registry createkey\n"
1527 " Create a new registry key")
1531 net_registry_deletekey
,
1532 NET_TRANSPORT_LOCAL
,
1533 N_("Delete a registry key"),
1534 N_("net registry deletekey\n"
1535 " Delete a registry key")
1538 "deletekey_recursive",
1539 net_registry_deletekey_recursive
,
1540 NET_TRANSPORT_LOCAL
,
1541 N_("Delete a registry key with subkeys"),
1542 N_("net registry deletekey_recursive\n"
1543 " Delete a registry key with subkeys")
1547 net_registry_getvalue
,
1548 NET_TRANSPORT_LOCAL
,
1549 N_("Print a registry value"),
1550 N_("net registry getvalue\n"
1551 " Print a registry value")
1555 net_registry_getvalueraw
,
1556 NET_TRANSPORT_LOCAL
,
1557 N_("Print a registry value (raw format)"),
1558 N_("net registry getvalueraw\n"
1559 " Print a registry value (raw format)")
1563 net_registry_getvaluesraw
,
1564 NET_TRANSPORT_LOCAL
,
1565 "Print all values of a key in raw format",
1566 "net registry getvaluesraw <key>\n"
1567 " Print a registry value (raw format)"
1571 net_registry_setvalue
,
1572 NET_TRANSPORT_LOCAL
,
1573 N_("Set a new registry value"),
1574 N_("net registry setvalue\n"
1575 " Set a new registry value")
1579 net_registry_increment
,
1580 NET_TRANSPORT_LOCAL
,
1581 N_("Increment a DWORD registry value under a lock"),
1582 N_("net registry increment\n"
1583 " Increment a DWORD registry value under a lock")
1587 net_registry_deletevalue
,
1588 NET_TRANSPORT_LOCAL
,
1589 N_("Delete a registry value"),
1590 N_("net registry deletevalue\n"
1591 " Delete a registry value")
1596 NET_TRANSPORT_LOCAL
,
1597 N_("Get security descriptor"),
1598 N_("net registry getsd\n"
1599 " Get security descriptor")
1603 net_registry_getsd_sddl
,
1604 NET_TRANSPORT_LOCAL
,
1605 N_("Get security descriptor in sddl format"),
1606 N_("net registry getsd_sddl\n"
1607 " Get security descriptor in sddl format")
1611 net_registry_setsd_sddl
,
1612 NET_TRANSPORT_LOCAL
,
1613 N_("Set security descriptor from sddl format string"),
1614 N_("net registry setsd_sddl\n"
1615 " Set security descriptor from sddl format string")
1619 net_registry_import
,
1620 NET_TRANSPORT_LOCAL
,
1621 N_("Import .reg file"),
1622 N_("net registry import\n"
1623 " Import .reg file")
1627 net_registry_export
,
1628 NET_TRANSPORT_LOCAL
,
1629 N_("Export .reg file"),
1630 N_("net registry export\n"
1631 " Export .reg file")
1635 net_registry_convert
,
1636 NET_TRANSPORT_LOCAL
,
1637 N_("Convert .reg file"),
1638 N_("net registry convert\n"
1639 " Convert .reg file")
1644 NET_TRANSPORT_LOCAL
,
1645 N_("Check a registry database"),
1646 N_("net registry check\n"
1647 " Check a registry database")
1649 { NULL
, NULL
, 0, NULL
, NULL
}
1652 if (!c
->display_usage
1654 && (strcasecmp_m(argv
[0], "convert") != 0)
1655 && (strcasecmp_m(argv
[0], "check") != 0))
1657 if (!W_ERROR_IS_OK(registry_init_basic())) {
1662 ret
= net_run_function(c
, argc
, argv
, "net registry", func
);