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 "utils/net.h"
22 #include "utils/net_registry_util.h"
24 #include "reg_objects.h"
26 /*******************************************************************
27 connect to a registry hive root (open a registry policy)
28 *******************************************************************/
30 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
31 uint32_t reg_type
, uint32_t access_mask
,
32 struct policy_handle
*reg_hnd
)
34 ZERO_STRUCTP(reg_hnd
);
38 case HKEY_CLASSES_ROOT
:
39 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
40 access_mask
, reg_hnd
, NULL
);
42 case HKEY_LOCAL_MACHINE
:
43 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
44 access_mask
, reg_hnd
, NULL
);
47 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
48 access_mask
, reg_hnd
, NULL
);
50 case HKEY_CURRENT_USER
:
51 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
52 access_mask
, reg_hnd
, NULL
);
54 case HKEY_PERFORMANCE_DATA
:
55 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
56 access_mask
, reg_hnd
, NULL
);
59 /* fall through to end of function */
63 return NT_STATUS_INVALID_PARAMETER
;
66 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
67 uint32
*reg_type
, const char **key_name
)
70 char *hivename
= NULL
;
71 char *tmp_keyname
= NULL
;
73 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
75 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
76 if (!W_ERROR_IS_OK(werr
)) {
80 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
81 if (*key_name
== NULL
) {
85 if (strequal(hivename
, "HKLM") ||
86 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
88 (*reg_type
) = HKEY_LOCAL_MACHINE
;
89 } else if (strequal(hivename
, "HKCR") ||
90 strequal(hivename
, "HKEY_CLASSES_ROOT"))
92 (*reg_type
) = HKEY_CLASSES_ROOT
;
93 } else if (strequal(hivename
, "HKU") ||
94 strequal(hivename
, "HKEY_USERS"))
96 (*reg_type
) = HKEY_USERS
;
97 } else if (strequal(hivename
, "HKCU") ||
98 strequal(hivename
, "HKEY_CURRENT_USER"))
100 (*reg_type
) = HKEY_CURRENT_USER
;
101 } else if (strequal(hivename
, "HKPD") ||
102 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
104 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
106 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
114 TALLOC_FREE(tmp_ctx
);
118 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
119 struct rpc_pipe_client
*pipe_hnd
,
120 const char *name
, uint32 access_mask
,
121 struct policy_handle
*hive_hnd
,
122 struct policy_handle
*key_hnd
)
126 struct winreg_String key
;
130 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
131 return NT_STATUS_INVALID_PARAMETER
;
134 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
136 if (!(NT_STATUS_IS_OK(status
))) {
140 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
141 access_mask
, key_hnd
, NULL
);
142 if (!(NT_STATUS_IS_OK(status
))) {
143 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
150 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
151 struct rpc_pipe_client
*pipe_hnd
,
152 struct policy_handle
*key_hnd
,
153 uint32
*pnum_keys
, char ***pnames
,
154 char ***pclasses
, NTTIME
***pmodtimes
)
158 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
159 uint32 num_values
, max_valnamelen
, max_valbufsize
;
161 NTTIME last_changed_time
;
163 struct winreg_String classname
;
164 char **names
, **classes
;
167 if (!(mem_ctx
= talloc_new(ctx
))) {
168 return NT_STATUS_NO_MEMORY
;
171 ZERO_STRUCT(classname
);
172 status
= rpccli_winreg_QueryInfoKey(
173 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
174 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
175 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
177 if (!NT_STATUS_IS_OK(status
)) {
181 if (num_subkeys
== 0) {
183 TALLOC_FREE(mem_ctx
);
187 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
188 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
189 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
191 status
= NT_STATUS_NO_MEMORY
;
195 for (i
=0; i
<num_subkeys
; i
++) {
197 struct winreg_StringBuf class_buf
;
198 struct winreg_StringBuf name_buf
;
204 class_buf
.size
= max_classlen
+2;
208 name_buf
.size
= max_subkeylen
+2;
210 ZERO_STRUCT(modtime
);
212 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
213 i
, &name_buf
, &class_buf
,
216 if (W_ERROR_EQUAL(werr
,
217 WERR_NO_MORE_ITEMS
) ) {
218 status
= NT_STATUS_OK
;
221 if (!NT_STATUS_IS_OK(status
)) {
227 if (class_buf
.name
&&
228 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
229 status
= NT_STATUS_NO_MEMORY
;
233 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
234 status
= NT_STATUS_NO_MEMORY
;
238 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
239 modtimes
, &modtime
, sizeof(modtime
))))) {
240 status
= NT_STATUS_NO_MEMORY
;
245 *pnum_keys
= num_subkeys
;
248 *pnames
= talloc_move(ctx
, &names
);
251 *pclasses
= talloc_move(ctx
, &classes
);
254 *pmodtimes
= talloc_move(ctx
, &modtimes
);
257 status
= NT_STATUS_OK
;
260 TALLOC_FREE(mem_ctx
);
264 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
265 struct rpc_pipe_client
*pipe_hnd
,
266 struct policy_handle
*key_hnd
,
267 uint32
*pnum_values
, char ***pvalnames
,
268 struct registry_value
***pvalues
)
272 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
273 uint32 num_values
, max_valnamelen
, max_valbufsize
;
275 NTTIME last_changed_time
;
277 struct winreg_String classname
;
278 struct registry_value
**values
;
281 if (!(mem_ctx
= talloc_new(ctx
))) {
282 return NT_STATUS_NO_MEMORY
;
285 ZERO_STRUCT(classname
);
286 status
= rpccli_winreg_QueryInfoKey(
287 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
288 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
289 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
291 if (!NT_STATUS_IS_OK(status
)) {
295 if (num_values
== 0) {
297 TALLOC_FREE(mem_ctx
);
301 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
302 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
304 status
= NT_STATUS_NO_MEMORY
;
308 for (i
=0; i
<num_values
; i
++) {
309 enum winreg_Type type
= REG_NONE
;
315 struct winreg_ValNameBuf name_buf
;
320 name_buf
.size
= max_valnamelen
+ 2;
322 data_size
= max_valbufsize
;
323 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
326 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
329 &value_length
, &err
);
331 if ( W_ERROR_EQUAL(err
,
332 WERR_NO_MORE_ITEMS
) ) {
333 status
= NT_STATUS_OK
;
337 if (!(NT_STATUS_IS_OK(status
))) {
341 if (name_buf
.name
== NULL
) {
342 status
= NT_STATUS_INVALID_PARAMETER
;
346 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
347 status
= NT_STATUS_NO_MEMORY
;
351 err
= registry_pull_value(values
, &values
[i
], type
, data
,
352 data_size
, value_length
);
353 if (!W_ERROR_IS_OK(err
)) {
354 status
= werror_to_ntstatus(err
);
359 *pnum_values
= num_values
;
362 *pvalnames
= talloc_move(ctx
, &names
);
365 *pvalues
= talloc_move(ctx
, &values
);
368 status
= NT_STATUS_OK
;
371 TALLOC_FREE(mem_ctx
);
375 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
376 struct rpc_pipe_client
*pipe_hnd
,
377 struct policy_handle
*key_hnd
,
379 struct KeySecurityData
*sd
)
381 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
386 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
387 struct rpc_pipe_client
*pipe_hnd
,
388 struct policy_handle
*key_hnd
,
390 const struct registry_value
*value
)
392 struct winreg_String name_string
;
397 err
= registry_push_value(mem_ctx
, value
, &blob
);
398 if (!W_ERROR_IS_OK(err
)) {
399 return werror_to_ntstatus(err
);
402 ZERO_STRUCT(name_string
);
404 name_string
.name
= name
;
405 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
406 name_string
, value
->type
,
407 blob
.data
, blob
.length
, NULL
);
408 TALLOC_FREE(blob
.data
);
412 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
413 const DOM_SID
*domain_sid
,
414 const char *domain_name
,
415 struct cli_state
*cli
,
416 struct rpc_pipe_client
*pipe_hnd
,
421 struct policy_handle hive_hnd
, key_hnd
;
423 struct registry_value value
;
425 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
426 SEC_FLAG_MAXIMUM_ALLOWED
,
427 &hive_hnd
, &key_hnd
);
428 if (!NT_STATUS_IS_OK(status
)) {
429 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
434 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
435 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
436 return NT_STATUS_NOT_IMPLEMENTED
;
439 if (strequal(argv
[2], "dword")) {
440 value
.type
= REG_DWORD
;
441 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
443 else if (strequal(argv
[2], "sz")) {
445 value
.v
.sz
.len
= strlen(argv
[3])+1;
446 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
449 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
450 status
= NT_STATUS_NOT_IMPLEMENTED
;
454 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
457 if (!NT_STATUS_IS_OK(status
)) {
458 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
463 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
464 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
469 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
472 if (argc
< 4 || c
->display_usage
) {
473 d_fprintf(stderr
, _("usage: net rpc registry setvalue <key> "
474 "<valuename> <type> [<val>]+\n"));
478 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
479 rpc_registry_setvalue_internal
, argc
, argv
);
482 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
483 const DOM_SID
*domain_sid
,
484 const char *domain_name
,
485 struct cli_state
*cli
,
486 struct rpc_pipe_client
*pipe_hnd
,
491 struct policy_handle hive_hnd
, key_hnd
;
493 struct winreg_String valuename
;
495 ZERO_STRUCT(valuename
);
497 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
498 SEC_FLAG_MAXIMUM_ALLOWED
,
499 &hive_hnd
, &key_hnd
);
500 if (!NT_STATUS_IS_OK(status
)) {
501 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
506 valuename
.name
= argv
[1];
508 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
511 if (!NT_STATUS_IS_OK(status
)) {
512 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
516 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
517 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
522 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
525 if (argc
!= 2 || c
->display_usage
) {
526 d_fprintf(stderr
, _("usage: net rpc registry deletevalue <key> "
531 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
532 rpc_registry_deletevalue_internal
, argc
, argv
);
535 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
536 const DOM_SID
*domain_sid
,
537 const char *domain_name
,
538 struct cli_state
*cli
,
539 struct rpc_pipe_client
*pipe_hnd
,
545 struct policy_handle hive_hnd
, key_hnd
;
548 struct winreg_String valuename
;
549 struct registry_value
*value
= NULL
;
550 enum winreg_Type type
= REG_NONE
;
551 uint8_t *data
= NULL
;
552 uint32_t data_size
= 0;
553 uint32_t value_length
= 0;
554 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
556 ZERO_STRUCT(valuename
);
558 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
559 SEC_FLAG_MAXIMUM_ALLOWED
,
560 &hive_hnd
, &key_hnd
);
561 if (!NT_STATUS_IS_OK(status
)) {
562 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
567 valuename
.name
= argv
[1];
570 * call QueryValue once with data == NULL to get the
571 * needed memory size to be allocated, then allocate
572 * data buffer and call again.
574 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
582 if (!NT_STATUS_IS_OK(status
)) {
583 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
588 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
591 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
599 if (!NT_STATUS_IS_OK(status
)) {
600 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
605 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
606 data_size
, value_length
);
607 if (!W_ERROR_IS_OK(werr
)) {
608 status
= werror_to_ntstatus(werr
);
612 print_registry_value(value
, raw
);
615 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
616 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
618 TALLOC_FREE(tmp_ctx
);
623 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
624 const DOM_SID
*domain_sid
,
625 const char *domain_name
,
626 struct cli_state
*cli
,
627 struct rpc_pipe_client
*pipe_hnd
,
632 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
633 cli
, pipe_hnd
, mem_ctx
, false,
637 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
640 if (argc
!= 2 || c
->display_usage
) {
641 d_fprintf(stderr
, _("usage: net rpc registry getvalue <key> "
646 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
647 rpc_registry_getvalue_full
, argc
, argv
);
650 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
651 const DOM_SID
*domain_sid
,
652 const char *domain_name
,
653 struct cli_state
*cli
,
654 struct rpc_pipe_client
*pipe_hnd
,
659 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
660 cli
, pipe_hnd
, mem_ctx
, true,
664 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
667 if (argc
!= 2 || c
->display_usage
) {
668 d_fprintf(stderr
, _("usage: net rpc registry getvalue <key> "
673 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
674 rpc_registry_getvalue_raw
, argc
, argv
);
677 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
678 const DOM_SID
*domain_sid
,
679 const char *domain_name
,
680 struct cli_state
*cli
,
681 struct rpc_pipe_client
*pipe_hnd
,
687 struct policy_handle hive_hnd
, key_hnd
;
688 struct winreg_String key
, keyclass
;
689 enum winreg_CreateAction action
;
693 ZERO_STRUCT(keyclass
);
695 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
696 return NT_STATUS_INVALID_PARAMETER
;
699 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
700 SEC_FLAG_MAXIMUM_ALLOWED
,
702 if (!(NT_STATUS_IS_OK(status
))) {
706 action
= REG_ACTION_NONE
;
709 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
710 keyclass
, 0, REG_KEY_READ
, NULL
,
711 &key_hnd
, &action
, NULL
);
712 if (!NT_STATUS_IS_OK(status
)) {
713 d_fprintf(stderr
, _("createkey returned %s\n"),
715 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
720 case REG_ACTION_NONE
:
721 d_printf(_("createkey did nothing -- huh?\n"));
723 case REG_CREATED_NEW_KEY
:
724 d_printf(_("createkey created %s\n"), argv
[0]);
726 case REG_OPENED_EXISTING_KEY
:
727 d_printf(_("createkey opened existing %s\n"), argv
[0]);
731 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
732 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
737 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
740 if (argc
!= 1 || c
->display_usage
) {
742 _("usage: net rpc registry createkey <key>\n"));
746 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
747 rpc_registry_createkey_internal
, argc
, argv
);
750 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
751 const DOM_SID
*domain_sid
,
752 const char *domain_name
,
753 struct cli_state
*cli
,
754 struct rpc_pipe_client
*pipe_hnd
,
760 struct policy_handle hive_hnd
;
761 struct winreg_String key
;
766 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
767 return NT_STATUS_INVALID_PARAMETER
;
770 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
771 SEC_FLAG_MAXIMUM_ALLOWED
,
773 if (!(NT_STATUS_IS_OK(status
))) {
777 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
778 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
780 if (!NT_STATUS_IS_OK(status
)) {
781 d_fprintf(stderr
, _("deletekey returned %s\n"),
788 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
790 if (argc
!= 1 || c
->display_usage
) {
792 _("usage: net rpc registry deletekey <key>\n"));
796 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
797 rpc_registry_deletekey_internal
, argc
, argv
);
800 /********************************************************************
801 ********************************************************************/
803 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
804 const DOM_SID
*domain_sid
,
805 const char *domain_name
,
806 struct cli_state
*cli
,
807 struct rpc_pipe_client
*pipe_hnd
,
812 struct policy_handle pol_hive
, pol_key
;
814 uint32 num_subkeys
= 0;
815 uint32 num_values
= 0;
816 char **names
= NULL
, **classes
= NULL
;
817 NTTIME
**modtimes
= NULL
;
819 struct registry_value
**values
= NULL
;
821 if (argc
!= 1 || c
->display_usage
) {
822 d_printf(_("Usage: net rpc registry enumerate <path>\n"));
823 d_printf(_("Example: net rpc registry enumerate "
824 "'HKLM\\Software\\Samba'\n"));
825 return NT_STATUS_INVALID_PARAMETER
;
828 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
829 &pol_hive
, &pol_key
);
830 if (!NT_STATUS_IS_OK(status
)) {
831 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
836 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
837 &names
, &classes
, &modtimes
);
838 if (!NT_STATUS_IS_OK(status
)) {
839 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
844 for (i
=0; i
<num_subkeys
; i
++) {
845 print_registry_key(names
[i
], modtimes
[i
]);
848 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
850 if (!NT_STATUS_IS_OK(status
)) {
851 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
856 for (i
=0; i
<num_values
; i
++) {
857 print_registry_value_with_name(names
[i
], values
[i
]);
860 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
861 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
866 /********************************************************************
867 ********************************************************************/
869 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
872 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
873 rpc_registry_enumerate_internal
, argc
, argv
);
876 /********************************************************************
877 ********************************************************************/
879 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
880 const DOM_SID
*domain_sid
,
881 const char *domain_name
,
882 struct cli_state
*cli
,
883 struct rpc_pipe_client
*pipe_hnd
,
888 WERROR result
= WERR_GENERAL_FAILURE
;
889 struct policy_handle pol_hive
, pol_key
;
890 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
891 struct winreg_String filename
;
893 if (argc
!= 2 || c
->display_usage
) {
894 d_printf(_("Usage: net rpc registry backup <path> "
896 return NT_STATUS_INVALID_PARAMETER
;
899 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
900 &pol_hive
, &pol_key
);
901 if (!NT_STATUS_IS_OK(status
)) {
902 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
907 filename
.name
= argv
[1];
908 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
909 if ( !W_ERROR_IS_OK(result
) ) {
910 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
911 cli
->desthost
, argv
[1]);
916 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
917 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
922 /********************************************************************
923 ********************************************************************/
925 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
927 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
928 rpc_registry_save_internal
, argc
, argv
);
932 /********************************************************************
933 ********************************************************************/
935 static void dump_values( REGF_NK_REC
*nk
)
938 const char *data_str
= NULL
;
939 uint32 data_size
, data
;
945 for ( i
=0; i
<nk
->num_values
; i
++ ) {
946 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
947 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
949 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
950 switch ( nk
->values
[i
].type
) {
952 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
953 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
957 d_printf( "%s", data_str
);
961 for ( j
=0; j
<data_size
; j
++ ) {
962 d_printf( "%c", nk
->values
[i
].data
[j
] );
966 data
= IVAL( nk
->values
[i
].data
, 0 );
967 d_printf("0x%x", data
);
970 for ( j
=0; j
<data_size
; j
++ ) {
971 d_printf( "%x", nk
->values
[i
].data
[j
] );
975 d_printf(_("unknown"));
984 /********************************************************************
985 ********************************************************************/
987 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
991 /* depth first dump of the registry tree */
993 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
995 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
998 d_printf("[%s]\n", regpath
);
1001 dump_registry_tree( file
, key
, regpath
);
1008 /********************************************************************
1009 ********************************************************************/
1011 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1012 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1013 const char *parentpath
)
1015 REGF_NK_REC
*key
, *subkey
;
1016 struct regval_ctr
*values
= NULL
;
1017 struct regsubkey_ctr
*subkeys
= NULL
;
1022 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1023 if (!W_ERROR_IS_OK(werr
)) {
1024 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1025 "%s\n", win_errstr(werr
)));
1029 if ( !(values
= TALLOC_ZERO_P( subkeys
, struct regval_ctr
)) ) {
1030 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1031 TALLOC_FREE(subkeys
);
1035 /* copy values into the struct regval_ctr */
1037 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1038 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1039 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1042 /* copy subkeys into the struct regsubkey_ctr */
1044 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1045 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1048 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1050 /* write each one of the subkeys out */
1052 path
= talloc_asprintf(subkeys
,
1058 TALLOC_FREE(subkeys
);
1062 nk
->subkey_index
= 0;
1063 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1064 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1067 d_printf("[%s]\n", path
);
1068 TALLOC_FREE(subkeys
);
1073 /********************************************************************
1074 ********************************************************************/
1076 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1078 REGF_FILE
*registry
;
1081 if (argc
!= 1 || c
->display_usage
) {
1082 d_printf(_("Usage: net rpc registry dump <file> \n"));
1086 d_printf(_("Opening %s...."), argv
[0]);
1087 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1088 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1091 d_printf(_("ok\n"));
1093 /* get the root of the registry file */
1095 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1096 d_fprintf(stderr
, _("Could not get rootkey\n"));
1097 regfio_close( registry
);
1100 d_printf("[%s]\n", nk
->keyname
);
1104 dump_registry_tree( registry
, nk
, nk
->keyname
);
1107 talloc_report_full( registry
->mem_ctx
, stderr
);
1109 d_printf(_("Closing registry..."));
1110 regfio_close( registry
);
1111 d_printf(_("ok\n"));
1116 /********************************************************************
1117 ********************************************************************/
1119 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1121 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1125 if (argc
!= 2 || c
->display_usage
) {
1126 d_printf(_("Usage: net rpc registry copy <srcfile> "
1131 d_printf(_("Opening %s...."), argv
[0]);
1132 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1133 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1136 d_printf(_("ok\n"));
1138 d_printf(_("Opening %s...."), argv
[1]);
1139 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1140 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1143 d_printf(_("ok\n"));
1145 /* get the root of the registry file */
1147 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1148 d_fprintf(stderr
, _("Could not get rootkey\n"));
1151 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1153 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1159 d_printf(_("Closing %s..."), argv
[1]);
1161 regfio_close( outfile
);
1163 d_printf(_("ok\n"));
1165 d_printf(_("Closing %s..."), argv
[0]);
1167 regfio_close( infile
);
1169 d_printf(_("ok\n"));
1174 /********************************************************************
1175 ********************************************************************/
1177 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1178 const DOM_SID
*domain_sid
,
1179 const char *domain_name
,
1180 struct cli_state
*cli
,
1181 struct rpc_pipe_client
*pipe_hnd
,
1182 TALLOC_CTX
*mem_ctx
,
1186 struct policy_handle pol_hive
, pol_key
;
1188 enum ndr_err_code ndr_err
;
1189 struct KeySecurityData
*sd
= NULL
;
1192 struct security_descriptor sec_desc
;
1193 uint32_t access_mask
= REG_KEY_READ
|
1194 SEC_FLAG_MAXIMUM_ALLOWED
|
1195 SEC_FLAG_SYSTEM_SECURITY
;
1197 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1198 d_printf(_("Usage: net rpc registry getsd <path> "
1200 d_printf(_("Example: net rpc registry getsd "
1201 "'HKLM\\Software\\Samba'\n"));
1202 return NT_STATUS_INVALID_PARAMETER
;
1205 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1207 &pol_hive
, &pol_key
);
1208 if (!NT_STATUS_IS_OK(status
)) {
1209 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1214 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1216 status
= NT_STATUS_NO_MEMORY
;
1223 sscanf(argv
[1], "%x", &sec_info
);
1225 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1228 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1229 if (!NT_STATUS_IS_OK(status
)) {
1230 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1235 blob
.data
= sd
->data
;
1236 blob
.length
= sd
->size
;
1238 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, NULL
, &sec_desc
,
1239 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1240 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1241 status
= ndr_map_error2ntstatus(ndr_err
);
1244 status
= NT_STATUS_OK
;
1246 display_sec_desc(&sec_desc
);
1249 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1250 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1256 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1258 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1259 rpc_registry_getsd_internal
, argc
, argv
);
1262 /********************************************************************
1263 ********************************************************************/
1265 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1267 struct functable func
[] = {
1270 rpc_registry_enumerate
,
1272 N_("Enumerate registry keys and values"),
1273 N_("net rpc registry enumerate\n"
1274 " Enumerate registry keys and values")
1278 rpc_registry_createkey
,
1280 N_("Create a new registry key"),
1281 N_("net rpc registry createkey\n"
1282 " Create a new registry key")
1286 rpc_registry_deletekey
,
1288 N_("Delete a registry key"),
1289 N_("net rpc registry deletekey\n"
1290 " Delete a registry key")
1294 rpc_registry_getvalue
,
1296 N_("Print a registry value"),
1297 N_("net rpc registry getvalue\n"
1298 " Print a registry value")
1302 rpc_registry_getvalueraw
,
1304 N_("Print a registry value"),
1305 N_("net rpc registry getvalueraw\n"
1306 " Print a registry value (raw version)")
1310 rpc_registry_setvalue
,
1312 N_("Set a new registry value"),
1313 N_("net rpc registry setvalue\n"
1314 " Set a new registry value")
1318 rpc_registry_deletevalue
,
1320 N_("Delete a registry value"),
1321 N_("net rpc registry deletevalue\n"
1322 " Delete a registry value")
1328 N_("Save a registry file"),
1329 N_("net rpc registry save\n"
1330 " Save a registry file")
1336 N_("Dump a registry file"),
1337 N_("net rpc registry dump\n"
1338 " Dump a registry file")
1344 N_("Copy a registry file"),
1345 N_("net rpc registry copy\n"
1346 " Copy a registry file")
1352 N_("Get security descriptor"),
1353 N_("net rpc registry getsd\n"
1354 " Get security descriptior")
1356 {NULL
, NULL
, 0, NULL
, NULL
}
1359 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);