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"
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
)
38 ZERO_STRUCTP(reg_hnd
);
42 case HKEY_CLASSES_ROOT
:
43 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
44 access_mask
, reg_hnd
, NULL
);
46 case HKEY_LOCAL_MACHINE
:
47 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
48 access_mask
, reg_hnd
, NULL
);
51 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
52 access_mask
, reg_hnd
, NULL
);
54 case HKEY_CURRENT_USER
:
55 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
56 access_mask
, reg_hnd
, NULL
);
58 case HKEY_PERFORMANCE_DATA
:
59 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
60 access_mask
, reg_hnd
, NULL
);
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 err
= registry_pull_value(values
, &values
[i
], type
, data
,
356 data_size
, value_length
);
357 if (!W_ERROR_IS_OK(err
)) {
358 status
= werror_to_ntstatus(err
);
363 *pnum_values
= num_values
;
366 *pvalnames
= talloc_move(ctx
, &names
);
369 *pvalues
= talloc_move(ctx
, &values
);
372 status
= NT_STATUS_OK
;
375 TALLOC_FREE(mem_ctx
);
379 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
380 struct rpc_pipe_client
*pipe_hnd
,
381 struct policy_handle
*key_hnd
,
383 struct KeySecurityData
*sd
)
385 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
390 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
391 struct rpc_pipe_client
*pipe_hnd
,
392 struct policy_handle
*key_hnd
,
394 const struct registry_value
*value
)
396 struct winreg_String name_string
;
401 err
= registry_push_value(mem_ctx
, value
, &blob
);
402 if (!W_ERROR_IS_OK(err
)) {
403 return werror_to_ntstatus(err
);
406 ZERO_STRUCT(name_string
);
408 name_string
.name
= name
;
409 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
410 name_string
, value
->type
,
411 blob
.data
, blob
.length
, NULL
);
412 TALLOC_FREE(blob
.data
);
416 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
417 const struct dom_sid
*domain_sid
,
418 const char *domain_name
,
419 struct cli_state
*cli
,
420 struct rpc_pipe_client
*pipe_hnd
,
425 struct policy_handle hive_hnd
, key_hnd
;
427 struct registry_value value
;
429 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
430 SEC_FLAG_MAXIMUM_ALLOWED
,
431 &hive_hnd
, &key_hnd
);
432 if (!NT_STATUS_IS_OK(status
)) {
433 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
438 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
439 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
440 return NT_STATUS_NOT_IMPLEMENTED
;
443 if (strequal(argv
[2], "dword")) {
444 value
.type
= REG_DWORD
;
445 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
447 else if (strequal(argv
[2], "sz")) {
449 value
.v
.sz
.len
= strlen(argv
[3])+1;
450 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
453 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
454 status
= NT_STATUS_NOT_IMPLEMENTED
;
458 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
461 if (!NT_STATUS_IS_OK(status
)) {
462 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
467 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
468 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
473 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
476 if (argc
< 4 || c
->display_usage
) {
477 d_fprintf(stderr
, "%s\n%s",
479 _("net rpc registry setvalue <key> <valuename> "
480 "<type> [<val>]+\n"));
484 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
485 rpc_registry_setvalue_internal
, argc
, argv
);
488 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
489 const struct dom_sid
*domain_sid
,
490 const char *domain_name
,
491 struct cli_state
*cli
,
492 struct rpc_pipe_client
*pipe_hnd
,
497 struct policy_handle hive_hnd
, key_hnd
;
499 struct winreg_String valuename
;
501 ZERO_STRUCT(valuename
);
503 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
504 SEC_FLAG_MAXIMUM_ALLOWED
,
505 &hive_hnd
, &key_hnd
);
506 if (!NT_STATUS_IS_OK(status
)) {
507 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
512 valuename
.name
= argv
[1];
514 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
517 if (!NT_STATUS_IS_OK(status
)) {
518 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
522 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
523 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
528 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
531 if (argc
!= 2 || c
->display_usage
) {
532 d_fprintf(stderr
, "%s\n%s",
534 _("net rpc registry deletevalue <key> <valuename>\n"));
538 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
539 rpc_registry_deletevalue_internal
, argc
, argv
);
542 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
543 const struct dom_sid
*domain_sid
,
544 const char *domain_name
,
545 struct cli_state
*cli
,
546 struct rpc_pipe_client
*pipe_hnd
,
552 struct policy_handle hive_hnd
, key_hnd
;
555 struct winreg_String valuename
;
556 struct registry_value
*value
= NULL
;
557 enum winreg_Type type
= REG_NONE
;
558 uint8_t *data
= NULL
;
559 uint32_t data_size
= 0;
560 uint32_t value_length
= 0;
561 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
563 ZERO_STRUCT(valuename
);
565 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
566 SEC_FLAG_MAXIMUM_ALLOWED
,
567 &hive_hnd
, &key_hnd
);
568 if (!NT_STATUS_IS_OK(status
)) {
569 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
574 valuename
.name
= argv
[1];
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 data
= (uint8
*)TALLOC(tmp_ctx
, 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"),
612 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
613 data_size
, value_length
);
614 if (!W_ERROR_IS_OK(werr
)) {
615 status
= werror_to_ntstatus(werr
);
619 print_registry_value(value
, raw
);
622 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
623 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
625 TALLOC_FREE(tmp_ctx
);
630 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
631 const struct dom_sid
*domain_sid
,
632 const char *domain_name
,
633 struct cli_state
*cli
,
634 struct rpc_pipe_client
*pipe_hnd
,
639 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
640 cli
, pipe_hnd
, mem_ctx
, false,
644 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
647 if (argc
!= 2 || c
->display_usage
) {
648 d_fprintf(stderr
, "%s\n%s",
650 _("net rpc registry getvalue <key> <valuename>\n"));
654 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
655 rpc_registry_getvalue_full
, argc
, argv
);
658 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
659 const struct dom_sid
*domain_sid
,
660 const char *domain_name
,
661 struct cli_state
*cli
,
662 struct rpc_pipe_client
*pipe_hnd
,
667 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
668 cli
, pipe_hnd
, mem_ctx
, true,
672 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
675 if (argc
!= 2 || c
->display_usage
) {
676 d_fprintf(stderr
, "%s\n%s",
678 _("net rpc registry getvalue <key> <valuename>\n"));
682 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
683 rpc_registry_getvalue_raw
, argc
, argv
);
686 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
687 const struct dom_sid
*domain_sid
,
688 const char *domain_name
,
689 struct cli_state
*cli
,
690 struct rpc_pipe_client
*pipe_hnd
,
696 struct policy_handle hive_hnd
, key_hnd
;
697 struct winreg_String key
, keyclass
;
698 enum winreg_CreateAction action
;
702 ZERO_STRUCT(keyclass
);
704 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
705 return NT_STATUS_INVALID_PARAMETER
;
708 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
709 SEC_FLAG_MAXIMUM_ALLOWED
,
711 if (!(NT_STATUS_IS_OK(status
))) {
715 action
= REG_ACTION_NONE
;
718 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
719 keyclass
, 0, REG_KEY_READ
, NULL
,
720 &key_hnd
, &action
, NULL
);
721 if (!NT_STATUS_IS_OK(status
)) {
722 d_fprintf(stderr
, _("createkey returned %s\n"),
724 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
729 case REG_ACTION_NONE
:
730 d_printf(_("createkey did nothing -- huh?\n"));
732 case REG_CREATED_NEW_KEY
:
733 d_printf(_("createkey created %s\n"), argv
[0]);
735 case REG_OPENED_EXISTING_KEY
:
736 d_printf(_("createkey opened existing %s\n"), argv
[0]);
740 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
741 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
746 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
749 if (argc
!= 1 || c
->display_usage
) {
750 d_fprintf(stderr
, "%s\n%s",
752 _("net rpc registry createkey <key>\n"));
756 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
757 rpc_registry_createkey_internal
, argc
, argv
);
760 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
761 const struct dom_sid
*domain_sid
,
762 const char *domain_name
,
763 struct cli_state
*cli
,
764 struct rpc_pipe_client
*pipe_hnd
,
770 struct policy_handle hive_hnd
;
771 struct winreg_String key
;
776 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
777 return NT_STATUS_INVALID_PARAMETER
;
780 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
781 SEC_FLAG_MAXIMUM_ALLOWED
,
783 if (!(NT_STATUS_IS_OK(status
))) {
787 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
788 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
790 if (!NT_STATUS_IS_OK(status
)) {
791 d_fprintf(stderr
, _("deletekey returned %s\n"),
798 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
800 if (argc
!= 1 || c
->display_usage
) {
801 d_fprintf(stderr
, "%s\n%s",
803 _("net rpc registry deletekey <key>\n"));
807 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
808 rpc_registry_deletekey_internal
, argc
, argv
);
811 /********************************************************************
812 ********************************************************************/
814 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
815 const struct dom_sid
*domain_sid
,
816 const char *domain_name
,
817 struct cli_state
*cli
,
818 struct rpc_pipe_client
*pipe_hnd
,
823 struct policy_handle pol_hive
, pol_key
;
825 uint32 num_subkeys
= 0;
826 uint32 num_values
= 0;
827 char **names
= NULL
, **classes
= NULL
;
828 NTTIME
**modtimes
= NULL
;
830 struct registry_value
**values
= NULL
;
832 if (argc
!= 1 || c
->display_usage
) {
835 _("net rpc registry enumerate <path>\n"));
836 d_printf("%s net rpc registry enumerate "
837 "'HKLM\\Software\\Samba'\n", _("Example:"));
838 return NT_STATUS_INVALID_PARAMETER
;
841 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
842 &pol_hive
, &pol_key
);
843 if (!NT_STATUS_IS_OK(status
)) {
844 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
849 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
850 &names
, &classes
, &modtimes
);
851 if (!NT_STATUS_IS_OK(status
)) {
852 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
857 for (i
=0; i
<num_subkeys
; i
++) {
858 print_registry_key(names
[i
], modtimes
[i
]);
861 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
863 if (!NT_STATUS_IS_OK(status
)) {
864 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
869 for (i
=0; i
<num_values
; i
++) {
870 print_registry_value_with_name(names
[i
], values
[i
]);
873 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
874 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
879 /********************************************************************
880 ********************************************************************/
882 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
885 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
886 rpc_registry_enumerate_internal
, argc
, argv
);
889 /********************************************************************
890 ********************************************************************/
892 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
893 const struct dom_sid
*domain_sid
,
894 const char *domain_name
,
895 struct cli_state
*cli
,
896 struct rpc_pipe_client
*pipe_hnd
,
901 WERROR result
= WERR_GENERAL_FAILURE
;
902 struct policy_handle pol_hive
, pol_key
;
903 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
904 struct winreg_String filename
;
906 if (argc
!= 2 || c
->display_usage
) {
909 _("net rpc registry backup <path> <file> \n"));
910 return NT_STATUS_INVALID_PARAMETER
;
913 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
914 &pol_hive
, &pol_key
);
915 if (!NT_STATUS_IS_OK(status
)) {
916 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
921 filename
.name
= argv
[1];
922 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
923 if ( !W_ERROR_IS_OK(result
) ) {
924 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
925 cli
->desthost
, argv
[1]);
930 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
931 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
936 /********************************************************************
937 ********************************************************************/
939 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
941 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
942 rpc_registry_save_internal
, argc
, argv
);
946 /********************************************************************
947 ********************************************************************/
949 static void dump_values( REGF_NK_REC
*nk
)
952 const char *data_str
= NULL
;
953 uint32 data_size
, data
;
959 for ( i
=0; i
<nk
->num_values
; i
++ ) {
960 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
961 d_printf( "(%s) ", str_regtype( nk
->values
[i
].type
) );
963 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
964 switch ( nk
->values
[i
].type
) {
966 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
967 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
971 d_printf( "%s", data_str
);
975 for ( j
=0; j
<data_size
; j
++ ) {
976 d_printf( "%c", nk
->values
[i
].data
[j
] );
980 data
= IVAL( nk
->values
[i
].data
, 0 );
981 d_printf("0x%x", data
);
984 for ( j
=0; j
<data_size
; j
++ ) {
985 d_printf( "%x", nk
->values
[i
].data
[j
] );
989 d_printf(_("unknown"));
998 /********************************************************************
999 ********************************************************************/
1001 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
1005 /* depth first dump of the registry tree */
1007 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
1009 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
1012 d_printf("[%s]\n", regpath
);
1015 dump_registry_tree( file
, key
, regpath
);
1022 /********************************************************************
1023 ********************************************************************/
1025 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1026 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1027 const char *parentpath
)
1029 REGF_NK_REC
*key
, *subkey
;
1030 struct regval_ctr
*values
= NULL
;
1031 struct regsubkey_ctr
*subkeys
= NULL
;
1036 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1037 if (!W_ERROR_IS_OK(werr
)) {
1038 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1039 "%s\n", win_errstr(werr
)));
1043 werr
= regval_ctr_init(subkeys
, &values
);
1044 if (!W_ERROR_IS_OK(werr
)) {
1045 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1046 TALLOC_FREE(subkeys
);
1050 /* copy values into the struct regval_ctr */
1052 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1053 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1054 nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1057 /* copy subkeys into the struct regsubkey_ctr */
1059 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1060 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1063 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1065 /* write each one of the subkeys out */
1067 path
= talloc_asprintf(subkeys
,
1073 TALLOC_FREE(subkeys
);
1077 nk
->subkey_index
= 0;
1078 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1079 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1082 d_printf("[%s]\n", path
);
1083 TALLOC_FREE(subkeys
);
1088 /********************************************************************
1089 ********************************************************************/
1091 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1093 REGF_FILE
*registry
;
1096 if (argc
!= 1 || c
->display_usage
) {
1099 _("net rpc registry dump <file> \n"));
1103 d_printf(_("Opening %s...."), argv
[0]);
1104 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1105 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1108 d_printf(_("ok\n"));
1110 /* get the root of the registry file */
1112 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1113 d_fprintf(stderr
, _("Could not get rootkey\n"));
1114 regfio_close( registry
);
1117 d_printf("[%s]\n", nk
->keyname
);
1121 dump_registry_tree( registry
, nk
, nk
->keyname
);
1124 talloc_report_full( registry
->mem_ctx
, stderr
);
1126 d_printf(_("Closing registry..."));
1127 regfio_close( registry
);
1128 d_printf(_("ok\n"));
1133 /********************************************************************
1134 ********************************************************************/
1136 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1138 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1142 if (argc
!= 2 || c
->display_usage
) {
1145 _("net rpc registry copy <srcfile> <newfile>\n"));
1149 d_printf(_("Opening %s...."), argv
[0]);
1150 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1151 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1154 d_printf(_("ok\n"));
1156 d_printf(_("Opening %s...."), argv
[1]);
1157 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1158 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1161 d_printf(_("ok\n"));
1163 /* get the root of the registry file */
1165 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1166 d_fprintf(stderr
, _("Could not get rootkey\n"));
1169 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1171 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1177 d_printf(_("Closing %s..."), argv
[1]);
1179 regfio_close( outfile
);
1181 d_printf(_("ok\n"));
1183 d_printf(_("Closing %s..."), argv
[0]);
1185 regfio_close( infile
);
1187 d_printf(_("ok\n"));
1192 /********************************************************************
1193 ********************************************************************/
1195 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1196 const struct dom_sid
*domain_sid
,
1197 const char *domain_name
,
1198 struct cli_state
*cli
,
1199 struct rpc_pipe_client
*pipe_hnd
,
1200 TALLOC_CTX
*mem_ctx
,
1204 struct policy_handle pol_hive
, pol_key
;
1206 enum ndr_err_code ndr_err
;
1207 struct KeySecurityData
*sd
= NULL
;
1210 struct security_descriptor sec_desc
;
1211 uint32_t access_mask
= REG_KEY_READ
|
1212 SEC_FLAG_MAXIMUM_ALLOWED
|
1213 SEC_FLAG_SYSTEM_SECURITY
;
1215 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1218 _("net rpc registry getsd <path> <secinfo>\n"));
1219 d_printf("%s net rpc registry getsd "
1220 "'HKLM\\Software\\Samba'\n", _("Example:"));
1221 return NT_STATUS_INVALID_PARAMETER
;
1224 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1226 &pol_hive
, &pol_key
);
1227 if (!NT_STATUS_IS_OK(status
)) {
1228 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1233 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1235 status
= NT_STATUS_NO_MEMORY
;
1242 sscanf(argv
[1], "%x", &sec_info
);
1244 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1247 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1248 if (!NT_STATUS_IS_OK(status
)) {
1249 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1254 blob
.data
= sd
->data
;
1255 blob
.length
= sd
->size
;
1257 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1258 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1259 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1260 status
= ndr_map_error2ntstatus(ndr_err
);
1263 status
= NT_STATUS_OK
;
1265 display_sec_desc(&sec_desc
);
1268 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1269 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1275 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1277 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1278 rpc_registry_getsd_internal
, argc
, argv
);
1281 /********************************************************************
1282 ********************************************************************/
1284 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1286 struct functable func
[] = {
1289 rpc_registry_enumerate
,
1291 N_("Enumerate registry keys and values"),
1292 N_("net rpc registry enumerate\n"
1293 " Enumerate registry keys and values")
1297 rpc_registry_createkey
,
1299 N_("Create a new registry key"),
1300 N_("net rpc registry createkey\n"
1301 " Create a new registry key")
1305 rpc_registry_deletekey
,
1307 N_("Delete a registry key"),
1308 N_("net rpc registry deletekey\n"
1309 " Delete a registry key")
1313 rpc_registry_getvalue
,
1315 N_("Print a registry value"),
1316 N_("net rpc registry getvalue\n"
1317 " Print a registry value")
1321 rpc_registry_getvalueraw
,
1323 N_("Print a registry value"),
1324 N_("net rpc registry getvalueraw\n"
1325 " Print a registry value (raw version)")
1329 rpc_registry_setvalue
,
1331 N_("Set a new registry value"),
1332 N_("net rpc registry setvalue\n"
1333 " Set a new registry value")
1337 rpc_registry_deletevalue
,
1339 N_("Delete a registry value"),
1340 N_("net rpc registry deletevalue\n"
1341 " Delete a registry value")
1347 N_("Save a registry file"),
1348 N_("net rpc registry save\n"
1349 " Save a registry file")
1355 N_("Dump a registry file"),
1356 N_("net rpc registry dump\n"
1357 " Dump a registry file")
1363 N_("Copy a registry file"),
1364 N_("net rpc registry copy\n"
1365 " Copy a registry file")
1371 N_("Get security descriptor"),
1372 N_("net rpc registry getsd\n"
1373 " Get security descriptior")
1375 {NULL
, NULL
, 0, NULL
, NULL
}
1378 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);