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/>. */
22 #include "utils/net.h"
23 #include "utils/net_registry_util.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
26 #include "registry/reg_util_marshalling.h"
28 /*******************************************************************
29 connect to a registry hive root (open a registry policy)
30 *******************************************************************/
32 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
33 uint32_t reg_type
, uint32_t access_mask
,
34 struct policy_handle
*reg_hnd
)
36 ZERO_STRUCTP(reg_hnd
);
40 case HKEY_CLASSES_ROOT
:
41 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
42 access_mask
, reg_hnd
, NULL
);
44 case HKEY_LOCAL_MACHINE
:
45 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
46 access_mask
, reg_hnd
, NULL
);
49 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
50 access_mask
, reg_hnd
, NULL
);
52 case HKEY_CURRENT_USER
:
53 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
54 access_mask
, reg_hnd
, NULL
);
56 case HKEY_PERFORMANCE_DATA
:
57 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
58 access_mask
, reg_hnd
, NULL
);
61 /* fall through to end of function */
65 return NT_STATUS_INVALID_PARAMETER
;
68 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
69 uint32
*reg_type
, const char **key_name
)
72 char *hivename
= NULL
;
73 char *tmp_keyname
= NULL
;
75 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
77 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
78 if (!W_ERROR_IS_OK(werr
)) {
82 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
83 if (*key_name
== NULL
) {
87 if (strequal(hivename
, "HKLM") ||
88 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
90 (*reg_type
) = HKEY_LOCAL_MACHINE
;
91 } else if (strequal(hivename
, "HKCR") ||
92 strequal(hivename
, "HKEY_CLASSES_ROOT"))
94 (*reg_type
) = HKEY_CLASSES_ROOT
;
95 } else if (strequal(hivename
, "HKU") ||
96 strequal(hivename
, "HKEY_USERS"))
98 (*reg_type
) = HKEY_USERS
;
99 } else if (strequal(hivename
, "HKCU") ||
100 strequal(hivename
, "HKEY_CURRENT_USER"))
102 (*reg_type
) = HKEY_CURRENT_USER
;
103 } else if (strequal(hivename
, "HKPD") ||
104 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
106 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
108 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
116 TALLOC_FREE(tmp_ctx
);
120 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
121 struct rpc_pipe_client
*pipe_hnd
,
122 const char *name
, uint32 access_mask
,
123 struct policy_handle
*hive_hnd
,
124 struct policy_handle
*key_hnd
)
128 struct winreg_String key
;
132 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
133 return NT_STATUS_INVALID_PARAMETER
;
136 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
138 if (!(NT_STATUS_IS_OK(status
))) {
142 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
143 access_mask
, key_hnd
, NULL
);
144 if (!(NT_STATUS_IS_OK(status
))) {
145 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
152 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
153 struct rpc_pipe_client
*pipe_hnd
,
154 struct policy_handle
*key_hnd
,
155 uint32
*pnum_keys
, char ***pnames
,
156 char ***pclasses
, NTTIME
***pmodtimes
)
160 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
161 uint32 num_values
, max_valnamelen
, max_valbufsize
;
163 NTTIME last_changed_time
;
165 struct winreg_String classname
;
166 char **names
, **classes
;
169 if (!(mem_ctx
= talloc_new(ctx
))) {
170 return NT_STATUS_NO_MEMORY
;
173 ZERO_STRUCT(classname
);
174 status
= rpccli_winreg_QueryInfoKey(
175 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
176 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
177 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
179 if (!NT_STATUS_IS_OK(status
)) {
183 if (num_subkeys
== 0) {
185 TALLOC_FREE(mem_ctx
);
189 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
190 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
191 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
193 status
= NT_STATUS_NO_MEMORY
;
197 for (i
=0; i
<num_subkeys
; i
++) {
199 struct winreg_StringBuf class_buf
;
200 struct winreg_StringBuf name_buf
;
206 class_buf
.size
= max_classlen
+2;
210 name_buf
.size
= max_subkeylen
+2;
212 ZERO_STRUCT(modtime
);
214 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
215 i
, &name_buf
, &class_buf
,
218 if (W_ERROR_EQUAL(werr
,
219 WERR_NO_MORE_ITEMS
) ) {
220 status
= NT_STATUS_OK
;
223 if (!NT_STATUS_IS_OK(status
)) {
229 if (class_buf
.name
&&
230 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
231 status
= NT_STATUS_NO_MEMORY
;
235 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
236 status
= NT_STATUS_NO_MEMORY
;
240 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
241 modtimes
, &modtime
, sizeof(modtime
))))) {
242 status
= NT_STATUS_NO_MEMORY
;
247 *pnum_keys
= num_subkeys
;
250 *pnames
= talloc_move(ctx
, &names
);
253 *pclasses
= talloc_move(ctx
, &classes
);
256 *pmodtimes
= talloc_move(ctx
, &modtimes
);
259 status
= NT_STATUS_OK
;
262 TALLOC_FREE(mem_ctx
);
266 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
267 struct rpc_pipe_client
*pipe_hnd
,
268 struct policy_handle
*key_hnd
,
269 uint32
*pnum_values
, char ***pvalnames
,
270 struct registry_value
***pvalues
)
274 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
275 uint32 num_values
, max_valnamelen
, max_valbufsize
;
277 NTTIME last_changed_time
;
279 struct winreg_String classname
;
280 struct registry_value
**values
;
283 if (!(mem_ctx
= talloc_new(ctx
))) {
284 return NT_STATUS_NO_MEMORY
;
287 ZERO_STRUCT(classname
);
288 status
= rpccli_winreg_QueryInfoKey(
289 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
290 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
291 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
293 if (!NT_STATUS_IS_OK(status
)) {
297 if (num_values
== 0) {
299 TALLOC_FREE(mem_ctx
);
303 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
304 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
306 status
= NT_STATUS_NO_MEMORY
;
310 for (i
=0; i
<num_values
; i
++) {
311 enum winreg_Type type
= REG_NONE
;
317 struct winreg_ValNameBuf name_buf
;
322 name_buf
.size
= max_valnamelen
+ 2;
324 data_size
= max_valbufsize
;
325 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
328 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
331 &value_length
, &err
);
333 if ( W_ERROR_EQUAL(err
,
334 WERR_NO_MORE_ITEMS
) ) {
335 status
= NT_STATUS_OK
;
339 if (!(NT_STATUS_IS_OK(status
))) {
343 if (name_buf
.name
== NULL
) {
344 status
= NT_STATUS_INVALID_PARAMETER
;
348 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
349 status
= NT_STATUS_NO_MEMORY
;
353 err
= registry_pull_value(values
, &values
[i
], type
, data
,
354 data_size
, value_length
);
355 if (!W_ERROR_IS_OK(err
)) {
356 status
= werror_to_ntstatus(err
);
361 *pnum_values
= num_values
;
364 *pvalnames
= talloc_move(ctx
, &names
);
367 *pvalues
= talloc_move(ctx
, &values
);
370 status
= NT_STATUS_OK
;
373 TALLOC_FREE(mem_ctx
);
377 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
378 struct rpc_pipe_client
*pipe_hnd
,
379 struct policy_handle
*key_hnd
,
381 struct KeySecurityData
*sd
)
383 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
388 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
389 struct rpc_pipe_client
*pipe_hnd
,
390 struct policy_handle
*key_hnd
,
392 const struct registry_value
*value
)
394 struct winreg_String name_string
;
399 err
= registry_push_value(mem_ctx
, value
, &blob
);
400 if (!W_ERROR_IS_OK(err
)) {
401 return werror_to_ntstatus(err
);
404 ZERO_STRUCT(name_string
);
406 name_string
.name
= name
;
407 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
408 name_string
, value
->type
,
409 blob
.data
, blob
.length
, NULL
);
410 TALLOC_FREE(blob
.data
);
414 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
415 const struct dom_sid
*domain_sid
,
416 const char *domain_name
,
417 struct cli_state
*cli
,
418 struct rpc_pipe_client
*pipe_hnd
,
423 struct policy_handle hive_hnd
, key_hnd
;
425 struct registry_value value
;
427 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
428 SEC_FLAG_MAXIMUM_ALLOWED
,
429 &hive_hnd
, &key_hnd
);
430 if (!NT_STATUS_IS_OK(status
)) {
431 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
436 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
437 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
438 return NT_STATUS_NOT_IMPLEMENTED
;
441 if (strequal(argv
[2], "dword")) {
442 value
.type
= REG_DWORD
;
443 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
445 else if (strequal(argv
[2], "sz")) {
447 value
.v
.sz
.len
= strlen(argv
[3])+1;
448 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
451 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
452 status
= NT_STATUS_NOT_IMPLEMENTED
;
456 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
459 if (!NT_STATUS_IS_OK(status
)) {
460 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
465 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
466 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
471 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
474 if (argc
< 4 || c
->display_usage
) {
475 d_fprintf(stderr
, "%s\n%s",
477 _("net rpc registry setvalue <key> <valuename> "
478 "<type> [<val>]+\n"));
482 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
483 rpc_registry_setvalue_internal
, argc
, argv
);
486 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
487 const struct dom_sid
*domain_sid
,
488 const char *domain_name
,
489 struct cli_state
*cli
,
490 struct rpc_pipe_client
*pipe_hnd
,
495 struct policy_handle hive_hnd
, key_hnd
;
497 struct winreg_String valuename
;
499 ZERO_STRUCT(valuename
);
501 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
502 SEC_FLAG_MAXIMUM_ALLOWED
,
503 &hive_hnd
, &key_hnd
);
504 if (!NT_STATUS_IS_OK(status
)) {
505 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
510 valuename
.name
= argv
[1];
512 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
515 if (!NT_STATUS_IS_OK(status
)) {
516 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
520 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
521 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
526 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
529 if (argc
!= 2 || c
->display_usage
) {
530 d_fprintf(stderr
, "%s\n%s",
532 _("net rpc registry deletevalue <key> <valuename>\n"));
536 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
537 rpc_registry_deletevalue_internal
, argc
, argv
);
540 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
541 const struct dom_sid
*domain_sid
,
542 const char *domain_name
,
543 struct cli_state
*cli
,
544 struct rpc_pipe_client
*pipe_hnd
,
550 struct policy_handle hive_hnd
, key_hnd
;
553 struct winreg_String valuename
;
554 struct registry_value
*value
= NULL
;
555 enum winreg_Type type
= REG_NONE
;
556 uint8_t *data
= NULL
;
557 uint32_t data_size
= 0;
558 uint32_t value_length
= 0;
559 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
561 ZERO_STRUCT(valuename
);
563 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
564 SEC_FLAG_MAXIMUM_ALLOWED
,
565 &hive_hnd
, &key_hnd
);
566 if (!NT_STATUS_IS_OK(status
)) {
567 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
572 valuename
.name
= argv
[1];
575 * call QueryValue once with data == NULL to get the
576 * needed memory size to be allocated, then allocate
577 * data buffer and call again.
579 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
587 if (!NT_STATUS_IS_OK(status
)) {
588 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
593 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
596 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
604 if (!NT_STATUS_IS_OK(status
)) {
605 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
610 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
611 data_size
, value_length
);
612 if (!W_ERROR_IS_OK(werr
)) {
613 status
= werror_to_ntstatus(werr
);
617 print_registry_value(value
, raw
);
620 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
621 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
623 TALLOC_FREE(tmp_ctx
);
628 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
629 const struct dom_sid
*domain_sid
,
630 const char *domain_name
,
631 struct cli_state
*cli
,
632 struct rpc_pipe_client
*pipe_hnd
,
637 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
638 cli
, pipe_hnd
, mem_ctx
, false,
642 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
645 if (argc
!= 2 || c
->display_usage
) {
646 d_fprintf(stderr
, "%s\n%s",
648 _("net rpc registry getvalue <key> <valuename>\n"));
652 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
653 rpc_registry_getvalue_full
, argc
, argv
);
656 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
657 const struct dom_sid
*domain_sid
,
658 const char *domain_name
,
659 struct cli_state
*cli
,
660 struct rpc_pipe_client
*pipe_hnd
,
665 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
666 cli
, pipe_hnd
, mem_ctx
, true,
670 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
673 if (argc
!= 2 || c
->display_usage
) {
674 d_fprintf(stderr
, "%s\n%s",
676 _("net rpc registry getvalue <key> <valuename>\n"));
680 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
681 rpc_registry_getvalue_raw
, argc
, argv
);
684 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
685 const struct dom_sid
*domain_sid
,
686 const char *domain_name
,
687 struct cli_state
*cli
,
688 struct rpc_pipe_client
*pipe_hnd
,
694 struct policy_handle hive_hnd
, key_hnd
;
695 struct winreg_String key
, keyclass
;
696 enum winreg_CreateAction action
;
700 ZERO_STRUCT(keyclass
);
702 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
703 return NT_STATUS_INVALID_PARAMETER
;
706 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
707 SEC_FLAG_MAXIMUM_ALLOWED
,
709 if (!(NT_STATUS_IS_OK(status
))) {
713 action
= REG_ACTION_NONE
;
716 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
717 keyclass
, 0, REG_KEY_READ
, NULL
,
718 &key_hnd
, &action
, NULL
);
719 if (!NT_STATUS_IS_OK(status
)) {
720 d_fprintf(stderr
, _("createkey returned %s\n"),
722 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
727 case REG_ACTION_NONE
:
728 d_printf(_("createkey did nothing -- huh?\n"));
730 case REG_CREATED_NEW_KEY
:
731 d_printf(_("createkey created %s\n"), argv
[0]);
733 case REG_OPENED_EXISTING_KEY
:
734 d_printf(_("createkey opened existing %s\n"), argv
[0]);
738 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
739 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
744 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
747 if (argc
!= 1 || c
->display_usage
) {
748 d_fprintf(stderr
, "%s\n%s",
750 _("net rpc registry createkey <key>\n"));
754 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
755 rpc_registry_createkey_internal
, argc
, argv
);
758 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
759 const struct dom_sid
*domain_sid
,
760 const char *domain_name
,
761 struct cli_state
*cli
,
762 struct rpc_pipe_client
*pipe_hnd
,
768 struct policy_handle hive_hnd
;
769 struct winreg_String key
;
774 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
775 return NT_STATUS_INVALID_PARAMETER
;
778 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
779 SEC_FLAG_MAXIMUM_ALLOWED
,
781 if (!(NT_STATUS_IS_OK(status
))) {
785 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
786 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
788 if (!NT_STATUS_IS_OK(status
)) {
789 d_fprintf(stderr
, _("deletekey returned %s\n"),
796 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
798 if (argc
!= 1 || c
->display_usage
) {
799 d_fprintf(stderr
, "%s\n%s",
801 _("net rpc registry deletekey <key>\n"));
805 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
806 rpc_registry_deletekey_internal
, argc
, argv
);
809 /********************************************************************
810 ********************************************************************/
812 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
813 const struct dom_sid
*domain_sid
,
814 const char *domain_name
,
815 struct cli_state
*cli
,
816 struct rpc_pipe_client
*pipe_hnd
,
821 struct policy_handle pol_hive
, pol_key
;
823 uint32 num_subkeys
= 0;
824 uint32 num_values
= 0;
825 char **names
= NULL
, **classes
= NULL
;
826 NTTIME
**modtimes
= NULL
;
828 struct registry_value
**values
= NULL
;
830 if (argc
!= 1 || c
->display_usage
) {
833 _("net rpc registry enumerate <path>\n"));
834 d_printf("%s net rpc registry enumerate "
835 "'HKLM\\Software\\Samba'\n", _("Example:"));
836 return NT_STATUS_INVALID_PARAMETER
;
839 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
840 &pol_hive
, &pol_key
);
841 if (!NT_STATUS_IS_OK(status
)) {
842 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
847 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
848 &names
, &classes
, &modtimes
);
849 if (!NT_STATUS_IS_OK(status
)) {
850 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
855 for (i
=0; i
<num_subkeys
; i
++) {
856 print_registry_key(names
[i
], modtimes
[i
]);
859 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
861 if (!NT_STATUS_IS_OK(status
)) {
862 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
867 for (i
=0; i
<num_values
; i
++) {
868 print_registry_value_with_name(names
[i
], values
[i
]);
871 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
872 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
877 /********************************************************************
878 ********************************************************************/
880 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
883 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
884 rpc_registry_enumerate_internal
, argc
, argv
);
887 /********************************************************************
888 ********************************************************************/
890 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
891 const struct dom_sid
*domain_sid
,
892 const char *domain_name
,
893 struct cli_state
*cli
,
894 struct rpc_pipe_client
*pipe_hnd
,
899 WERROR result
= WERR_GENERAL_FAILURE
;
900 struct policy_handle pol_hive
, pol_key
;
901 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
902 struct winreg_String filename
;
904 if (argc
!= 2 || c
->display_usage
) {
907 _("net rpc registry backup <path> <file> \n"));
908 return NT_STATUS_INVALID_PARAMETER
;
911 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
912 &pol_hive
, &pol_key
);
913 if (!NT_STATUS_IS_OK(status
)) {
914 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
919 filename
.name
= argv
[1];
920 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
921 if ( !W_ERROR_IS_OK(result
) ) {
922 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
923 cli
->desthost
, argv
[1]);
928 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
929 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
934 /********************************************************************
935 ********************************************************************/
937 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
939 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
940 rpc_registry_save_internal
, argc
, argv
);
944 /********************************************************************
945 ********************************************************************/
947 static void dump_values( REGF_NK_REC
*nk
)
950 const char *data_str
= NULL
;
951 uint32 data_size
, data
;
957 for ( i
=0; i
<nk
->num_values
; i
++ ) {
958 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
959 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
961 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
962 switch ( nk
->values
[i
].type
) {
964 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
965 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
969 d_printf( "%s", data_str
);
973 for ( j
=0; j
<data_size
; j
++ ) {
974 d_printf( "%c", nk
->values
[i
].data
[j
] );
978 data
= IVAL( nk
->values
[i
].data
, 0 );
979 d_printf("0x%x", data
);
982 for ( j
=0; j
<data_size
; j
++ ) {
983 d_printf( "%x", nk
->values
[i
].data
[j
] );
987 d_printf(_("unknown"));
996 /********************************************************************
997 ********************************************************************/
999 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
1003 /* depth first dump of the registry tree */
1005 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1007 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1010 d_printf("[%s]\n", regpath
);
1013 dump_registry_tree( file
, key
, regpath
);
1020 /********************************************************************
1021 ********************************************************************/
1023 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1024 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1025 const char *parentpath
)
1027 REGF_NK_REC
*key
, *subkey
;
1028 struct regval_ctr
*values
= NULL
;
1029 struct regsubkey_ctr
*subkeys
= NULL
;
1034 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1035 if (!W_ERROR_IS_OK(werr
)) {
1036 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1037 "%s\n", win_errstr(werr
)));
1041 werr
= regval_ctr_init(subkeys
, &values
);
1042 if (!W_ERROR_IS_OK(werr
)) {
1043 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1044 TALLOC_FREE(subkeys
);
1048 /* copy values into the struct regval_ctr */
1050 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1051 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1052 nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1055 /* copy subkeys into the struct regsubkey_ctr */
1057 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1058 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1061 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1063 /* write each one of the subkeys out */
1065 path
= talloc_asprintf(subkeys
,
1071 TALLOC_FREE(subkeys
);
1075 nk
->subkey_index
= 0;
1076 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1077 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1080 d_printf("[%s]\n", path
);
1081 TALLOC_FREE(subkeys
);
1086 /********************************************************************
1087 ********************************************************************/
1089 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1091 REGF_FILE
*registry
;
1094 if (argc
!= 1 || c
->display_usage
) {
1097 _("net rpc registry dump <file> \n"));
1101 d_printf(_("Opening %s...."), argv
[0]);
1102 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1103 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1106 d_printf(_("ok\n"));
1108 /* get the root of the registry file */
1110 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1111 d_fprintf(stderr
, _("Could not get rootkey\n"));
1112 regfio_close( registry
);
1115 d_printf("[%s]\n", nk
->keyname
);
1119 dump_registry_tree( registry
, nk
, nk
->keyname
);
1122 talloc_report_full( registry
->mem_ctx
, stderr
);
1124 d_printf(_("Closing registry..."));
1125 regfio_close( registry
);
1126 d_printf(_("ok\n"));
1131 /********************************************************************
1132 ********************************************************************/
1134 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1136 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1140 if (argc
!= 2 || c
->display_usage
) {
1143 _("net rpc registry copy <srcfile> <newfile>\n"));
1147 d_printf(_("Opening %s...."), argv
[0]);
1148 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1149 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1152 d_printf(_("ok\n"));
1154 d_printf(_("Opening %s...."), argv
[1]);
1155 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1156 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1159 d_printf(_("ok\n"));
1161 /* get the root of the registry file */
1163 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1164 d_fprintf(stderr
, _("Could not get rootkey\n"));
1167 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1169 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1175 d_printf(_("Closing %s..."), argv
[1]);
1177 regfio_close( outfile
);
1179 d_printf(_("ok\n"));
1181 d_printf(_("Closing %s..."), argv
[0]);
1183 regfio_close( infile
);
1185 d_printf(_("ok\n"));
1190 /********************************************************************
1191 ********************************************************************/
1193 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1194 const struct dom_sid
*domain_sid
,
1195 const char *domain_name
,
1196 struct cli_state
*cli
,
1197 struct rpc_pipe_client
*pipe_hnd
,
1198 TALLOC_CTX
*mem_ctx
,
1202 struct policy_handle pol_hive
, pol_key
;
1204 enum ndr_err_code ndr_err
;
1205 struct KeySecurityData
*sd
= NULL
;
1208 struct security_descriptor sec_desc
;
1209 uint32_t access_mask
= REG_KEY_READ
|
1210 SEC_FLAG_MAXIMUM_ALLOWED
|
1211 SEC_FLAG_SYSTEM_SECURITY
;
1213 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1216 _("net rpc registry getsd <path> <secinfo>\n"));
1217 d_printf("%s net rpc registry getsd "
1218 "'HKLM\\Software\\Samba'\n", _("Example:"));
1219 return NT_STATUS_INVALID_PARAMETER
;
1222 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1224 &pol_hive
, &pol_key
);
1225 if (!NT_STATUS_IS_OK(status
)) {
1226 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1231 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1233 status
= NT_STATUS_NO_MEMORY
;
1240 sscanf(argv
[1], "%x", &sec_info
);
1242 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1245 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1246 if (!NT_STATUS_IS_OK(status
)) {
1247 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1252 blob
.data
= sd
->data
;
1253 blob
.length
= sd
->size
;
1255 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1256 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1257 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1258 status
= ndr_map_error2ntstatus(ndr_err
);
1261 status
= NT_STATUS_OK
;
1263 display_sec_desc(&sec_desc
);
1266 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1267 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1273 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1275 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1276 rpc_registry_getsd_internal
, argc
, argv
);
1279 /********************************************************************
1280 ********************************************************************/
1282 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1284 struct functable func
[] = {
1287 rpc_registry_enumerate
,
1289 N_("Enumerate registry keys and values"),
1290 N_("net rpc registry enumerate\n"
1291 " Enumerate registry keys and values")
1295 rpc_registry_createkey
,
1297 N_("Create a new registry key"),
1298 N_("net rpc registry createkey\n"
1299 " Create a new registry key")
1303 rpc_registry_deletekey
,
1305 N_("Delete a registry key"),
1306 N_("net rpc registry deletekey\n"
1307 " Delete a registry key")
1311 rpc_registry_getvalue
,
1313 N_("Print a registry value"),
1314 N_("net rpc registry getvalue\n"
1315 " Print a registry value")
1319 rpc_registry_getvalueraw
,
1321 N_("Print a registry value"),
1322 N_("net rpc registry getvalueraw\n"
1323 " Print a registry value (raw version)")
1327 rpc_registry_setvalue
,
1329 N_("Set a new registry value"),
1330 N_("net rpc registry setvalue\n"
1331 " Set a new registry value")
1335 rpc_registry_deletevalue
,
1337 N_("Delete a registry value"),
1338 N_("net rpc registry deletevalue\n"
1339 " Delete a registry value")
1345 N_("Save a registry file"),
1346 N_("net rpc registry save\n"
1347 " Save a registry file")
1353 N_("Dump a registry file"),
1354 N_("net rpc registry dump\n"
1355 " Dump a registry file")
1361 N_("Copy a registry file"),
1362 N_("net rpc registry copy\n"
1363 " Copy a registry file")
1369 N_("Get security descriptor"),
1370 N_("net rpc registry getsd\n"
1371 " Get security descriptior")
1373 {NULL
, NULL
, 0, NULL
, NULL
}
1376 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);