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"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 /*******************************************************************
28 connect to a registry hive root (open a registry policy)
29 *******************************************************************/
31 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
32 uint32_t reg_type
, uint32_t access_mask
,
33 struct policy_handle
*reg_hnd
)
35 ZERO_STRUCTP(reg_hnd
);
39 case HKEY_CLASSES_ROOT
:
40 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
41 access_mask
, reg_hnd
, NULL
);
43 case HKEY_LOCAL_MACHINE
:
44 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
45 access_mask
, reg_hnd
, NULL
);
48 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
49 access_mask
, reg_hnd
, NULL
);
51 case HKEY_CURRENT_USER
:
52 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
53 access_mask
, reg_hnd
, NULL
);
55 case HKEY_PERFORMANCE_DATA
:
56 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
57 access_mask
, reg_hnd
, NULL
);
60 /* fall through to end of function */
64 return NT_STATUS_INVALID_PARAMETER
;
67 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
68 uint32
*reg_type
, const char **key_name
)
71 char *hivename
= NULL
;
72 char *tmp_keyname
= NULL
;
74 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
76 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
77 if (!W_ERROR_IS_OK(werr
)) {
81 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
82 if (*key_name
== NULL
) {
86 if (strequal(hivename
, "HKLM") ||
87 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
89 (*reg_type
) = HKEY_LOCAL_MACHINE
;
90 } else if (strequal(hivename
, "HKCR") ||
91 strequal(hivename
, "HKEY_CLASSES_ROOT"))
93 (*reg_type
) = HKEY_CLASSES_ROOT
;
94 } else if (strequal(hivename
, "HKU") ||
95 strequal(hivename
, "HKEY_USERS"))
97 (*reg_type
) = HKEY_USERS
;
98 } else if (strequal(hivename
, "HKCU") ||
99 strequal(hivename
, "HKEY_CURRENT_USER"))
101 (*reg_type
) = HKEY_CURRENT_USER
;
102 } else if (strequal(hivename
, "HKPD") ||
103 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
105 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
107 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
115 TALLOC_FREE(tmp_ctx
);
119 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
120 struct rpc_pipe_client
*pipe_hnd
,
121 const char *name
, uint32 access_mask
,
122 struct policy_handle
*hive_hnd
,
123 struct policy_handle
*key_hnd
)
127 struct winreg_String key
;
131 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
132 return NT_STATUS_INVALID_PARAMETER
;
135 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
137 if (!(NT_STATUS_IS_OK(status
))) {
141 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
142 access_mask
, key_hnd
, NULL
);
143 if (!(NT_STATUS_IS_OK(status
))) {
144 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
151 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
152 struct rpc_pipe_client
*pipe_hnd
,
153 struct policy_handle
*key_hnd
,
154 uint32
*pnum_keys
, char ***pnames
,
155 char ***pclasses
, NTTIME
***pmodtimes
)
159 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
160 uint32 num_values
, max_valnamelen
, max_valbufsize
;
162 NTTIME last_changed_time
;
164 struct winreg_String classname
;
165 char **names
, **classes
;
168 if (!(mem_ctx
= talloc_new(ctx
))) {
169 return NT_STATUS_NO_MEMORY
;
172 ZERO_STRUCT(classname
);
173 status
= rpccli_winreg_QueryInfoKey(
174 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
175 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
176 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
178 if (!NT_STATUS_IS_OK(status
)) {
182 if (num_subkeys
== 0) {
184 TALLOC_FREE(mem_ctx
);
188 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
189 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
190 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
192 status
= NT_STATUS_NO_MEMORY
;
196 for (i
=0; i
<num_subkeys
; i
++) {
198 struct winreg_StringBuf class_buf
;
199 struct winreg_StringBuf name_buf
;
205 class_buf
.size
= max_classlen
+2;
209 name_buf
.size
= max_subkeylen
+2;
211 ZERO_STRUCT(modtime
);
213 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
214 i
, &name_buf
, &class_buf
,
217 if (W_ERROR_EQUAL(werr
,
218 WERR_NO_MORE_ITEMS
) ) {
219 status
= NT_STATUS_OK
;
222 if (!NT_STATUS_IS_OK(status
)) {
228 if (class_buf
.name
&&
229 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
230 status
= NT_STATUS_NO_MEMORY
;
234 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
235 status
= NT_STATUS_NO_MEMORY
;
239 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
240 modtimes
, &modtime
, sizeof(modtime
))))) {
241 status
= NT_STATUS_NO_MEMORY
;
246 *pnum_keys
= num_subkeys
;
249 *pnames
= talloc_move(ctx
, &names
);
252 *pclasses
= talloc_move(ctx
, &classes
);
255 *pmodtimes
= talloc_move(ctx
, &modtimes
);
258 status
= NT_STATUS_OK
;
261 TALLOC_FREE(mem_ctx
);
265 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
266 struct rpc_pipe_client
*pipe_hnd
,
267 struct policy_handle
*key_hnd
,
268 uint32
*pnum_values
, char ***pvalnames
,
269 struct registry_value
***pvalues
)
273 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
274 uint32 num_values
, max_valnamelen
, max_valbufsize
;
276 NTTIME last_changed_time
;
278 struct winreg_String classname
;
279 struct registry_value
**values
;
282 if (!(mem_ctx
= talloc_new(ctx
))) {
283 return NT_STATUS_NO_MEMORY
;
286 ZERO_STRUCT(classname
);
287 status
= rpccli_winreg_QueryInfoKey(
288 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
289 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
290 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
292 if (!NT_STATUS_IS_OK(status
)) {
296 if (num_values
== 0) {
298 TALLOC_FREE(mem_ctx
);
302 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
303 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
305 status
= NT_STATUS_NO_MEMORY
;
309 for (i
=0; i
<num_values
; i
++) {
310 enum winreg_Type type
= REG_NONE
;
316 struct winreg_ValNameBuf name_buf
;
321 name_buf
.size
= max_valnamelen
+ 2;
323 data_size
= max_valbufsize
;
324 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
327 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
330 &value_length
, &err
);
332 if ( W_ERROR_EQUAL(err
,
333 WERR_NO_MORE_ITEMS
) ) {
334 status
= NT_STATUS_OK
;
338 if (!(NT_STATUS_IS_OK(status
))) {
342 if (name_buf
.name
== NULL
) {
343 status
= NT_STATUS_INVALID_PARAMETER
;
347 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
348 status
= NT_STATUS_NO_MEMORY
;
352 err
= registry_pull_value(values
, &values
[i
], type
, data
,
353 data_size
, value_length
);
354 if (!W_ERROR_IS_OK(err
)) {
355 status
= werror_to_ntstatus(err
);
360 *pnum_values
= num_values
;
363 *pvalnames
= talloc_move(ctx
, &names
);
366 *pvalues
= talloc_move(ctx
, &values
);
369 status
= NT_STATUS_OK
;
372 TALLOC_FREE(mem_ctx
);
376 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
377 struct rpc_pipe_client
*pipe_hnd
,
378 struct policy_handle
*key_hnd
,
380 struct KeySecurityData
*sd
)
382 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
387 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
388 struct rpc_pipe_client
*pipe_hnd
,
389 struct policy_handle
*key_hnd
,
391 const struct registry_value
*value
)
393 struct winreg_String name_string
;
398 err
= registry_push_value(mem_ctx
, value
, &blob
);
399 if (!W_ERROR_IS_OK(err
)) {
400 return werror_to_ntstatus(err
);
403 ZERO_STRUCT(name_string
);
405 name_string
.name
= name
;
406 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
407 name_string
, value
->type
,
408 blob
.data
, blob
.length
, NULL
);
409 TALLOC_FREE(blob
.data
);
413 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
414 const DOM_SID
*domain_sid
,
415 const char *domain_name
,
416 struct cli_state
*cli
,
417 struct rpc_pipe_client
*pipe_hnd
,
422 struct policy_handle hive_hnd
, key_hnd
;
424 struct registry_value value
;
426 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
427 SEC_FLAG_MAXIMUM_ALLOWED
,
428 &hive_hnd
, &key_hnd
);
429 if (!NT_STATUS_IS_OK(status
)) {
430 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
435 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
436 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
437 return NT_STATUS_NOT_IMPLEMENTED
;
440 if (strequal(argv
[2], "dword")) {
441 value
.type
= REG_DWORD
;
442 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
444 else if (strequal(argv
[2], "sz")) {
446 value
.v
.sz
.len
= strlen(argv
[3])+1;
447 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
450 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
451 status
= NT_STATUS_NOT_IMPLEMENTED
;
455 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
458 if (!NT_STATUS_IS_OK(status
)) {
459 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
464 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
465 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
470 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
473 if (argc
< 4 || c
->display_usage
) {
474 d_fprintf(stderr
, "%s\n%s",
476 _("net rpc registry setvalue <key> <valuename> "
477 "<type> [<val>]+\n"));
481 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
482 rpc_registry_setvalue_internal
, argc
, argv
);
485 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
486 const DOM_SID
*domain_sid
,
487 const char *domain_name
,
488 struct cli_state
*cli
,
489 struct rpc_pipe_client
*pipe_hnd
,
494 struct policy_handle hive_hnd
, key_hnd
;
496 struct winreg_String valuename
;
498 ZERO_STRUCT(valuename
);
500 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
501 SEC_FLAG_MAXIMUM_ALLOWED
,
502 &hive_hnd
, &key_hnd
);
503 if (!NT_STATUS_IS_OK(status
)) {
504 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
509 valuename
.name
= argv
[1];
511 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
514 if (!NT_STATUS_IS_OK(status
)) {
515 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
519 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
520 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
525 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
528 if (argc
!= 2 || c
->display_usage
) {
529 d_fprintf(stderr
, "%s\n%s",
531 _("net rpc registry deletevalue <key> <valuename>\n"));
535 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
536 rpc_registry_deletevalue_internal
, argc
, argv
);
539 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
540 const DOM_SID
*domain_sid
,
541 const char *domain_name
,
542 struct cli_state
*cli
,
543 struct rpc_pipe_client
*pipe_hnd
,
549 struct policy_handle hive_hnd
, key_hnd
;
552 struct winreg_String valuename
;
553 struct registry_value
*value
= NULL
;
554 enum winreg_Type type
= REG_NONE
;
555 uint8_t *data
= NULL
;
556 uint32_t data_size
= 0;
557 uint32_t value_length
= 0;
558 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
560 ZERO_STRUCT(valuename
);
562 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
563 SEC_FLAG_MAXIMUM_ALLOWED
,
564 &hive_hnd
, &key_hnd
);
565 if (!NT_STATUS_IS_OK(status
)) {
566 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
571 valuename
.name
= argv
[1];
574 * call QueryValue once with data == NULL to get the
575 * needed memory size to be allocated, then allocate
576 * data buffer and call again.
578 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
586 if (!NT_STATUS_IS_OK(status
)) {
587 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
592 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
595 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
603 if (!NT_STATUS_IS_OK(status
)) {
604 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
609 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
610 data_size
, value_length
);
611 if (!W_ERROR_IS_OK(werr
)) {
612 status
= werror_to_ntstatus(werr
);
616 print_registry_value(value
, raw
);
619 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
620 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
622 TALLOC_FREE(tmp_ctx
);
627 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
628 const DOM_SID
*domain_sid
,
629 const char *domain_name
,
630 struct cli_state
*cli
,
631 struct rpc_pipe_client
*pipe_hnd
,
636 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
637 cli
, pipe_hnd
, mem_ctx
, false,
641 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
644 if (argc
!= 2 || c
->display_usage
) {
645 d_fprintf(stderr
, "%s\n%s",
647 _("net rpc registry getvalue <key> <valuename>\n"));
651 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
652 rpc_registry_getvalue_full
, argc
, argv
);
655 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
656 const DOM_SID
*domain_sid
,
657 const char *domain_name
,
658 struct cli_state
*cli
,
659 struct rpc_pipe_client
*pipe_hnd
,
664 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
665 cli
, pipe_hnd
, mem_ctx
, true,
669 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
672 if (argc
!= 2 || c
->display_usage
) {
673 d_fprintf(stderr
, "%s\n%s",
675 _("net rpc registry getvalue <key> <valuename>\n"));
679 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
680 rpc_registry_getvalue_raw
, argc
, argv
);
683 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
684 const DOM_SID
*domain_sid
,
685 const char *domain_name
,
686 struct cli_state
*cli
,
687 struct rpc_pipe_client
*pipe_hnd
,
693 struct policy_handle hive_hnd
, key_hnd
;
694 struct winreg_String key
, keyclass
;
695 enum winreg_CreateAction action
;
699 ZERO_STRUCT(keyclass
);
701 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
702 return NT_STATUS_INVALID_PARAMETER
;
705 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
706 SEC_FLAG_MAXIMUM_ALLOWED
,
708 if (!(NT_STATUS_IS_OK(status
))) {
712 action
= REG_ACTION_NONE
;
715 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
716 keyclass
, 0, REG_KEY_READ
, NULL
,
717 &key_hnd
, &action
, NULL
);
718 if (!NT_STATUS_IS_OK(status
)) {
719 d_fprintf(stderr
, _("createkey returned %s\n"),
721 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
726 case REG_ACTION_NONE
:
727 d_printf(_("createkey did nothing -- huh?\n"));
729 case REG_CREATED_NEW_KEY
:
730 d_printf(_("createkey created %s\n"), argv
[0]);
732 case REG_OPENED_EXISTING_KEY
:
733 d_printf(_("createkey opened existing %s\n"), argv
[0]);
737 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
738 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
743 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
746 if (argc
!= 1 || c
->display_usage
) {
747 d_fprintf(stderr
, "%s\n%s",
749 _("net rpc registry createkey <key>\n"));
753 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
754 rpc_registry_createkey_internal
, argc
, argv
);
757 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
758 const DOM_SID
*domain_sid
,
759 const char *domain_name
,
760 struct cli_state
*cli
,
761 struct rpc_pipe_client
*pipe_hnd
,
767 struct policy_handle hive_hnd
;
768 struct winreg_String key
;
773 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
774 return NT_STATUS_INVALID_PARAMETER
;
777 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
778 SEC_FLAG_MAXIMUM_ALLOWED
,
780 if (!(NT_STATUS_IS_OK(status
))) {
784 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
785 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
787 if (!NT_STATUS_IS_OK(status
)) {
788 d_fprintf(stderr
, _("deletekey returned %s\n"),
795 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
797 if (argc
!= 1 || c
->display_usage
) {
798 d_fprintf(stderr
, "%s\n%s",
800 _("net rpc registry deletekey <key>\n"));
804 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
805 rpc_registry_deletekey_internal
, argc
, argv
);
808 /********************************************************************
809 ********************************************************************/
811 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
812 const DOM_SID
*domain_sid
,
813 const char *domain_name
,
814 struct cli_state
*cli
,
815 struct rpc_pipe_client
*pipe_hnd
,
820 struct policy_handle pol_hive
, pol_key
;
822 uint32 num_subkeys
= 0;
823 uint32 num_values
= 0;
824 char **names
= NULL
, **classes
= NULL
;
825 NTTIME
**modtimes
= NULL
;
827 struct registry_value
**values
= NULL
;
829 if (argc
!= 1 || c
->display_usage
) {
832 _("net rpc registry enumerate <path>\n"));
833 d_printf("%s net rpc registry enumerate "
834 "'HKLM\\Software\\Samba'\n", _("Example:"));
835 return NT_STATUS_INVALID_PARAMETER
;
838 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
839 &pol_hive
, &pol_key
);
840 if (!NT_STATUS_IS_OK(status
)) {
841 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
846 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
847 &names
, &classes
, &modtimes
);
848 if (!NT_STATUS_IS_OK(status
)) {
849 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
854 for (i
=0; i
<num_subkeys
; i
++) {
855 print_registry_key(names
[i
], modtimes
[i
]);
858 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
860 if (!NT_STATUS_IS_OK(status
)) {
861 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
866 for (i
=0; i
<num_values
; i
++) {
867 print_registry_value_with_name(names
[i
], values
[i
]);
870 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
871 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
876 /********************************************************************
877 ********************************************************************/
879 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
882 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
883 rpc_registry_enumerate_internal
, argc
, argv
);
886 /********************************************************************
887 ********************************************************************/
889 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
890 const DOM_SID
*domain_sid
,
891 const char *domain_name
,
892 struct cli_state
*cli
,
893 struct rpc_pipe_client
*pipe_hnd
,
898 WERROR result
= WERR_GENERAL_FAILURE
;
899 struct policy_handle pol_hive
, pol_key
;
900 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
901 struct winreg_String filename
;
903 if (argc
!= 2 || c
->display_usage
) {
906 _("net rpc registry backup <path> <file> \n"));
907 return NT_STATUS_INVALID_PARAMETER
;
910 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
911 &pol_hive
, &pol_key
);
912 if (!NT_STATUS_IS_OK(status
)) {
913 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
918 filename
.name
= argv
[1];
919 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
920 if ( !W_ERROR_IS_OK(result
) ) {
921 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
922 cli
->desthost
, argv
[1]);
927 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
928 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
933 /********************************************************************
934 ********************************************************************/
936 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
938 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
939 rpc_registry_save_internal
, argc
, argv
);
943 /********************************************************************
944 ********************************************************************/
946 static void dump_values( REGF_NK_REC
*nk
)
949 const char *data_str
= NULL
;
950 uint32 data_size
, data
;
956 for ( i
=0; i
<nk
->num_values
; i
++ ) {
957 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
958 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
960 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
961 switch ( nk
->values
[i
].type
) {
963 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
964 pull_reg_sz(talloc_tos(), NULL
, &blob
, &data_str
);
968 d_printf( "%s", data_str
);
972 for ( j
=0; j
<data_size
; j
++ ) {
973 d_printf( "%c", nk
->values
[i
].data
[j
] );
977 data
= IVAL( nk
->values
[i
].data
, 0 );
978 d_printf("0x%x", data
);
981 for ( j
=0; j
<data_size
; j
++ ) {
982 d_printf( "%x", nk
->values
[i
].data
[j
] );
986 d_printf(_("unknown"));
995 /********************************************************************
996 ********************************************************************/
998 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
1002 /* depth first dump of the registry tree */
1004 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1006 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1009 d_printf("[%s]\n", regpath
);
1012 dump_registry_tree( file
, key
, regpath
);
1019 /********************************************************************
1020 ********************************************************************/
1022 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1023 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1024 const char *parentpath
)
1026 REGF_NK_REC
*key
, *subkey
;
1027 struct regval_ctr
*values
= NULL
;
1028 struct regsubkey_ctr
*subkeys
= NULL
;
1033 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1034 if (!W_ERROR_IS_OK(werr
)) {
1035 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1036 "%s\n", win_errstr(werr
)));
1040 if ( !(values
= TALLOC_ZERO_P( subkeys
, struct regval_ctr
)) ) {
1041 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1042 TALLOC_FREE(subkeys
);
1046 /* copy values into the struct regval_ctr */
1048 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1049 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1050 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1053 /* copy subkeys into the struct regsubkey_ctr */
1055 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1056 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1059 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1061 /* write each one of the subkeys out */
1063 path
= talloc_asprintf(subkeys
,
1069 TALLOC_FREE(subkeys
);
1073 nk
->subkey_index
= 0;
1074 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1075 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1078 d_printf("[%s]\n", path
);
1079 TALLOC_FREE(subkeys
);
1084 /********************************************************************
1085 ********************************************************************/
1087 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1089 REGF_FILE
*registry
;
1092 if (argc
!= 1 || c
->display_usage
) {
1095 _("net rpc registry dump <file> \n"));
1099 d_printf(_("Opening %s...."), argv
[0]);
1100 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1101 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1104 d_printf(_("ok\n"));
1106 /* get the root of the registry file */
1108 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1109 d_fprintf(stderr
, _("Could not get rootkey\n"));
1110 regfio_close( registry
);
1113 d_printf("[%s]\n", nk
->keyname
);
1117 dump_registry_tree( registry
, nk
, nk
->keyname
);
1120 talloc_report_full( registry
->mem_ctx
, stderr
);
1122 d_printf(_("Closing registry..."));
1123 regfio_close( registry
);
1124 d_printf(_("ok\n"));
1129 /********************************************************************
1130 ********************************************************************/
1132 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1134 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1138 if (argc
!= 2 || c
->display_usage
) {
1141 _("net rpc registry copy <srcfile> <newfile>\n"));
1145 d_printf(_("Opening %s...."), argv
[0]);
1146 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1147 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1150 d_printf(_("ok\n"));
1152 d_printf(_("Opening %s...."), argv
[1]);
1153 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1154 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1157 d_printf(_("ok\n"));
1159 /* get the root of the registry file */
1161 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1162 d_fprintf(stderr
, _("Could not get rootkey\n"));
1165 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1167 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1173 d_printf(_("Closing %s..."), argv
[1]);
1175 regfio_close( outfile
);
1177 d_printf(_("ok\n"));
1179 d_printf(_("Closing %s..."), argv
[0]);
1181 regfio_close( infile
);
1183 d_printf(_("ok\n"));
1188 /********************************************************************
1189 ********************************************************************/
1191 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1192 const DOM_SID
*domain_sid
,
1193 const char *domain_name
,
1194 struct cli_state
*cli
,
1195 struct rpc_pipe_client
*pipe_hnd
,
1196 TALLOC_CTX
*mem_ctx
,
1200 struct policy_handle pol_hive
, pol_key
;
1202 enum ndr_err_code ndr_err
;
1203 struct KeySecurityData
*sd
= NULL
;
1206 struct security_descriptor sec_desc
;
1207 uint32_t access_mask
= REG_KEY_READ
|
1208 SEC_FLAG_MAXIMUM_ALLOWED
|
1209 SEC_FLAG_SYSTEM_SECURITY
;
1211 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1214 _("net rpc registry getsd <path> <secinfo>\n"));
1215 d_printf("%s net rpc registry getsd "
1216 "'HKLM\\Software\\Samba'\n", _("Example:"));
1217 return NT_STATUS_INVALID_PARAMETER
;
1220 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1222 &pol_hive
, &pol_key
);
1223 if (!NT_STATUS_IS_OK(status
)) {
1224 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1229 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1231 status
= NT_STATUS_NO_MEMORY
;
1238 sscanf(argv
[1], "%x", &sec_info
);
1240 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1243 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1244 if (!NT_STATUS_IS_OK(status
)) {
1245 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1250 blob
.data
= sd
->data
;
1251 blob
.length
= sd
->size
;
1253 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, NULL
, &sec_desc
,
1254 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1255 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1256 status
= ndr_map_error2ntstatus(ndr_err
);
1259 status
= NT_STATUS_OK
;
1261 display_sec_desc(&sec_desc
);
1264 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1265 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1271 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1273 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1274 rpc_registry_getsd_internal
, argc
, argv
);
1277 /********************************************************************
1278 ********************************************************************/
1280 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1282 struct functable func
[] = {
1285 rpc_registry_enumerate
,
1287 N_("Enumerate registry keys and values"),
1288 N_("net rpc registry enumerate\n"
1289 " Enumerate registry keys and values")
1293 rpc_registry_createkey
,
1295 N_("Create a new registry key"),
1296 N_("net rpc registry createkey\n"
1297 " Create a new registry key")
1301 rpc_registry_deletekey
,
1303 N_("Delete a registry key"),
1304 N_("net rpc registry deletekey\n"
1305 " Delete a registry key")
1309 rpc_registry_getvalue
,
1311 N_("Print a registry value"),
1312 N_("net rpc registry getvalue\n"
1313 " Print a registry value")
1317 rpc_registry_getvalueraw
,
1319 N_("Print a registry value"),
1320 N_("net rpc registry getvalueraw\n"
1321 " Print a registry value (raw version)")
1325 rpc_registry_setvalue
,
1327 N_("Set a new registry value"),
1328 N_("net rpc registry setvalue\n"
1329 " Set a new registry value")
1333 rpc_registry_deletevalue
,
1335 N_("Delete a registry value"),
1336 N_("net rpc registry deletevalue\n"
1337 " Delete a registry value")
1343 N_("Save a registry file"),
1344 N_("net rpc registry save\n"
1345 " Save a registry file")
1351 N_("Dump a registry file"),
1352 N_("net rpc registry dump\n"
1353 " Dump a registry file")
1359 N_("Copy a registry file"),
1360 N_("net rpc registry copy\n"
1361 " Copy a registry file")
1367 N_("Get security descriptor"),
1368 N_("net rpc registry getsd\n"
1369 " Get security descriptior")
1371 {NULL
, NULL
, 0, NULL
, NULL
}
1374 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);