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_objects.h"
27 #include "../librpc/gen_ndr/ndr_security.h"
29 /*******************************************************************
30 connect to a registry hive root (open a registry policy)
31 *******************************************************************/
33 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
34 uint32_t reg_type
, uint32_t access_mask
,
35 struct policy_handle
*reg_hnd
)
37 ZERO_STRUCTP(reg_hnd
);
41 case HKEY_CLASSES_ROOT
:
42 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
43 access_mask
, reg_hnd
, NULL
);
45 case HKEY_LOCAL_MACHINE
:
46 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
47 access_mask
, reg_hnd
, NULL
);
50 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
51 access_mask
, reg_hnd
, NULL
);
53 case HKEY_CURRENT_USER
:
54 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
55 access_mask
, reg_hnd
, NULL
);
57 case HKEY_PERFORMANCE_DATA
:
58 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
59 access_mask
, reg_hnd
, NULL
);
62 /* fall through to end of function */
66 return NT_STATUS_INVALID_PARAMETER
;
69 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
70 uint32
*reg_type
, const char **key_name
)
73 char *hivename
= NULL
;
74 char *tmp_keyname
= NULL
;
76 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
78 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
79 if (!W_ERROR_IS_OK(werr
)) {
83 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
84 if (*key_name
== NULL
) {
88 if (strequal(hivename
, "HKLM") ||
89 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
91 (*reg_type
) = HKEY_LOCAL_MACHINE
;
92 } else if (strequal(hivename
, "HKCR") ||
93 strequal(hivename
, "HKEY_CLASSES_ROOT"))
95 (*reg_type
) = HKEY_CLASSES_ROOT
;
96 } else if (strequal(hivename
, "HKU") ||
97 strequal(hivename
, "HKEY_USERS"))
99 (*reg_type
) = HKEY_USERS
;
100 } else if (strequal(hivename
, "HKCU") ||
101 strequal(hivename
, "HKEY_CURRENT_USER"))
103 (*reg_type
) = HKEY_CURRENT_USER
;
104 } else if (strequal(hivename
, "HKPD") ||
105 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
107 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
109 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
117 TALLOC_FREE(tmp_ctx
);
121 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
122 struct rpc_pipe_client
*pipe_hnd
,
123 const char *name
, uint32 access_mask
,
124 struct policy_handle
*hive_hnd
,
125 struct policy_handle
*key_hnd
)
129 struct winreg_String key
;
133 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
134 return NT_STATUS_INVALID_PARAMETER
;
137 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
139 if (!(NT_STATUS_IS_OK(status
))) {
143 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
144 access_mask
, key_hnd
, NULL
);
145 if (!(NT_STATUS_IS_OK(status
))) {
146 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
153 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
154 struct rpc_pipe_client
*pipe_hnd
,
155 struct policy_handle
*key_hnd
,
156 uint32
*pnum_keys
, char ***pnames
,
157 char ***pclasses
, NTTIME
***pmodtimes
)
161 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
162 uint32 num_values
, max_valnamelen
, max_valbufsize
;
164 NTTIME last_changed_time
;
166 struct winreg_String classname
;
167 char **names
, **classes
;
170 if (!(mem_ctx
= talloc_new(ctx
))) {
171 return NT_STATUS_NO_MEMORY
;
174 ZERO_STRUCT(classname
);
175 status
= rpccli_winreg_QueryInfoKey(
176 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
177 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
178 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
180 if (!NT_STATUS_IS_OK(status
)) {
184 if (num_subkeys
== 0) {
186 TALLOC_FREE(mem_ctx
);
190 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
191 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
192 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
194 status
= NT_STATUS_NO_MEMORY
;
198 for (i
=0; i
<num_subkeys
; i
++) {
200 struct winreg_StringBuf class_buf
;
201 struct winreg_StringBuf name_buf
;
207 class_buf
.size
= max_classlen
+2;
211 name_buf
.size
= max_subkeylen
+2;
213 ZERO_STRUCT(modtime
);
215 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
216 i
, &name_buf
, &class_buf
,
219 if (W_ERROR_EQUAL(werr
,
220 WERR_NO_MORE_ITEMS
) ) {
221 status
= NT_STATUS_OK
;
224 if (!NT_STATUS_IS_OK(status
)) {
230 if (class_buf
.name
&&
231 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
232 status
= NT_STATUS_NO_MEMORY
;
236 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
237 status
= NT_STATUS_NO_MEMORY
;
241 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
242 modtimes
, &modtime
, sizeof(modtime
))))) {
243 status
= NT_STATUS_NO_MEMORY
;
248 *pnum_keys
= num_subkeys
;
251 *pnames
= talloc_move(ctx
, &names
);
254 *pclasses
= talloc_move(ctx
, &classes
);
257 *pmodtimes
= talloc_move(ctx
, &modtimes
);
260 status
= NT_STATUS_OK
;
263 TALLOC_FREE(mem_ctx
);
267 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
268 struct rpc_pipe_client
*pipe_hnd
,
269 struct policy_handle
*key_hnd
,
270 uint32
*pnum_values
, char ***pvalnames
,
271 struct registry_value
***pvalues
)
275 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
276 uint32 num_values
, max_valnamelen
, max_valbufsize
;
278 NTTIME last_changed_time
;
280 struct winreg_String classname
;
281 struct registry_value
**values
;
284 if (!(mem_ctx
= talloc_new(ctx
))) {
285 return NT_STATUS_NO_MEMORY
;
288 ZERO_STRUCT(classname
);
289 status
= rpccli_winreg_QueryInfoKey(
290 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
291 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
292 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
294 if (!NT_STATUS_IS_OK(status
)) {
298 if (num_values
== 0) {
300 TALLOC_FREE(mem_ctx
);
304 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
305 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
307 status
= NT_STATUS_NO_MEMORY
;
311 for (i
=0; i
<num_values
; i
++) {
312 enum winreg_Type type
= REG_NONE
;
318 struct winreg_ValNameBuf name_buf
;
323 name_buf
.size
= max_valnamelen
+ 2;
325 data_size
= max_valbufsize
;
326 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
329 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
332 &value_length
, &err
);
334 if ( W_ERROR_EQUAL(err
,
335 WERR_NO_MORE_ITEMS
) ) {
336 status
= NT_STATUS_OK
;
340 if (!(NT_STATUS_IS_OK(status
))) {
344 if (name_buf
.name
== NULL
) {
345 status
= NT_STATUS_INVALID_PARAMETER
;
349 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
350 status
= NT_STATUS_NO_MEMORY
;
354 values
[i
] = talloc_zero(values
, struct registry_value
);
355 if (values
[i
] == NULL
) {
356 status
= NT_STATUS_NO_MEMORY
;
360 values
[i
]->type
= type
;
361 values
[i
]->data
= data_blob_talloc(values
[i
], data
, data_size
);
364 *pnum_values
= num_values
;
367 *pvalnames
= talloc_move(ctx
, &names
);
370 *pvalues
= talloc_move(ctx
, &values
);
373 status
= NT_STATUS_OK
;
376 TALLOC_FREE(mem_ctx
);
380 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
381 struct rpc_pipe_client
*pipe_hnd
,
382 struct policy_handle
*key_hnd
,
384 struct KeySecurityData
*sd
)
386 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
391 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
392 struct rpc_pipe_client
*pipe_hnd
,
393 struct policy_handle
*key_hnd
,
395 const struct registry_value
*value
)
397 struct winreg_String name_string
;
400 ZERO_STRUCT(name_string
);
402 name_string
.name
= name
;
403 result
= rpccli_winreg_SetValue(pipe_hnd
, mem_ctx
, key_hnd
,
404 name_string
, value
->type
,
405 value
->data
.data
, value
->data
.length
, NULL
);
409 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
410 const struct dom_sid
*domain_sid
,
411 const char *domain_name
,
412 struct cli_state
*cli
,
413 struct rpc_pipe_client
*pipe_hnd
,
418 struct policy_handle hive_hnd
, key_hnd
;
420 struct registry_value value
;
422 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
423 SEC_FLAG_MAXIMUM_ALLOWED
,
424 &hive_hnd
, &key_hnd
);
425 if (!NT_STATUS_IS_OK(status
)) {
426 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
431 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
432 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
433 return NT_STATUS_NOT_IMPLEMENTED
;
436 if (strequal(argv
[2], "dword")) {
437 uint32_t v
= strtoul(argv
[3], NULL
, 10);
438 value
.type
= REG_DWORD
;
439 value
.data
= data_blob_talloc(mem_ctx
, NULL
, 4);
440 SIVAL(value
.data
.data
, 0, v
);
442 else if (strequal(argv
[2], "sz")) {
444 if (!push_reg_sz(mem_ctx
, &value
.data
, argv
[3])) {
445 status
= NT_STATUS_NO_MEMORY
;
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 struct 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 struct 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
;
551 struct winreg_String valuename
;
552 struct registry_value
*value
= NULL
;
553 enum winreg_Type type
= REG_NONE
;
554 uint32_t data_size
= 0;
555 uint32_t value_length
= 0;
556 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
558 ZERO_STRUCT(valuename
);
560 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
561 SEC_FLAG_MAXIMUM_ALLOWED
,
562 &hive_hnd
, &key_hnd
);
563 if (!NT_STATUS_IS_OK(status
)) {
564 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
569 valuename
.name
= argv
[1];
571 value
= talloc_zero(tmp_ctx
, struct registry_value
);
573 return NT_STATUS_NO_MEMORY
;
577 * call QueryValue once with data == NULL to get the
578 * needed memory size to be allocated, then allocate
579 * data buffer and call again.
581 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
589 if (!NT_STATUS_IS_OK(status
)) {
590 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
595 value
->data
= data_blob_talloc(tmp_ctx
, NULL
, data_size
);
597 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
605 if (!NT_STATUS_IS_OK(status
)) {
606 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
613 print_registry_value(value
, raw
);
616 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
617 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
619 TALLOC_FREE(tmp_ctx
);
624 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
625 const struct dom_sid
*domain_sid
,
626 const char *domain_name
,
627 struct cli_state
*cli
,
628 struct rpc_pipe_client
*pipe_hnd
,
633 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
634 cli
, pipe_hnd
, mem_ctx
, false,
638 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
641 if (argc
!= 2 || c
->display_usage
) {
642 d_fprintf(stderr
, "%s\n%s",
644 _("net rpc registry getvalue <key> <valuename>\n"));
648 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
649 rpc_registry_getvalue_full
, argc
, argv
);
652 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
653 const struct dom_sid
*domain_sid
,
654 const char *domain_name
,
655 struct cli_state
*cli
,
656 struct rpc_pipe_client
*pipe_hnd
,
661 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
662 cli
, pipe_hnd
, mem_ctx
, true,
666 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
669 if (argc
!= 2 || c
->display_usage
) {
670 d_fprintf(stderr
, "%s\n%s",
672 _("net rpc registry getvalue <key> <valuename>\n"));
676 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
677 rpc_registry_getvalue_raw
, argc
, argv
);
680 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
681 const struct dom_sid
*domain_sid
,
682 const char *domain_name
,
683 struct cli_state
*cli
,
684 struct rpc_pipe_client
*pipe_hnd
,
690 struct policy_handle hive_hnd
, key_hnd
;
691 struct winreg_String key
, keyclass
;
692 enum winreg_CreateAction action
;
696 ZERO_STRUCT(keyclass
);
698 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
699 return NT_STATUS_INVALID_PARAMETER
;
702 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
703 SEC_FLAG_MAXIMUM_ALLOWED
,
705 if (!(NT_STATUS_IS_OK(status
))) {
709 action
= REG_ACTION_NONE
;
712 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
713 keyclass
, 0, REG_KEY_READ
, NULL
,
714 &key_hnd
, &action
, NULL
);
715 if (!NT_STATUS_IS_OK(status
)) {
716 d_fprintf(stderr
, _("createkey returned %s\n"),
718 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
723 case REG_ACTION_NONE
:
724 d_printf(_("createkey did nothing -- huh?\n"));
726 case REG_CREATED_NEW_KEY
:
727 d_printf(_("createkey created %s\n"), argv
[0]);
729 case REG_OPENED_EXISTING_KEY
:
730 d_printf(_("createkey opened existing %s\n"), argv
[0]);
734 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
735 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
740 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
743 if (argc
!= 1 || c
->display_usage
) {
744 d_fprintf(stderr
, "%s\n%s",
746 _("net rpc registry createkey <key>\n"));
750 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
751 rpc_registry_createkey_internal
, argc
, argv
);
754 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
755 const struct dom_sid
*domain_sid
,
756 const char *domain_name
,
757 struct cli_state
*cli
,
758 struct rpc_pipe_client
*pipe_hnd
,
764 struct policy_handle hive_hnd
;
765 struct winreg_String key
;
770 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
771 return NT_STATUS_INVALID_PARAMETER
;
774 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
775 SEC_FLAG_MAXIMUM_ALLOWED
,
777 if (!(NT_STATUS_IS_OK(status
))) {
781 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
782 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
784 if (!NT_STATUS_IS_OK(status
)) {
785 d_fprintf(stderr
, _("deletekey returned %s\n"),
792 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
794 if (argc
!= 1 || c
->display_usage
) {
795 d_fprintf(stderr
, "%s\n%s",
797 _("net rpc registry deletekey <key>\n"));
801 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
802 rpc_registry_deletekey_internal
, argc
, argv
);
805 /********************************************************************
806 ********************************************************************/
808 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
809 const struct dom_sid
*domain_sid
,
810 const char *domain_name
,
811 struct cli_state
*cli
,
812 struct rpc_pipe_client
*pipe_hnd
,
817 struct policy_handle pol_hive
, pol_key
;
819 uint32 num_subkeys
= 0;
820 uint32 num_values
= 0;
821 char **names
= NULL
, **classes
= NULL
;
822 NTTIME
**modtimes
= NULL
;
824 struct registry_value
**values
= NULL
;
826 if (argc
!= 1 || c
->display_usage
) {
829 _("net rpc registry enumerate <path>\n"));
830 d_printf("%s net rpc registry enumerate "
831 "'HKLM\\Software\\Samba'\n", _("Example:"));
832 return NT_STATUS_INVALID_PARAMETER
;
835 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
836 &pol_hive
, &pol_key
);
837 if (!NT_STATUS_IS_OK(status
)) {
838 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
843 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
844 &names
, &classes
, &modtimes
);
845 if (!NT_STATUS_IS_OK(status
)) {
846 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
851 for (i
=0; i
<num_subkeys
; i
++) {
852 print_registry_key(names
[i
], modtimes
[i
]);
855 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
857 if (!NT_STATUS_IS_OK(status
)) {
858 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
863 for (i
=0; i
<num_values
; i
++) {
864 print_registry_value_with_name(names
[i
], values
[i
]);
867 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
868 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
873 /********************************************************************
874 ********************************************************************/
876 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
879 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
880 rpc_registry_enumerate_internal
, argc
, argv
);
883 /********************************************************************
884 ********************************************************************/
886 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
887 const struct dom_sid
*domain_sid
,
888 const char *domain_name
,
889 struct cli_state
*cli
,
890 struct rpc_pipe_client
*pipe_hnd
,
895 WERROR result
= WERR_GENERAL_FAILURE
;
896 struct policy_handle pol_hive
, pol_key
;
897 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
898 struct winreg_String filename
;
900 if (argc
!= 2 || c
->display_usage
) {
903 _("net rpc registry backup <path> <file> \n"));
904 return NT_STATUS_INVALID_PARAMETER
;
907 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
908 &pol_hive
, &pol_key
);
909 if (!NT_STATUS_IS_OK(status
)) {
910 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
915 filename
.name
= argv
[1];
916 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
917 if ( !W_ERROR_IS_OK(result
) ) {
918 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
919 cli
->desthost
, argv
[1]);
924 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
925 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
930 /********************************************************************
931 ********************************************************************/
933 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
935 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
936 rpc_registry_save_internal
, argc
, argv
);
940 /********************************************************************
941 ********************************************************************/
943 static void dump_values( REGF_NK_REC
*nk
)
946 const char *data_str
= NULL
;
947 uint32 data_size
, data
;
953 for ( i
=0; i
<nk
->num_values
; i
++ ) {
954 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
955 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
957 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
958 switch ( nk
->values
[i
].type
) {
960 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
961 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
965 d_printf( "%s", data_str
);
969 for ( j
=0; j
<data_size
; j
++ ) {
970 d_printf( "%c", nk
->values
[i
].data
[j
] );
974 data
= IVAL( nk
->values
[i
].data
, 0 );
975 d_printf("0x%x", data
);
978 for ( j
=0; j
<data_size
; j
++ ) {
979 d_printf( "%x", nk
->values
[i
].data
[j
] );
983 d_printf(_("unknown"));
992 /********************************************************************
993 ********************************************************************/
995 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
999 /* depth first dump of the registry tree */
1001 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1003 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1006 d_printf("[%s]\n", regpath
);
1009 dump_registry_tree( file
, key
, regpath
);
1016 /********************************************************************
1017 ********************************************************************/
1019 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1020 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1021 const char *parentpath
)
1023 REGF_NK_REC
*key
, *subkey
;
1024 struct regval_ctr
*values
= NULL
;
1025 struct regsubkey_ctr
*subkeys
= NULL
;
1030 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1031 if (!W_ERROR_IS_OK(werr
)) {
1032 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1033 "%s\n", win_errstr(werr
)));
1037 werr
= regval_ctr_init(subkeys
, &values
);
1038 if (!W_ERROR_IS_OK(werr
)) {
1039 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1040 TALLOC_FREE(subkeys
);
1044 /* copy values into the struct regval_ctr */
1046 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1047 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1048 nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1051 /* copy subkeys into the struct regsubkey_ctr */
1053 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1054 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1057 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1059 /* write each one of the subkeys out */
1061 path
= talloc_asprintf(subkeys
,
1067 TALLOC_FREE(subkeys
);
1071 nk
->subkey_index
= 0;
1072 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1073 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1076 d_printf("[%s]\n", path
);
1077 TALLOC_FREE(subkeys
);
1082 /********************************************************************
1083 ********************************************************************/
1085 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1087 REGF_FILE
*registry
;
1090 if (argc
!= 1 || c
->display_usage
) {
1093 _("net rpc registry dump <file> \n"));
1097 d_printf(_("Opening %s...."), argv
[0]);
1098 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1099 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1102 d_printf(_("ok\n"));
1104 /* get the root of the registry file */
1106 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1107 d_fprintf(stderr
, _("Could not get rootkey\n"));
1108 regfio_close( registry
);
1111 d_printf("[%s]\n", nk
->keyname
);
1115 dump_registry_tree( registry
, nk
, nk
->keyname
);
1118 talloc_report_full( registry
->mem_ctx
, stderr
);
1120 d_printf(_("Closing registry..."));
1121 regfio_close( registry
);
1122 d_printf(_("ok\n"));
1127 /********************************************************************
1128 ********************************************************************/
1130 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1132 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1136 if (argc
!= 2 || c
->display_usage
) {
1139 _("net rpc registry copy <srcfile> <newfile>\n"));
1143 d_printf(_("Opening %s...."), argv
[0]);
1144 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1145 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1148 d_printf(_("ok\n"));
1150 d_printf(_("Opening %s...."), argv
[1]);
1151 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1152 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1155 d_printf(_("ok\n"));
1157 /* get the root of the registry file */
1159 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1160 d_fprintf(stderr
, _("Could not get rootkey\n"));
1163 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1165 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1171 d_printf(_("Closing %s..."), argv
[1]);
1173 regfio_close( outfile
);
1175 d_printf(_("ok\n"));
1177 d_printf(_("Closing %s..."), argv
[0]);
1179 regfio_close( infile
);
1181 d_printf(_("ok\n"));
1186 /********************************************************************
1187 ********************************************************************/
1189 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1190 const struct dom_sid
*domain_sid
,
1191 const char *domain_name
,
1192 struct cli_state
*cli
,
1193 struct rpc_pipe_client
*pipe_hnd
,
1194 TALLOC_CTX
*mem_ctx
,
1198 struct policy_handle pol_hive
, pol_key
;
1200 enum ndr_err_code ndr_err
;
1201 struct KeySecurityData
*sd
= NULL
;
1204 struct security_descriptor sec_desc
;
1205 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
|
1206 SEC_FLAG_SYSTEM_SECURITY
;
1208 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1211 _("net rpc registry getsd <path> <secinfo>\n"));
1212 d_printf("%s net rpc registry getsd "
1213 "'HKLM\\Software\\Samba'\n", _("Example:"));
1214 return NT_STATUS_INVALID_PARAMETER
;
1217 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1219 &pol_hive
, &pol_key
);
1220 if (!NT_STATUS_IS_OK(status
)) {
1221 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1226 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1228 status
= NT_STATUS_NO_MEMORY
;
1235 sscanf(argv
[1], "%x", &sec_info
);
1237 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1240 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1241 if (!NT_STATUS_IS_OK(status
)) {
1242 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1247 blob
.data
= sd
->data
;
1248 blob
.length
= sd
->size
;
1250 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1251 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1252 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1253 status
= ndr_map_error2ntstatus(ndr_err
);
1256 status
= NT_STATUS_OK
;
1258 display_sec_desc(&sec_desc
);
1261 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1262 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1268 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1270 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1271 rpc_registry_getsd_internal
, argc
, argv
);
1274 /********************************************************************
1275 ********************************************************************/
1277 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1279 struct functable func
[] = {
1282 rpc_registry_enumerate
,
1284 N_("Enumerate registry keys and values"),
1285 N_("net rpc registry enumerate\n"
1286 " Enumerate registry keys and values")
1290 rpc_registry_createkey
,
1292 N_("Create a new registry key"),
1293 N_("net rpc registry createkey\n"
1294 " Create a new registry key")
1298 rpc_registry_deletekey
,
1300 N_("Delete a registry key"),
1301 N_("net rpc registry deletekey\n"
1302 " Delete a registry key")
1306 rpc_registry_getvalue
,
1308 N_("Print a registry value"),
1309 N_("net rpc registry getvalue\n"
1310 " Print a registry value")
1314 rpc_registry_getvalueraw
,
1316 N_("Print a registry value"),
1317 N_("net rpc registry getvalueraw\n"
1318 " Print a registry value (raw version)")
1322 rpc_registry_setvalue
,
1324 N_("Set a new registry value"),
1325 N_("net rpc registry setvalue\n"
1326 " Set a new registry value")
1330 rpc_registry_deletevalue
,
1332 N_("Delete a registry value"),
1333 N_("net rpc registry deletevalue\n"
1334 " Delete a registry value")
1340 N_("Save a registry file"),
1341 N_("net rpc registry save\n"
1342 " Save a registry file")
1348 N_("Dump a registry file"),
1349 N_("net rpc registry dump\n"
1350 " Dump a registry file")
1356 N_("Copy a registry file"),
1357 N_("net rpc registry copy\n"
1358 " Copy a registry file")
1364 N_("Get security descriptor"),
1365 N_("net rpc registry getsd\n"
1366 " Get security descriptior")
1368 {NULL
, NULL
, 0, NULL
, NULL
}
1371 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);