2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "popt_common.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
30 /*******************************************************************
31 connect to a registry hive root (open a registry policy)
32 *******************************************************************/
34 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
35 uint32_t reg_type
, uint32_t access_mask
,
36 struct policy_handle
*reg_hnd
, WERROR
*werr
)
38 ZERO_STRUCTP(reg_hnd
);
42 case HKEY_CLASSES_ROOT
:
43 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
44 access_mask
, reg_hnd
, werr
);
46 case HKEY_LOCAL_MACHINE
:
47 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
48 access_mask
, reg_hnd
, werr
);
51 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
52 access_mask
, reg_hnd
, werr
);
54 case HKEY_CURRENT_USER
:
55 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
56 access_mask
, reg_hnd
, werr
);
58 case HKEY_PERFORMANCE_DATA
:
59 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
60 access_mask
, reg_hnd
, werr
);
63 /* fall through to end of function */
67 return NT_STATUS_INVALID_PARAMETER
;
70 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
71 uint32
*reg_type
, const char **key_name
)
74 char *hivename
= NULL
;
75 char *tmp_keyname
= NULL
;
77 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
79 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
80 if (!W_ERROR_IS_OK(werr
)) {
84 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
85 if (*key_name
== NULL
) {
89 if (strequal(hivename
, "HKLM") ||
90 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
92 (*reg_type
) = HKEY_LOCAL_MACHINE
;
93 } else if (strequal(hivename
, "HKCR") ||
94 strequal(hivename
, "HKEY_CLASSES_ROOT"))
96 (*reg_type
) = HKEY_CLASSES_ROOT
;
97 } else if (strequal(hivename
, "HKU") ||
98 strequal(hivename
, "HKEY_USERS"))
100 (*reg_type
) = HKEY_USERS
;
101 } else if (strequal(hivename
, "HKCU") ||
102 strequal(hivename
, "HKEY_CURRENT_USER"))
104 (*reg_type
) = HKEY_CURRENT_USER
;
105 } else if (strequal(hivename
, "HKPD") ||
106 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
108 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
110 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
118 TALLOC_FREE(tmp_ctx
);
122 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
123 struct rpc_pipe_client
*pipe_hnd
,
124 const char *name
, uint32 access_mask
,
125 struct policy_handle
*hive_hnd
,
126 struct policy_handle
*key_hnd
)
130 struct winreg_String key
;
134 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
135 return NT_STATUS_INVALID_PARAMETER
;
138 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
140 if (!(NT_STATUS_IS_OK(status
))) {
144 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
145 access_mask
, key_hnd
, NULL
);
146 if (!(NT_STATUS_IS_OK(status
))) {
147 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
154 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
155 struct rpc_pipe_client
*pipe_hnd
,
156 struct policy_handle
*key_hnd
,
157 uint32
*pnum_keys
, char ***pnames
,
158 char ***pclasses
, NTTIME
***pmodtimes
)
162 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
163 uint32 num_values
, max_valnamelen
, max_valbufsize
;
165 NTTIME last_changed_time
;
167 struct winreg_String classname
;
168 char **names
, **classes
;
171 if (!(mem_ctx
= talloc_new(ctx
))) {
172 return NT_STATUS_NO_MEMORY
;
175 ZERO_STRUCT(classname
);
176 status
= rpccli_winreg_QueryInfoKey(
177 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
178 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
179 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
181 if (!NT_STATUS_IS_OK(status
)) {
185 if (num_subkeys
== 0) {
187 TALLOC_FREE(mem_ctx
);
191 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
192 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
193 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
195 status
= NT_STATUS_NO_MEMORY
;
199 for (i
=0; i
<num_subkeys
; i
++) {
201 struct winreg_StringBuf class_buf
;
202 struct winreg_StringBuf name_buf
;
208 class_buf
.size
= max_classlen
+2;
212 name_buf
.size
= max_subkeylen
+2;
214 ZERO_STRUCT(modtime
);
216 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
217 i
, &name_buf
, &class_buf
,
220 if (W_ERROR_EQUAL(werr
,
221 WERR_NO_MORE_ITEMS
) ) {
222 status
= NT_STATUS_OK
;
225 if (!NT_STATUS_IS_OK(status
)) {
231 if (class_buf
.name
&&
232 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
233 status
= NT_STATUS_NO_MEMORY
;
237 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
238 status
= NT_STATUS_NO_MEMORY
;
242 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
243 modtimes
, &modtime
, sizeof(modtime
))))) {
244 status
= NT_STATUS_NO_MEMORY
;
249 *pnum_keys
= num_subkeys
;
252 *pnames
= talloc_move(ctx
, &names
);
255 *pclasses
= talloc_move(ctx
, &classes
);
258 *pmodtimes
= talloc_move(ctx
, &modtimes
);
261 status
= NT_STATUS_OK
;
264 TALLOC_FREE(mem_ctx
);
268 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
269 struct rpc_pipe_client
*pipe_hnd
,
270 struct policy_handle
*key_hnd
,
271 uint32
*pnum_values
, char ***pvalnames
,
272 struct registry_value
***pvalues
)
276 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
277 uint32 num_values
, max_valnamelen
, max_valbufsize
;
279 NTTIME last_changed_time
;
281 struct winreg_String classname
;
282 struct registry_value
**values
;
285 if (!(mem_ctx
= talloc_new(ctx
))) {
286 return NT_STATUS_NO_MEMORY
;
289 ZERO_STRUCT(classname
);
290 status
= rpccli_winreg_QueryInfoKey(
291 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
292 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
293 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
295 if (!NT_STATUS_IS_OK(status
)) {
299 if (num_values
== 0) {
301 TALLOC_FREE(mem_ctx
);
305 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
306 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
308 status
= NT_STATUS_NO_MEMORY
;
312 for (i
=0; i
<num_values
; i
++) {
313 enum winreg_Type type
= REG_NONE
;
319 struct winreg_ValNameBuf name_buf
;
324 name_buf
.size
= max_valnamelen
+ 2;
326 data_size
= max_valbufsize
;
327 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
330 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
333 &value_length
, &err
);
335 if ( W_ERROR_EQUAL(err
,
336 WERR_NO_MORE_ITEMS
) ) {
337 status
= NT_STATUS_OK
;
341 if (!(NT_STATUS_IS_OK(status
))) {
345 if (name_buf
.name
== NULL
) {
346 status
= NT_STATUS_INVALID_PARAMETER
;
350 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
351 status
= NT_STATUS_NO_MEMORY
;
355 values
[i
] = talloc_zero(values
, struct registry_value
);
356 if (values
[i
] == NULL
) {
357 status
= NT_STATUS_NO_MEMORY
;
361 values
[i
]->type
= type
;
362 values
[i
]->data
= data_blob_talloc(values
[i
], data
, data_size
);
365 *pnum_values
= num_values
;
368 *pvalnames
= talloc_move(ctx
, &names
);
371 *pvalues
= talloc_move(ctx
, &values
);
374 status
= NT_STATUS_OK
;
377 TALLOC_FREE(mem_ctx
);
381 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
382 struct rpc_pipe_client
*pipe_hnd
,
383 struct policy_handle
*key_hnd
,
385 struct KeySecurityData
*sd
)
387 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
392 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
393 struct rpc_pipe_client
*pipe_hnd
,
394 struct policy_handle
*key_hnd
,
396 const struct registry_value
*value
)
398 struct winreg_String name_string
;
401 ZERO_STRUCT(name_string
);
403 name_string
.name
= name
;
404 result
= rpccli_winreg_SetValue(pipe_hnd
, mem_ctx
, key_hnd
,
405 name_string
, value
->type
,
406 value
->data
.data
, value
->data
.length
, NULL
);
410 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
411 const struct dom_sid
*domain_sid
,
412 const char *domain_name
,
413 struct cli_state
*cli
,
414 struct rpc_pipe_client
*pipe_hnd
,
419 struct policy_handle hive_hnd
, key_hnd
;
421 struct registry_value value
;
423 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
424 SEC_FLAG_MAXIMUM_ALLOWED
,
425 &hive_hnd
, &key_hnd
);
426 if (!NT_STATUS_IS_OK(status
)) {
427 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
432 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
433 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
434 return NT_STATUS_NOT_IMPLEMENTED
;
437 if (strequal(argv
[2], "dword")) {
438 uint32_t v
= strtoul(argv
[3], NULL
, 10);
439 value
.type
= REG_DWORD
;
440 value
.data
= data_blob_talloc(mem_ctx
, NULL
, 4);
441 SIVAL(value
.data
.data
, 0, v
);
443 else if (strequal(argv
[2], "sz")) {
445 if (!push_reg_sz(mem_ctx
, &value
.data
, argv
[3])) {
446 status
= NT_STATUS_NO_MEMORY
;
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
;
552 struct winreg_String valuename
;
553 struct registry_value
*value
= NULL
;
554 enum winreg_Type type
= REG_NONE
;
555 uint32_t data_size
= 0;
556 uint32_t value_length
= 0;
557 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
559 ZERO_STRUCT(valuename
);
561 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
562 SEC_FLAG_MAXIMUM_ALLOWED
,
563 &hive_hnd
, &key_hnd
);
564 if (!NT_STATUS_IS_OK(status
)) {
565 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
570 valuename
.name
= argv
[1];
572 value
= talloc_zero(tmp_ctx
, struct registry_value
);
574 return NT_STATUS_NO_MEMORY
;
578 * call QueryValue once with data == NULL to get the
579 * needed memory size to be allocated, then allocate
580 * data buffer and call again.
582 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
590 if (!NT_STATUS_IS_OK(status
)) {
591 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
596 value
->data
= data_blob_talloc(tmp_ctx
, NULL
, data_size
);
598 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
606 if (!NT_STATUS_IS_OK(status
)) {
607 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
614 print_registry_value(value
, raw
);
617 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
618 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
620 TALLOC_FREE(tmp_ctx
);
625 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
626 const struct dom_sid
*domain_sid
,
627 const char *domain_name
,
628 struct cli_state
*cli
,
629 struct rpc_pipe_client
*pipe_hnd
,
634 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
635 cli
, pipe_hnd
, mem_ctx
, false,
639 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
642 if (argc
!= 2 || c
->display_usage
) {
643 d_fprintf(stderr
, "%s\n%s",
645 _("net rpc registry getvalue <key> <valuename>\n"));
649 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
650 rpc_registry_getvalue_full
, argc
, argv
);
653 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
654 const struct dom_sid
*domain_sid
,
655 const char *domain_name
,
656 struct cli_state
*cli
,
657 struct rpc_pipe_client
*pipe_hnd
,
662 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
663 cli
, pipe_hnd
, mem_ctx
, true,
667 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
670 if (argc
!= 2 || c
->display_usage
) {
671 d_fprintf(stderr
, "%s\n%s",
673 _("net rpc registry getvalue <key> <valuename>\n"));
677 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
678 rpc_registry_getvalue_raw
, argc
, argv
);
681 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
682 const struct dom_sid
*domain_sid
,
683 const char *domain_name
,
684 struct cli_state
*cli
,
685 struct rpc_pipe_client
*pipe_hnd
,
691 struct policy_handle hive_hnd
, key_hnd
;
692 struct winreg_String key
, keyclass
;
693 enum winreg_CreateAction action
;
697 ZERO_STRUCT(keyclass
);
699 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
700 return NT_STATUS_INVALID_PARAMETER
;
703 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
704 SEC_FLAG_MAXIMUM_ALLOWED
,
706 if (!(NT_STATUS_IS_OK(status
))) {
710 action
= REG_ACTION_NONE
;
713 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
714 keyclass
, 0, REG_KEY_READ
, NULL
,
715 &key_hnd
, &action
, NULL
);
716 if (!NT_STATUS_IS_OK(status
)) {
717 d_fprintf(stderr
, _("createkey returned %s\n"),
719 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
724 case REG_ACTION_NONE
:
725 d_printf(_("createkey did nothing -- huh?\n"));
727 case REG_CREATED_NEW_KEY
:
728 d_printf(_("createkey created %s\n"), argv
[0]);
730 case REG_OPENED_EXISTING_KEY
:
731 d_printf(_("createkey opened existing %s\n"), argv
[0]);
735 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
736 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
741 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
744 if (argc
!= 1 || c
->display_usage
) {
745 d_fprintf(stderr
, "%s\n%s",
747 _("net rpc registry createkey <key>\n"));
751 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
752 rpc_registry_createkey_internal
, argc
, argv
);
755 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
756 const struct dom_sid
*domain_sid
,
757 const char *domain_name
,
758 struct cli_state
*cli
,
759 struct rpc_pipe_client
*pipe_hnd
,
765 struct policy_handle hive_hnd
;
766 struct winreg_String key
;
771 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
772 return NT_STATUS_INVALID_PARAMETER
;
775 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
776 SEC_FLAG_MAXIMUM_ALLOWED
,
778 if (!(NT_STATUS_IS_OK(status
))) {
782 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
783 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
785 if (!NT_STATUS_IS_OK(status
)) {
786 d_fprintf(stderr
, _("deletekey returned %s\n"),
793 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
795 if (argc
!= 1 || c
->display_usage
) {
796 d_fprintf(stderr
, "%s\n%s",
798 _("net rpc registry deletekey <key>\n"));
802 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
803 rpc_registry_deletekey_internal
, argc
, argv
);
806 /********************************************************************
807 ********************************************************************/
809 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
810 const struct dom_sid
*domain_sid
,
811 const char *domain_name
,
812 struct cli_state
*cli
,
813 struct rpc_pipe_client
*pipe_hnd
,
818 struct policy_handle pol_hive
, pol_key
;
820 uint32 num_subkeys
= 0;
821 uint32 num_values
= 0;
822 char **names
= NULL
, **classes
= NULL
;
823 NTTIME
**modtimes
= NULL
;
825 struct registry_value
**values
= NULL
;
827 if (argc
!= 1 || c
->display_usage
) {
830 _("net rpc registry enumerate <path>\n"));
831 d_printf("%s net rpc registry enumerate "
832 "'HKLM\\Software\\Samba'\n", _("Example:"));
833 return NT_STATUS_INVALID_PARAMETER
;
836 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
837 &pol_hive
, &pol_key
);
838 if (!NT_STATUS_IS_OK(status
)) {
839 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
844 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
845 &names
, &classes
, &modtimes
);
846 if (!NT_STATUS_IS_OK(status
)) {
847 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
852 for (i
=0; i
<num_subkeys
; i
++) {
853 print_registry_key(names
[i
], modtimes
[i
]);
856 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
858 if (!NT_STATUS_IS_OK(status
)) {
859 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
864 for (i
=0; i
<num_values
; i
++) {
865 print_registry_value_with_name(names
[i
], values
[i
]);
868 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
869 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
874 /********************************************************************
875 ********************************************************************/
877 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
880 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
881 rpc_registry_enumerate_internal
, argc
, argv
);
884 /********************************************************************
885 ********************************************************************/
887 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
888 const struct dom_sid
*domain_sid
,
889 const char *domain_name
,
890 struct cli_state
*cli
,
891 struct rpc_pipe_client
*pipe_hnd
,
896 WERROR result
= WERR_GENERAL_FAILURE
;
897 struct policy_handle pol_hive
, pol_key
;
898 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
899 struct winreg_String filename
;
901 if (argc
!= 2 || c
->display_usage
) {
904 _("net rpc registry backup <path> <file> \n"));
905 return NT_STATUS_INVALID_PARAMETER
;
908 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
909 &pol_hive
, &pol_key
);
910 if (!NT_STATUS_IS_OK(status
)) {
911 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
916 filename
.name
= argv
[1];
917 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
918 if ( !W_ERROR_IS_OK(result
) ) {
919 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
920 cli
->desthost
, argv
[1]);
925 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
926 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
931 /********************************************************************
932 ********************************************************************/
934 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
936 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
937 rpc_registry_save_internal
, argc
, argv
);
941 /********************************************************************
942 ********************************************************************/
944 static void dump_values( REGF_NK_REC
*nk
)
947 const char *data_str
= NULL
;
948 uint32 data_size
, data
;
954 for ( i
=0; i
<nk
->num_values
; i
++ ) {
955 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
956 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
958 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
959 switch ( nk
->values
[i
].type
) {
961 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
962 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
966 d_printf( "%s", data_str
);
970 for ( j
=0; j
<data_size
; j
++ ) {
971 d_printf( "%c", nk
->values
[i
].data
[j
] );
975 data
= IVAL( nk
->values
[i
].data
, 0 );
976 d_printf("0x%x", data
);
979 for ( j
=0; j
<data_size
; j
++ ) {
980 d_printf( "%x", nk
->values
[i
].data
[j
] );
984 d_printf(_("unknown"));
993 /********************************************************************
994 ********************************************************************/
996 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
1000 /* depth first dump of the registry tree */
1002 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1004 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1007 d_printf("[%s]\n", regpath
);
1010 dump_registry_tree( file
, key
, regpath
);
1017 /********************************************************************
1018 ********************************************************************/
1020 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1021 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1022 const char *parentpath
)
1024 REGF_NK_REC
*key
, *subkey
;
1025 struct regval_ctr
*values
= NULL
;
1026 struct regsubkey_ctr
*subkeys
= NULL
;
1031 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1032 if (!W_ERROR_IS_OK(werr
)) {
1033 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1034 "%s\n", win_errstr(werr
)));
1038 werr
= regval_ctr_init(subkeys
, &values
);
1039 if (!W_ERROR_IS_OK(werr
)) {
1040 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1041 TALLOC_FREE(subkeys
);
1045 /* copy values into the struct regval_ctr */
1047 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1048 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1049 nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1052 /* copy subkeys into the struct regsubkey_ctr */
1054 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1055 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1058 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1060 /* write each one of the subkeys out */
1062 path
= talloc_asprintf(subkeys
,
1068 TALLOC_FREE(subkeys
);
1072 nk
->subkey_index
= 0;
1073 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1074 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1077 d_printf("[%s]\n", path
);
1078 TALLOC_FREE(subkeys
);
1083 /********************************************************************
1084 ********************************************************************/
1086 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1088 REGF_FILE
*registry
;
1091 if (argc
!= 1 || c
->display_usage
) {
1094 _("net rpc registry dump <file> \n"));
1098 d_printf(_("Opening %s...."), argv
[0]);
1099 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1100 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1103 d_printf(_("ok\n"));
1105 /* get the root of the registry file */
1107 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1108 d_fprintf(stderr
, _("Could not get rootkey\n"));
1109 regfio_close( registry
);
1112 d_printf("[%s]\n", nk
->keyname
);
1116 dump_registry_tree( registry
, nk
, nk
->keyname
);
1119 talloc_report_full( registry
->mem_ctx
, stderr
);
1121 d_printf(_("Closing registry..."));
1122 regfio_close( registry
);
1123 d_printf(_("ok\n"));
1128 /********************************************************************
1129 ********************************************************************/
1131 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1133 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1137 if (argc
!= 2 || c
->display_usage
) {
1140 _("net rpc registry copy <srcfile> <newfile>\n"));
1144 d_printf(_("Opening %s...."), argv
[0]);
1145 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1146 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1149 d_printf(_("ok\n"));
1151 d_printf(_("Opening %s...."), argv
[1]);
1152 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
),
1153 (S_IRUSR
|S_IWUSR
) )) ) {
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 struct 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
= SEC_FLAG_MAXIMUM_ALLOWED
|
1208 SEC_FLAG_SYSTEM_SECURITY
;
1210 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1213 _("net rpc registry getsd <path> <secinfo>\n"));
1214 d_printf("%s net rpc registry getsd "
1215 "'HKLM\\Software\\Samba'\n", _("Example:"));
1216 return NT_STATUS_INVALID_PARAMETER
;
1219 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1221 &pol_hive
, &pol_key
);
1222 if (!NT_STATUS_IS_OK(status
)) {
1223 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1228 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1230 status
= NT_STATUS_NO_MEMORY
;
1237 sscanf(argv
[1], "%x", &sec_info
);
1239 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1242 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1243 if (!NT_STATUS_IS_OK(status
)) {
1244 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1249 blob
.data
= sd
->data
;
1250 blob
.length
= sd
->size
;
1252 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1253 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1254 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1255 status
= ndr_map_error2ntstatus(ndr_err
);
1258 status
= NT_STATUS_OK
;
1260 display_sec_desc(&sec_desc
);
1263 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1264 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1270 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1272 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1273 rpc_registry_getsd_internal
, argc
, argv
);
1276 /********************************************************************
1277 ********************************************************************/
1279 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1281 struct functable func
[] = {
1284 rpc_registry_enumerate
,
1286 N_("Enumerate registry keys and values"),
1287 N_("net rpc registry enumerate\n"
1288 " Enumerate registry keys and values")
1292 rpc_registry_createkey
,
1294 N_("Create a new registry key"),
1295 N_("net rpc registry createkey\n"
1296 " Create a new registry key")
1300 rpc_registry_deletekey
,
1302 N_("Delete a registry key"),
1303 N_("net rpc registry deletekey\n"
1304 " Delete a registry key")
1308 rpc_registry_getvalue
,
1310 N_("Print a registry value"),
1311 N_("net rpc registry getvalue\n"
1312 " Print a registry value")
1316 rpc_registry_getvalueraw
,
1318 N_("Print a registry value"),
1319 N_("net rpc registry getvalueraw\n"
1320 " Print a registry value (raw version)")
1324 rpc_registry_setvalue
,
1326 N_("Set a new registry value"),
1327 N_("net rpc registry setvalue\n"
1328 " Set a new registry value")
1332 rpc_registry_deletevalue
,
1334 N_("Delete a registry value"),
1335 N_("net rpc registry deletevalue\n"
1336 " Delete a registry value")
1342 N_("Save a registry file"),
1343 N_("net rpc registry save\n"
1344 " Save a registry file")
1350 N_("Dump a registry file"),
1351 N_("net rpc registry dump\n"
1352 " Dump a registry file")
1358 N_("Copy a registry file"),
1359 N_("net rpc registry copy\n"
1360 " Copy a registry file")
1366 N_("Get security descriptor"),
1367 N_("net rpc registry getsd\n"
1368 " Get security descriptior")
1370 {NULL
, NULL
, 0, NULL
, NULL
}
1373 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);