2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "popt_common.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "registry/reg_format.h"
33 /*******************************************************************
34 connect to a registry hive root (open a registry policy)
35 *******************************************************************/
37 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
38 uint32_t reg_type
, uint32_t access_mask
,
39 struct policy_handle
*reg_hnd
, WERROR
*werr
)
41 ZERO_STRUCTP(reg_hnd
);
45 case HKEY_CLASSES_ROOT
:
46 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
47 access_mask
, reg_hnd
, werr
);
49 case HKEY_LOCAL_MACHINE
:
50 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
51 access_mask
, reg_hnd
, werr
);
54 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
55 access_mask
, reg_hnd
, werr
);
57 case HKEY_CURRENT_USER
:
58 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
59 access_mask
, reg_hnd
, werr
);
61 case HKEY_PERFORMANCE_DATA
:
62 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
63 access_mask
, reg_hnd
, werr
);
66 /* fall through to end of function */
70 return NT_STATUS_INVALID_PARAMETER
;
73 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
74 uint32
*reg_type
, const char **key_name
)
77 char *hivename
= NULL
;
78 char *tmp_keyname
= NULL
;
80 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
82 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
83 if (!W_ERROR_IS_OK(werr
)) {
87 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
88 if (*key_name
== NULL
) {
92 if (strequal(hivename
, "HKLM") ||
93 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
95 (*reg_type
) = HKEY_LOCAL_MACHINE
;
96 } else if (strequal(hivename
, "HKCR") ||
97 strequal(hivename
, "HKEY_CLASSES_ROOT"))
99 (*reg_type
) = HKEY_CLASSES_ROOT
;
100 } else if (strequal(hivename
, "HKU") ||
101 strequal(hivename
, "HKEY_USERS"))
103 (*reg_type
) = HKEY_USERS
;
104 } else if (strequal(hivename
, "HKCU") ||
105 strequal(hivename
, "HKEY_CURRENT_USER"))
107 (*reg_type
) = HKEY_CURRENT_USER
;
108 } else if (strequal(hivename
, "HKPD") ||
109 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
111 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
113 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
121 TALLOC_FREE(tmp_ctx
);
125 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
126 struct rpc_pipe_client
*pipe_hnd
,
127 const char *name
, uint32 access_mask
,
128 struct policy_handle
*hive_hnd
,
129 struct policy_handle
*key_hnd
)
133 struct winreg_String key
;
137 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
138 return NT_STATUS_INVALID_PARAMETER
;
141 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
143 if (!(NT_STATUS_IS_OK(status
))) {
147 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
148 access_mask
, key_hnd
, NULL
);
149 if (!(NT_STATUS_IS_OK(status
))) {
150 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
157 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
158 struct rpc_pipe_client
*pipe_hnd
,
159 struct policy_handle
*key_hnd
,
160 uint32
*pnum_keys
, char ***pnames
,
161 char ***pclasses
, NTTIME
***pmodtimes
)
165 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
166 uint32 num_values
, max_valnamelen
, max_valbufsize
;
168 NTTIME last_changed_time
;
170 struct winreg_String classname
;
171 char **names
, **classes
;
174 if (!(mem_ctx
= talloc_new(ctx
))) {
175 return NT_STATUS_NO_MEMORY
;
178 ZERO_STRUCT(classname
);
179 status
= rpccli_winreg_QueryInfoKey(
180 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
181 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
182 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
184 if (!NT_STATUS_IS_OK(status
)) {
188 if (num_subkeys
== 0) {
190 TALLOC_FREE(mem_ctx
);
194 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
195 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
196 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
198 status
= NT_STATUS_NO_MEMORY
;
202 for (i
=0; i
<num_subkeys
; i
++) {
204 struct winreg_StringBuf class_buf
;
205 struct winreg_StringBuf name_buf
;
211 class_buf
.size
= max_classlen
+2;
215 name_buf
.size
= max_subkeylen
+2;
217 ZERO_STRUCT(modtime
);
219 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
220 i
, &name_buf
, &class_buf
,
223 if (W_ERROR_EQUAL(werr
,
224 WERR_NO_MORE_ITEMS
) ) {
225 status
= NT_STATUS_OK
;
228 if (!NT_STATUS_IS_OK(status
)) {
234 if (class_buf
.name
&&
235 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
236 status
= NT_STATUS_NO_MEMORY
;
240 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
241 status
= NT_STATUS_NO_MEMORY
;
245 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
246 modtimes
, &modtime
, sizeof(modtime
))))) {
247 status
= NT_STATUS_NO_MEMORY
;
252 *pnum_keys
= num_subkeys
;
255 *pnames
= talloc_move(ctx
, &names
);
258 *pclasses
= talloc_move(ctx
, &classes
);
261 *pmodtimes
= talloc_move(ctx
, &modtimes
);
264 status
= NT_STATUS_OK
;
267 TALLOC_FREE(mem_ctx
);
271 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
272 struct rpc_pipe_client
*pipe_hnd
,
273 struct policy_handle
*key_hnd
,
274 uint32
*pnum_values
, char ***pvalnames
,
275 struct registry_value
***pvalues
)
279 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
280 uint32 num_values
, max_valnamelen
, max_valbufsize
;
282 NTTIME last_changed_time
;
284 struct winreg_String classname
;
285 struct registry_value
**values
;
288 if (!(mem_ctx
= talloc_new(ctx
))) {
289 return NT_STATUS_NO_MEMORY
;
292 ZERO_STRUCT(classname
);
293 status
= rpccli_winreg_QueryInfoKey(
294 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
295 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
296 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
298 if (!NT_STATUS_IS_OK(status
)) {
302 if (num_values
== 0) {
304 TALLOC_FREE(mem_ctx
);
308 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
309 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
311 status
= NT_STATUS_NO_MEMORY
;
315 for (i
=0; i
<num_values
; i
++) {
316 enum winreg_Type type
= REG_NONE
;
322 struct winreg_ValNameBuf name_buf
;
327 name_buf
.size
= max_valnamelen
+ 2;
329 data_size
= max_valbufsize
;
330 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
333 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
336 &value_length
, &err
);
338 if ( W_ERROR_EQUAL(err
,
339 WERR_NO_MORE_ITEMS
) ) {
340 status
= NT_STATUS_OK
;
344 if (!(NT_STATUS_IS_OK(status
))) {
348 if (name_buf
.name
== NULL
) {
349 status
= NT_STATUS_INVALID_PARAMETER
;
353 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
354 status
= NT_STATUS_NO_MEMORY
;
358 values
[i
] = talloc_zero(values
, struct registry_value
);
359 if (values
[i
] == NULL
) {
360 status
= NT_STATUS_NO_MEMORY
;
364 values
[i
]->type
= type
;
365 values
[i
]->data
= data_blob_talloc(values
[i
], data
, data_size
);
368 *pnum_values
= num_values
;
371 *pvalnames
= talloc_move(ctx
, &names
);
374 *pvalues
= talloc_move(ctx
, &values
);
377 status
= NT_STATUS_OK
;
380 TALLOC_FREE(mem_ctx
);
384 static NTSTATUS
registry_enumvalues2(TALLOC_CTX
*ctx
,
385 struct rpc_pipe_client
*pipe_hnd
,
386 struct policy_handle
*key_hnd
,
387 uint32
*pnum_values
, char ***pvalnames
,
388 struct regval_blob
***pvalues
)
392 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
393 uint32 num_values
, max_valnamelen
, max_valbufsize
;
395 NTTIME last_changed_time
;
397 struct winreg_String classname
;
398 struct regval_blob
**values
;
401 if (!(mem_ctx
= talloc_new(ctx
))) {
402 return NT_STATUS_NO_MEMORY
;
405 ZERO_STRUCT(classname
);
406 status
= rpccli_winreg_QueryInfoKey(
407 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
408 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
409 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
411 if (!NT_STATUS_IS_OK(status
)) {
415 if (num_values
== 0) {
417 TALLOC_FREE(mem_ctx
);
421 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
422 (!(values
= TALLOC_ARRAY(mem_ctx
, struct regval_blob
*,
424 status
= NT_STATUS_NO_MEMORY
;
428 for (i
=0; i
<num_values
; i
++) {
429 enum winreg_Type type
= REG_NONE
;
435 struct winreg_ValNameBuf name_buf
;
440 name_buf
.size
= max_valnamelen
+ 2;
442 data_size
= max_valbufsize
;
443 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
446 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
449 &value_length
, &err
);
451 if ( W_ERROR_EQUAL(err
, WERR_NO_MORE_ITEMS
) ) {
452 status
= NT_STATUS_OK
;
456 if (!(NT_STATUS_IS_OK(status
))) {
460 if (name_buf
.name
== NULL
) {
461 status
= NT_STATUS_INVALID_PARAMETER
;
465 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
466 status
= NT_STATUS_NO_MEMORY
;
470 assert(value_length
<=data_size
); //???
472 values
[i
] = regval_compose(values
,
477 status
= NT_STATUS_NO_MEMORY
;
482 *pnum_values
= num_values
;
485 *pvalnames
= talloc_move(ctx
, &names
);
488 *pvalues
= talloc_move(ctx
, &values
);
491 status
= NT_STATUS_OK
;
494 TALLOC_FREE(mem_ctx
);
498 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
499 struct rpc_pipe_client
*pipe_hnd
,
500 struct policy_handle
*key_hnd
,
502 struct KeySecurityData
*sd
)
504 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
509 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
510 struct rpc_pipe_client
*pipe_hnd
,
511 struct policy_handle
*key_hnd
,
513 const struct registry_value
*value
)
515 struct winreg_String name_string
;
518 ZERO_STRUCT(name_string
);
520 name_string
.name
= name
;
521 result
= rpccli_winreg_SetValue(pipe_hnd
, mem_ctx
, key_hnd
,
522 name_string
, value
->type
,
523 value
->data
.data
, value
->data
.length
, NULL
);
527 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
528 const struct dom_sid
*domain_sid
,
529 const char *domain_name
,
530 struct cli_state
*cli
,
531 struct rpc_pipe_client
*pipe_hnd
,
536 struct policy_handle hive_hnd
, key_hnd
;
538 struct registry_value value
;
540 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
541 SEC_FLAG_MAXIMUM_ALLOWED
,
542 &hive_hnd
, &key_hnd
);
543 if (!NT_STATUS_IS_OK(status
)) {
544 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
549 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
550 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
551 return NT_STATUS_NOT_IMPLEMENTED
;
554 if (strequal(argv
[2], "dword")) {
555 uint32_t v
= strtoul(argv
[3], NULL
, 10);
556 value
.type
= REG_DWORD
;
557 value
.data
= data_blob_talloc(mem_ctx
, NULL
, 4);
558 SIVAL(value
.data
.data
, 0, v
);
560 else if (strequal(argv
[2], "sz")) {
562 if (!push_reg_sz(mem_ctx
, &value
.data
, argv
[3])) {
563 status
= NT_STATUS_NO_MEMORY
;
568 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
569 status
= NT_STATUS_NOT_IMPLEMENTED
;
573 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
576 if (!NT_STATUS_IS_OK(status
)) {
577 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
582 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
583 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
588 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
591 if (argc
< 4 || c
->display_usage
) {
592 d_fprintf(stderr
, "%s\n%s",
594 _("net rpc registry setvalue <key> <valuename> "
595 "<type> [<val>]+\n"));
599 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
600 rpc_registry_setvalue_internal
, argc
, argv
);
603 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
604 const struct dom_sid
*domain_sid
,
605 const char *domain_name
,
606 struct cli_state
*cli
,
607 struct rpc_pipe_client
*pipe_hnd
,
612 struct policy_handle hive_hnd
, key_hnd
;
614 struct winreg_String valuename
;
616 ZERO_STRUCT(valuename
);
618 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
619 SEC_FLAG_MAXIMUM_ALLOWED
,
620 &hive_hnd
, &key_hnd
);
621 if (!NT_STATUS_IS_OK(status
)) {
622 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
627 valuename
.name
= argv
[1];
629 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
632 if (!NT_STATUS_IS_OK(status
)) {
633 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
637 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
638 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
643 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
646 if (argc
!= 2 || c
->display_usage
) {
647 d_fprintf(stderr
, "%s\n%s",
649 _("net rpc registry deletevalue <key> <valuename>\n"));
653 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
654 rpc_registry_deletevalue_internal
, argc
, argv
);
657 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
658 const struct dom_sid
*domain_sid
,
659 const char *domain_name
,
660 struct cli_state
*cli
,
661 struct rpc_pipe_client
*pipe_hnd
,
667 struct policy_handle hive_hnd
, key_hnd
;
669 struct winreg_String valuename
;
670 struct registry_value
*value
= NULL
;
671 enum winreg_Type type
= REG_NONE
;
672 uint32_t data_size
= 0;
673 uint32_t value_length
= 0;
674 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
676 ZERO_STRUCT(valuename
);
678 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
679 SEC_FLAG_MAXIMUM_ALLOWED
,
680 &hive_hnd
, &key_hnd
);
681 if (!NT_STATUS_IS_OK(status
)) {
682 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
687 valuename
.name
= argv
[1];
689 value
= talloc_zero(tmp_ctx
, struct registry_value
);
691 return NT_STATUS_NO_MEMORY
;
695 * call QueryValue once with data == NULL to get the
696 * needed memory size to be allocated, then allocate
697 * data buffer and call again.
699 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
707 if (!NT_STATUS_IS_OK(status
)) {
708 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
713 value
->data
= data_blob_talloc(tmp_ctx
, NULL
, data_size
);
715 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
723 if (!NT_STATUS_IS_OK(status
)) {
724 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
731 print_registry_value(value
, raw
);
734 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
735 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
737 TALLOC_FREE(tmp_ctx
);
742 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
743 const struct dom_sid
*domain_sid
,
744 const char *domain_name
,
745 struct cli_state
*cli
,
746 struct rpc_pipe_client
*pipe_hnd
,
751 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
752 cli
, pipe_hnd
, mem_ctx
, false,
756 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
759 if (argc
!= 2 || c
->display_usage
) {
760 d_fprintf(stderr
, "%s\n%s",
762 _("net rpc registry getvalue <key> <valuename>\n"));
766 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
767 rpc_registry_getvalue_full
, argc
, argv
);
770 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
771 const struct dom_sid
*domain_sid
,
772 const char *domain_name
,
773 struct cli_state
*cli
,
774 struct rpc_pipe_client
*pipe_hnd
,
779 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
780 cli
, pipe_hnd
, mem_ctx
, true,
784 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
787 if (argc
!= 2 || c
->display_usage
) {
788 d_fprintf(stderr
, "%s\n%s",
790 _("net rpc registry getvalue <key> <valuename>\n"));
794 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
795 rpc_registry_getvalue_raw
, argc
, argv
);
798 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
799 const struct dom_sid
*domain_sid
,
800 const char *domain_name
,
801 struct cli_state
*cli
,
802 struct rpc_pipe_client
*pipe_hnd
,
808 struct policy_handle hive_hnd
, key_hnd
;
809 struct winreg_String key
, keyclass
;
810 enum winreg_CreateAction action
;
814 ZERO_STRUCT(keyclass
);
816 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
817 return NT_STATUS_INVALID_PARAMETER
;
820 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
821 SEC_FLAG_MAXIMUM_ALLOWED
,
823 if (!(NT_STATUS_IS_OK(status
))) {
827 action
= REG_ACTION_NONE
;
830 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
831 keyclass
, 0, REG_KEY_READ
, NULL
,
832 &key_hnd
, &action
, NULL
);
833 if (!NT_STATUS_IS_OK(status
)) {
834 d_fprintf(stderr
, _("createkey returned %s\n"),
836 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
841 case REG_ACTION_NONE
:
842 d_printf(_("createkey did nothing -- huh?\n"));
844 case REG_CREATED_NEW_KEY
:
845 d_printf(_("createkey created %s\n"), argv
[0]);
847 case REG_OPENED_EXISTING_KEY
:
848 d_printf(_("createkey opened existing %s\n"), argv
[0]);
852 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
853 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
858 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
861 if (argc
!= 1 || c
->display_usage
) {
862 d_fprintf(stderr
, "%s\n%s",
864 _("net rpc registry createkey <key>\n"));
868 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
869 rpc_registry_createkey_internal
, argc
, argv
);
872 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
873 const struct dom_sid
*domain_sid
,
874 const char *domain_name
,
875 struct cli_state
*cli
,
876 struct rpc_pipe_client
*pipe_hnd
,
882 struct policy_handle hive_hnd
;
883 struct winreg_String key
;
888 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
889 return NT_STATUS_INVALID_PARAMETER
;
892 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
893 SEC_FLAG_MAXIMUM_ALLOWED
,
895 if (!(NT_STATUS_IS_OK(status
))) {
899 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
900 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
902 if (!NT_STATUS_IS_OK(status
)) {
903 d_fprintf(stderr
, _("deletekey returned %s\n"),
910 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
912 if (argc
!= 1 || c
->display_usage
) {
913 d_fprintf(stderr
, "%s\n%s",
915 _("net rpc registry deletekey <key>\n"));
919 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
920 rpc_registry_deletekey_internal
, argc
, argv
);
923 /********************************************************************
924 ********************************************************************/
926 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
927 const struct dom_sid
*domain_sid
,
928 const char *domain_name
,
929 struct cli_state
*cli
,
930 struct rpc_pipe_client
*pipe_hnd
,
935 struct policy_handle pol_hive
, pol_key
;
937 uint32 num_subkeys
= 0;
938 uint32 num_values
= 0;
939 char **names
= NULL
, **classes
= NULL
;
940 NTTIME
**modtimes
= NULL
;
942 struct registry_value
**values
= NULL
;
944 if (argc
!= 1 || c
->display_usage
) {
947 _("net rpc registry enumerate <path>\n"));
948 d_printf("%s net rpc registry enumerate "
949 "'HKLM\\Software\\Samba'\n", _("Example:"));
950 return NT_STATUS_INVALID_PARAMETER
;
953 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
954 &pol_hive
, &pol_key
);
955 if (!NT_STATUS_IS_OK(status
)) {
956 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
961 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
962 &names
, &classes
, &modtimes
);
963 if (!NT_STATUS_IS_OK(status
)) {
964 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
969 for (i
=0; i
<num_subkeys
; i
++) {
970 print_registry_key(names
[i
], modtimes
[i
]);
973 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
975 if (!NT_STATUS_IS_OK(status
)) {
976 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
981 for (i
=0; i
<num_values
; i
++) {
982 print_registry_value_with_name(names
[i
], values
[i
]);
985 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
986 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
991 /********************************************************************
992 ********************************************************************/
994 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
997 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
998 rpc_registry_enumerate_internal
, argc
, argv
);
1001 /********************************************************************
1002 ********************************************************************/
1004 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
1005 const struct dom_sid
*domain_sid
,
1006 const char *domain_name
,
1007 struct cli_state
*cli
,
1008 struct rpc_pipe_client
*pipe_hnd
,
1009 TALLOC_CTX
*mem_ctx
,
1013 WERROR result
= WERR_GENERAL_FAILURE
;
1014 struct policy_handle pol_hive
, pol_key
;
1015 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1016 struct winreg_String filename
;
1018 if (argc
!= 2 || c
->display_usage
) {
1021 _("net rpc registry backup <path> <file> \n"));
1022 return NT_STATUS_INVALID_PARAMETER
;
1025 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
1026 &pol_hive
, &pol_key
);
1027 if (!NT_STATUS_IS_OK(status
)) {
1028 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1033 filename
.name
= argv
[1];
1034 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
1035 if ( !W_ERROR_IS_OK(result
) ) {
1036 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
1037 cli
->desthost
, argv
[1]);
1042 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1043 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1048 /********************************************************************
1049 ********************************************************************/
1051 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
1053 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1054 rpc_registry_save_internal
, argc
, argv
);
1058 /********************************************************************
1059 ********************************************************************/
1061 static void dump_values( REGF_NK_REC
*nk
)
1064 const char *data_str
= NULL
;
1065 uint32 data_size
, data
;
1071 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1072 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
1073 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
1075 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
1076 switch ( nk
->values
[i
].type
) {
1078 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
1079 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
1083 d_printf( "%s", data_str
);
1087 for ( j
=0; j
<data_size
; j
++ ) {
1088 d_printf( "%c", nk
->values
[i
].data
[j
] );
1092 data
= IVAL( nk
->values
[i
].data
, 0 );
1093 d_printf("0x%x", data
);
1096 for ( j
=0; j
<data_size
; j
++ ) {
1097 d_printf( "%x", nk
->values
[i
].data
[j
] );
1101 d_printf(_("unknown"));
1110 /********************************************************************
1111 ********************************************************************/
1113 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
1117 /* depth first dump of the registry tree */
1119 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1121 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1124 d_printf("[%s]\n", regpath
);
1127 dump_registry_tree( file
, key
, regpath
);
1134 /********************************************************************
1135 ********************************************************************/
1137 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1138 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1139 const char *parentpath
)
1141 REGF_NK_REC
*key
, *subkey
;
1142 struct regval_ctr
*values
= NULL
;
1143 struct regsubkey_ctr
*subkeys
= NULL
;
1148 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1149 if (!W_ERROR_IS_OK(werr
)) {
1150 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1151 "%s\n", win_errstr(werr
)));
1155 werr
= regval_ctr_init(subkeys
, &values
);
1156 if (!W_ERROR_IS_OK(werr
)) {
1157 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1158 TALLOC_FREE(subkeys
);
1162 /* copy values into the struct regval_ctr */
1164 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1165 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1166 nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1169 /* copy subkeys into the struct regsubkey_ctr */
1171 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1172 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1175 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1177 /* write each one of the subkeys out */
1179 path
= talloc_asprintf(subkeys
,
1185 TALLOC_FREE(subkeys
);
1189 nk
->subkey_index
= 0;
1190 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1191 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1194 d_printf("[%s]\n", path
);
1195 TALLOC_FREE(subkeys
);
1200 /********************************************************************
1201 ********************************************************************/
1203 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1205 REGF_FILE
*registry
;
1208 if (argc
!= 1 || c
->display_usage
) {
1211 _("net rpc registry dump <file> \n"));
1215 d_printf(_("Opening %s...."), argv
[0]);
1216 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1217 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1220 d_printf(_("ok\n"));
1222 /* get the root of the registry file */
1224 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1225 d_fprintf(stderr
, _("Could not get rootkey\n"));
1226 regfio_close( registry
);
1229 d_printf("[%s]\n", nk
->keyname
);
1233 dump_registry_tree( registry
, nk
, nk
->keyname
);
1236 talloc_report_full( registry
->mem_ctx
, stderr
);
1238 d_printf(_("Closing registry..."));
1239 regfio_close( registry
);
1240 d_printf(_("ok\n"));
1245 /********************************************************************
1246 ********************************************************************/
1248 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1250 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1254 if (argc
!= 2 || c
->display_usage
) {
1257 _("net rpc registry copy <srcfile> <newfile>\n"));
1261 d_printf(_("Opening %s...."), argv
[0]);
1262 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1263 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1266 d_printf(_("ok\n"));
1268 d_printf(_("Opening %s...."), argv
[1]);
1269 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1270 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1273 d_printf(_("ok\n"));
1275 /* get the root of the registry file */
1277 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1278 d_fprintf(stderr
, _("Could not get rootkey\n"));
1281 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1283 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1289 d_printf(_("Closing %s..."), argv
[1]);
1291 regfio_close( outfile
);
1293 d_printf(_("ok\n"));
1295 d_printf(_("Closing %s..."), argv
[0]);
1297 regfio_close( infile
);
1299 d_printf(_("ok\n"));
1304 /********************************************************************
1305 ********************************************************************/
1307 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1308 const struct dom_sid
*domain_sid
,
1309 const char *domain_name
,
1310 struct cli_state
*cli
,
1311 struct rpc_pipe_client
*pipe_hnd
,
1312 TALLOC_CTX
*mem_ctx
,
1316 struct policy_handle pol_hive
, pol_key
;
1318 enum ndr_err_code ndr_err
;
1319 struct KeySecurityData
*sd
= NULL
;
1322 struct security_descriptor sec_desc
;
1323 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
|
1324 SEC_FLAG_SYSTEM_SECURITY
;
1326 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1329 _("net rpc registry getsd <path> <secinfo>\n"));
1330 d_printf("%s net rpc registry getsd "
1331 "'HKLM\\Software\\Samba'\n", _("Example:"));
1332 return NT_STATUS_INVALID_PARAMETER
;
1335 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1337 &pol_hive
, &pol_key
);
1338 if (!NT_STATUS_IS_OK(status
)) {
1339 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1344 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1346 status
= NT_STATUS_NO_MEMORY
;
1353 sscanf(argv
[1], "%x", &sec_info
);
1355 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1358 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1359 if (!NT_STATUS_IS_OK(status
)) {
1360 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1365 blob
.data
= sd
->data
;
1366 blob
.length
= sd
->size
;
1368 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1369 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1370 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1371 status
= ndr_map_error2ntstatus(ndr_err
);
1374 status
= NT_STATUS_OK
;
1376 display_sec_desc(&sec_desc
);
1379 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1380 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1386 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1388 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1389 rpc_registry_getsd_internal
, argc
, argv
);
1392 /********************************************************************
1393 ********************************************************************/
1395 * @defgroup net_rpc_registry net rpc registry
1399 * @defgroup net_rpc_registry_export Export
1400 * @ingroup net_rpc_registry
1404 static NTSTATUS
registry_export(struct rpc_pipe_client
* pipe_hnd
,
1406 struct policy_handle
* key_hnd
,
1407 struct reg_format
* f
,
1408 const char* parentfullname
,
1412 uint32 num_subkeys
= 0;
1413 uint32 num_values
= 0;
1414 char **names
= NULL
, **classes
= NULL
;
1415 NTTIME
**modtimes
= NULL
;
1416 struct regval_blob
**values
= NULL
;
1419 TALLOC_CTX
* mem_ctx
= talloc_new(ctx
);
1422 const char* fullname
= name
1423 ? talloc_asprintf(mem_ctx
, "%s\\%s", parentfullname
, name
)
1425 reg_format_key(f
, &fullname
, 1, false);
1427 status
= registry_enumvalues2(mem_ctx
, pipe_hnd
, key_hnd
, &num_values
,
1429 if (!NT_STATUS_IS_OK(status
)) {
1430 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
1435 for (i
=0; i
<num_values
; i
++) {
1436 reg_format_regval_blob(f
, names
[i
], values
[i
]);
1440 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, key_hnd
, &num_subkeys
,
1441 &names
, &classes
, &modtimes
);
1442 if (!NT_STATUS_IS_OK(status
)) {
1443 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
1448 for (i
=0; i
<num_subkeys
; i
++) {
1449 struct policy_handle subkey_hnd
;
1450 struct winreg_String key
;
1452 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1453 key
.name
= names
[i
];
1455 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, key_hnd
, key
,
1458 if (NT_STATUS_IS_OK(status
)) {
1459 status
= registry_export(pipe_hnd
, mem_ctx
, &subkey_hnd
,
1460 f
, fullname
, names
[i
]);
1461 if (!(NT_STATUS_IS_OK(status
)))
1463 _("export key failed: %s %s\n"),
1464 names
[i
], nt_errstr(status
));
1466 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
,
1470 _("rpccli_winreg_OpenKey failed: %s %s\n"),
1471 names
[i
], nt_errstr(status
));
1475 talloc_free(mem_ctx
);
1479 static NTSTATUS
rpc_registry_export_internal(struct net_context
*c
,
1480 const struct dom_sid
*domain_sid
,
1481 const char *domain_name
,
1482 struct cli_state
*cli
,
1483 struct rpc_pipe_client
*pipe_hnd
,
1484 TALLOC_CTX
*mem_ctx
,
1488 struct policy_handle pol_hive
, pol_key
;
1490 struct reg_format
* f
;
1492 if (argc
< 2 || argc
> 3 || c
->display_usage
) {
1495 _("net rpc registry export <path> <file> [opt]\n"));
1496 d_printf("%s net rpc registry export "
1497 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1498 return NT_STATUS_INVALID_PARAMETER
;
1501 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
1502 &pol_hive
, &pol_key
);
1503 if (!NT_STATUS_IS_OK(status
)) {
1504 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1509 f
= reg_format_file(mem_ctx
, argv
[1], (argc
> 2) ? argv
[2] : NULL
);
1511 d_fprintf(stderr
, _("open file failed: %s\n"), strerror(errno
));
1512 return map_nt_error_from_unix(errno
);
1515 status
= registry_export(pipe_hnd
, mem_ctx
, &pol_key
,
1517 if (!NT_STATUS_IS_OK(status
))
1520 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1521 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1525 /********************************************************************
1526 ********************************************************************/
1528 static int rpc_registry_export(struct net_context
*c
, int argc
,
1531 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1532 rpc_registry_export_internal
, argc
, argv
);
1538 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1540 struct functable func
[] = {
1543 rpc_registry_enumerate
,
1545 N_("Enumerate registry keys and values"),
1546 N_("net rpc registry enumerate\n"
1547 " Enumerate registry keys and values")
1551 rpc_registry_createkey
,
1553 N_("Create a new registry key"),
1554 N_("net rpc registry createkey\n"
1555 " Create a new registry key")
1559 rpc_registry_deletekey
,
1561 N_("Delete a registry key"),
1562 N_("net rpc registry deletekey\n"
1563 " Delete a registry key")
1567 rpc_registry_getvalue
,
1569 N_("Print a registry value"),
1570 N_("net rpc registry getvalue\n"
1571 " Print a registry value")
1575 rpc_registry_getvalueraw
,
1577 N_("Print a registry value"),
1578 N_("net rpc registry getvalueraw\n"
1579 " Print a registry value (raw version)")
1583 rpc_registry_setvalue
,
1585 N_("Set a new registry value"),
1586 N_("net rpc registry setvalue\n"
1587 " Set a new registry value")
1591 rpc_registry_deletevalue
,
1593 N_("Delete a registry value"),
1594 N_("net rpc registry deletevalue\n"
1595 " Delete a registry value")
1601 N_("Save a registry file"),
1602 N_("net rpc registry save\n"
1603 " Save a registry file")
1609 N_("Dump a registry file"),
1610 N_("net rpc registry dump\n"
1611 " Dump a registry file")
1617 N_("Copy a registry file"),
1618 N_("net rpc registry copy\n"
1619 " Copy a registry file")
1625 N_("Get security descriptor"),
1626 N_("net rpc registry getsd\n"
1627 " Get security descriptior")
1631 rpc_registry_export
,
1633 N_("net registry export\n"
1634 " Export .reg file")
1636 {NULL
, NULL
, 0, NULL
, NULL
}
1638 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);