2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "utils/net.h"
22 #include "utils/net_registry_util.h"
24 #include "reg_objects.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 /*******************************************************************
28 connect to a registry hive root (open a registry policy)
29 *******************************************************************/
31 static NTSTATUS
rpccli_winreg_Connect(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
32 uint32_t reg_type
, uint32_t access_mask
,
33 struct policy_handle
*reg_hnd
)
35 ZERO_STRUCTP(reg_hnd
);
39 case HKEY_CLASSES_ROOT
:
40 return rpccli_winreg_OpenHKCR( cli
, mem_ctx
, NULL
,
41 access_mask
, reg_hnd
, NULL
);
43 case HKEY_LOCAL_MACHINE
:
44 return rpccli_winreg_OpenHKLM( cli
, mem_ctx
, NULL
,
45 access_mask
, reg_hnd
, NULL
);
48 return rpccli_winreg_OpenHKU( cli
, mem_ctx
, NULL
,
49 access_mask
, reg_hnd
, NULL
);
51 case HKEY_CURRENT_USER
:
52 return rpccli_winreg_OpenHKCU( cli
, mem_ctx
, NULL
,
53 access_mask
, reg_hnd
, NULL
);
55 case HKEY_PERFORMANCE_DATA
:
56 return rpccli_winreg_OpenHKPD( cli
, mem_ctx
, NULL
,
57 access_mask
, reg_hnd
, NULL
);
60 /* fall through to end of function */
64 return NT_STATUS_INVALID_PARAMETER
;
67 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
68 uint32
*reg_type
, const char **key_name
)
71 char *hivename
= NULL
;
72 char *tmp_keyname
= NULL
;
74 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
76 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
77 if (!W_ERROR_IS_OK(werr
)) {
81 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
82 if (*key_name
== NULL
) {
86 if (strequal(hivename
, "HKLM") ||
87 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
89 (*reg_type
) = HKEY_LOCAL_MACHINE
;
90 } else if (strequal(hivename
, "HKCR") ||
91 strequal(hivename
, "HKEY_CLASSES_ROOT"))
93 (*reg_type
) = HKEY_CLASSES_ROOT
;
94 } else if (strequal(hivename
, "HKU") ||
95 strequal(hivename
, "HKEY_USERS"))
97 (*reg_type
) = HKEY_USERS
;
98 } else if (strequal(hivename
, "HKCU") ||
99 strequal(hivename
, "HKEY_CURRENT_USER"))
101 (*reg_type
) = HKEY_CURRENT_USER
;
102 } else if (strequal(hivename
, "HKPD") ||
103 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
105 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
107 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
115 TALLOC_FREE(tmp_ctx
);
119 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
120 struct rpc_pipe_client
*pipe_hnd
,
121 const char *name
, uint32 access_mask
,
122 struct policy_handle
*hive_hnd
,
123 struct policy_handle
*key_hnd
)
127 struct winreg_String key
;
131 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
132 return NT_STATUS_INVALID_PARAMETER
;
135 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
137 if (!(NT_STATUS_IS_OK(status
))) {
141 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
142 access_mask
, key_hnd
, NULL
);
143 if (!(NT_STATUS_IS_OK(status
))) {
144 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
151 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
152 struct rpc_pipe_client
*pipe_hnd
,
153 struct policy_handle
*key_hnd
,
154 uint32
*pnum_keys
, char ***pnames
,
155 char ***pclasses
, NTTIME
***pmodtimes
)
159 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
160 uint32 num_values
, max_valnamelen
, max_valbufsize
;
162 NTTIME last_changed_time
;
164 struct winreg_String classname
;
165 char **names
, **classes
;
168 if (!(mem_ctx
= talloc_new(ctx
))) {
169 return NT_STATUS_NO_MEMORY
;
172 ZERO_STRUCT(classname
);
173 status
= rpccli_winreg_QueryInfoKey(
174 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
175 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
176 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
178 if (!NT_STATUS_IS_OK(status
)) {
182 if (num_subkeys
== 0) {
184 TALLOC_FREE(mem_ctx
);
188 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
189 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
190 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
192 status
= NT_STATUS_NO_MEMORY
;
196 for (i
=0; i
<num_subkeys
; i
++) {
198 struct winreg_StringBuf class_buf
;
199 struct winreg_StringBuf name_buf
;
205 class_buf
.size
= max_classlen
+2;
209 name_buf
.size
= max_subkeylen
+2;
211 ZERO_STRUCT(modtime
);
213 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
214 i
, &name_buf
, &class_buf
,
217 if (W_ERROR_EQUAL(werr
,
218 WERR_NO_MORE_ITEMS
) ) {
219 status
= NT_STATUS_OK
;
222 if (!NT_STATUS_IS_OK(status
)) {
228 if (class_buf
.name
&&
229 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
230 status
= NT_STATUS_NO_MEMORY
;
234 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
235 status
= NT_STATUS_NO_MEMORY
;
239 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
240 modtimes
, &modtime
, sizeof(modtime
))))) {
241 status
= NT_STATUS_NO_MEMORY
;
246 *pnum_keys
= num_subkeys
;
249 *pnames
= talloc_move(ctx
, &names
);
252 *pclasses
= talloc_move(ctx
, &classes
);
255 *pmodtimes
= talloc_move(ctx
, &modtimes
);
258 status
= NT_STATUS_OK
;
261 TALLOC_FREE(mem_ctx
);
265 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
266 struct rpc_pipe_client
*pipe_hnd
,
267 struct policy_handle
*key_hnd
,
268 uint32
*pnum_values
, char ***pvalnames
,
269 struct registry_value
***pvalues
)
273 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
274 uint32 num_values
, max_valnamelen
, max_valbufsize
;
276 NTTIME last_changed_time
;
278 struct winreg_String classname
;
279 struct registry_value
**values
;
282 if (!(mem_ctx
= talloc_new(ctx
))) {
283 return NT_STATUS_NO_MEMORY
;
286 ZERO_STRUCT(classname
);
287 status
= rpccli_winreg_QueryInfoKey(
288 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
289 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
290 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
292 if (!NT_STATUS_IS_OK(status
)) {
296 if (num_values
== 0) {
298 TALLOC_FREE(mem_ctx
);
302 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
303 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
305 status
= NT_STATUS_NO_MEMORY
;
309 for (i
=0; i
<num_values
; i
++) {
310 enum winreg_Type type
= REG_NONE
;
316 struct winreg_ValNameBuf name_buf
;
321 name_buf
.size
= max_valnamelen
+ 2;
323 data_size
= max_valbufsize
;
324 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
327 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
330 &value_length
, &err
);
332 if ( W_ERROR_EQUAL(err
,
333 WERR_NO_MORE_ITEMS
) ) {
334 status
= NT_STATUS_OK
;
338 if (!(NT_STATUS_IS_OK(status
))) {
342 if (name_buf
.name
== NULL
) {
343 status
= NT_STATUS_INVALID_PARAMETER
;
347 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
348 status
= NT_STATUS_NO_MEMORY
;
352 err
= registry_pull_value(values
, &values
[i
], type
, data
,
353 data_size
, value_length
);
354 if (!W_ERROR_IS_OK(err
)) {
355 status
= werror_to_ntstatus(err
);
360 *pnum_values
= num_values
;
363 *pvalnames
= talloc_move(ctx
, &names
);
366 *pvalues
= talloc_move(ctx
, &values
);
369 status
= NT_STATUS_OK
;
372 TALLOC_FREE(mem_ctx
);
376 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
377 struct rpc_pipe_client
*pipe_hnd
,
378 struct policy_handle
*key_hnd
,
380 struct KeySecurityData
*sd
)
382 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
387 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
388 struct rpc_pipe_client
*pipe_hnd
,
389 struct policy_handle
*key_hnd
,
391 const struct registry_value
*value
)
393 struct winreg_String name_string
;
398 err
= registry_push_value(mem_ctx
, value
, &blob
);
399 if (!W_ERROR_IS_OK(err
)) {
400 return werror_to_ntstatus(err
);
403 ZERO_STRUCT(name_string
);
405 name_string
.name
= name
;
406 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
407 name_string
, value
->type
,
408 blob
.data
, blob
.length
, NULL
);
409 TALLOC_FREE(blob
.data
);
413 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
414 const DOM_SID
*domain_sid
,
415 const char *domain_name
,
416 struct cli_state
*cli
,
417 struct rpc_pipe_client
*pipe_hnd
,
422 struct policy_handle hive_hnd
, key_hnd
;
424 struct registry_value value
;
426 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
427 SEC_FLAG_MAXIMUM_ALLOWED
,
428 &hive_hnd
, &key_hnd
);
429 if (!NT_STATUS_IS_OK(status
)) {
430 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
435 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
436 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
437 return NT_STATUS_NOT_IMPLEMENTED
;
440 if (strequal(argv
[2], "dword")) {
441 value
.type
= REG_DWORD
;
442 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
444 else if (strequal(argv
[2], "sz")) {
446 value
.v
.sz
.len
= strlen(argv
[3])+1;
447 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
450 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
451 status
= NT_STATUS_NOT_IMPLEMENTED
;
455 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
458 if (!NT_STATUS_IS_OK(status
)) {
459 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
464 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
465 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
470 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
473 if (argc
< 4 || c
->display_usage
) {
474 d_fprintf(stderr
, _("usage:"),_(" net rpc registry setvalue <key> "
475 "<valuename> <type> [<val>]+\n"));
479 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
480 rpc_registry_setvalue_internal
, argc
, argv
);
483 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
484 const DOM_SID
*domain_sid
,
485 const char *domain_name
,
486 struct cli_state
*cli
,
487 struct rpc_pipe_client
*pipe_hnd
,
492 struct policy_handle hive_hnd
, key_hnd
;
494 struct winreg_String valuename
;
496 ZERO_STRUCT(valuename
);
498 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
499 SEC_FLAG_MAXIMUM_ALLOWED
,
500 &hive_hnd
, &key_hnd
);
501 if (!NT_STATUS_IS_OK(status
)) {
502 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
507 valuename
.name
= argv
[1];
509 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
512 if (!NT_STATUS_IS_OK(status
)) {
513 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
517 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
518 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
523 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
526 if (argc
!= 2 || c
->display_usage
) {
527 d_fprintf(stderr
, _("usage:"),_(" net rpc registry deletevalue <key> "
532 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
533 rpc_registry_deletevalue_internal
, argc
, argv
);
536 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
537 const DOM_SID
*domain_sid
,
538 const char *domain_name
,
539 struct cli_state
*cli
,
540 struct rpc_pipe_client
*pipe_hnd
,
546 struct policy_handle hive_hnd
, key_hnd
;
549 struct winreg_String valuename
;
550 struct registry_value
*value
= NULL
;
551 enum winreg_Type type
= REG_NONE
;
552 uint8_t *data
= NULL
;
553 uint32_t data_size
= 0;
554 uint32_t value_length
= 0;
555 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
557 ZERO_STRUCT(valuename
);
559 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
560 SEC_FLAG_MAXIMUM_ALLOWED
,
561 &hive_hnd
, &key_hnd
);
562 if (!NT_STATUS_IS_OK(status
)) {
563 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
568 valuename
.name
= argv
[1];
571 * call QueryValue once with data == NULL to get the
572 * needed memory size to be allocated, then allocate
573 * data buffer and call again.
575 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
583 if (!NT_STATUS_IS_OK(status
)) {
584 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
589 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
592 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
600 if (!NT_STATUS_IS_OK(status
)) {
601 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
606 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
607 data_size
, value_length
);
608 if (!W_ERROR_IS_OK(werr
)) {
609 status
= werror_to_ntstatus(werr
);
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 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
, _("usage:"),_(" net rpc registry getvalue <key> "
647 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
648 rpc_registry_getvalue_full
, argc
, argv
);
651 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
652 const DOM_SID
*domain_sid
,
653 const char *domain_name
,
654 struct cli_state
*cli
,
655 struct rpc_pipe_client
*pipe_hnd
,
660 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
661 cli
, pipe_hnd
, mem_ctx
, true,
665 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
668 if (argc
!= 2 || c
->display_usage
) {
669 d_fprintf(stderr
, _("usage:"),_(" net rpc registry getvalue <key> "
674 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
675 rpc_registry_getvalue_raw
, argc
, argv
);
678 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
679 const DOM_SID
*domain_sid
,
680 const char *domain_name
,
681 struct cli_state
*cli
,
682 struct rpc_pipe_client
*pipe_hnd
,
688 struct policy_handle hive_hnd
, key_hnd
;
689 struct winreg_String key
, keyclass
;
690 enum winreg_CreateAction action
;
694 ZERO_STRUCT(keyclass
);
696 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
697 return NT_STATUS_INVALID_PARAMETER
;
700 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
701 SEC_FLAG_MAXIMUM_ALLOWED
,
703 if (!(NT_STATUS_IS_OK(status
))) {
707 action
= REG_ACTION_NONE
;
710 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
711 keyclass
, 0, REG_KEY_READ
, NULL
,
712 &key_hnd
, &action
, NULL
);
713 if (!NT_STATUS_IS_OK(status
)) {
714 d_fprintf(stderr
, _("createkey returned %s\n"),
716 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
721 case REG_ACTION_NONE
:
722 d_printf(_("createkey did nothing -- huh?\n"));
724 case REG_CREATED_NEW_KEY
:
725 d_printf(_("createkey created %s\n"), argv
[0]);
727 case REG_OPENED_EXISTING_KEY
:
728 d_printf(_("createkey opened existing %s\n"), argv
[0]);
732 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
733 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
738 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
741 if (argc
!= 1 || c
->display_usage
) {
743 _("usage:"),_(" net rpc registry createkey <key>\n"));
747 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
748 rpc_registry_createkey_internal
, argc
, argv
);
751 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
752 const DOM_SID
*domain_sid
,
753 const char *domain_name
,
754 struct cli_state
*cli
,
755 struct rpc_pipe_client
*pipe_hnd
,
761 struct policy_handle hive_hnd
;
762 struct winreg_String key
;
767 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
768 return NT_STATUS_INVALID_PARAMETER
;
771 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
772 SEC_FLAG_MAXIMUM_ALLOWED
,
774 if (!(NT_STATUS_IS_OK(status
))) {
778 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
779 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
781 if (!NT_STATUS_IS_OK(status
)) {
782 d_fprintf(stderr
, _("deletekey returned %s\n"),
789 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
791 if (argc
!= 1 || c
->display_usage
) {
793 _("usage:"),_(" net rpc registry deletekey <key>\n"));
797 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
798 rpc_registry_deletekey_internal
, argc
, argv
);
801 /********************************************************************
802 ********************************************************************/
804 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
805 const DOM_SID
*domain_sid
,
806 const char *domain_name
,
807 struct cli_state
*cli
,
808 struct rpc_pipe_client
*pipe_hnd
,
813 struct policy_handle pol_hive
, pol_key
;
815 uint32 num_subkeys
= 0;
816 uint32 num_values
= 0;
817 char **names
= NULL
, **classes
= NULL
;
818 NTTIME
**modtimes
= NULL
;
820 struct registry_value
**values
= NULL
;
822 if (argc
!= 1 || c
->display_usage
) {
823 d_printf(_("Usage:"),_(" net rpc registry enumerate <path>\n"));
824 d_printf(_("Example:")," net rpc registry enumerate "
825 "'HKLM\\Software\\Samba'\n");
826 return NT_STATUS_INVALID_PARAMETER
;
829 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
830 &pol_hive
, &pol_key
);
831 if (!NT_STATUS_IS_OK(status
)) {
832 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
837 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
838 &names
, &classes
, &modtimes
);
839 if (!NT_STATUS_IS_OK(status
)) {
840 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
845 for (i
=0; i
<num_subkeys
; i
++) {
846 print_registry_key(names
[i
], modtimes
[i
]);
849 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
851 if (!NT_STATUS_IS_OK(status
)) {
852 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
857 for (i
=0; i
<num_values
; i
++) {
858 print_registry_value_with_name(names
[i
], values
[i
]);
861 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
862 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
867 /********************************************************************
868 ********************************************************************/
870 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
873 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
874 rpc_registry_enumerate_internal
, argc
, argv
);
877 /********************************************************************
878 ********************************************************************/
880 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
881 const DOM_SID
*domain_sid
,
882 const char *domain_name
,
883 struct cli_state
*cli
,
884 struct rpc_pipe_client
*pipe_hnd
,
889 WERROR result
= WERR_GENERAL_FAILURE
;
890 struct policy_handle pol_hive
, pol_key
;
891 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
892 struct winreg_String filename
;
894 if (argc
!= 2 || c
->display_usage
) {
895 d_printf(_("Usage:"),_(" net rpc registry backup <path> "
897 return NT_STATUS_INVALID_PARAMETER
;
900 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
901 &pol_hive
, &pol_key
);
902 if (!NT_STATUS_IS_OK(status
)) {
903 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
908 filename
.name
= argv
[1];
909 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
910 if ( !W_ERROR_IS_OK(result
) ) {
911 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
912 cli
->desthost
, argv
[1]);
917 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
918 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
923 /********************************************************************
924 ********************************************************************/
926 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
928 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
929 rpc_registry_save_internal
, argc
, argv
);
933 /********************************************************************
934 ********************************************************************/
936 static void dump_values( REGF_NK_REC
*nk
)
939 const char *data_str
= NULL
;
940 uint32 data_size
, data
;
946 for ( i
=0; i
<nk
->num_values
; i
++ ) {
947 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
948 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
950 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
951 switch ( nk
->values
[i
].type
) {
953 blob
= data_blob_const(nk
->values
[i
].data
, data_size
);
954 pull_reg_sz(talloc_tos(), &blob
, &data_str
);
958 d_printf( "%s", data_str
);
962 for ( j
=0; j
<data_size
; j
++ ) {
963 d_printf( "%c", nk
->values
[i
].data
[j
] );
967 data
= IVAL( nk
->values
[i
].data
, 0 );
968 d_printf("0x%x", data
);
971 for ( j
=0; j
<data_size
; j
++ ) {
972 d_printf( "%x", nk
->values
[i
].data
[j
] );
976 d_printf(_("unknown"));
985 /********************************************************************
986 ********************************************************************/
988 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
992 /* depth first dump of the registry tree */
994 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
996 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
999 d_printf("[%s]\n", regpath
);
1002 dump_registry_tree( file
, key
, regpath
);
1009 /********************************************************************
1010 ********************************************************************/
1012 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
1013 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
1014 const char *parentpath
)
1016 REGF_NK_REC
*key
, *subkey
;
1017 struct regval_ctr
*values
= NULL
;
1018 struct regsubkey_ctr
*subkeys
= NULL
;
1023 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
1024 if (!W_ERROR_IS_OK(werr
)) {
1025 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1026 "%s\n", win_errstr(werr
)));
1030 if ( !(values
= TALLOC_ZERO_P( subkeys
, struct regval_ctr
)) ) {
1031 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1032 TALLOC_FREE(subkeys
);
1036 /* copy values into the struct regval_ctr */
1038 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1039 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1040 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1043 /* copy subkeys into the struct regsubkey_ctr */
1045 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1046 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1049 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1051 /* write each one of the subkeys out */
1053 path
= talloc_asprintf(subkeys
,
1059 TALLOC_FREE(subkeys
);
1063 nk
->subkey_index
= 0;
1064 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1065 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1068 d_printf("[%s]\n", path
);
1069 TALLOC_FREE(subkeys
);
1074 /********************************************************************
1075 ********************************************************************/
1077 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1079 REGF_FILE
*registry
;
1082 if (argc
!= 1 || c
->display_usage
) {
1083 d_printf(_("Usage:"),_(" net rpc registry dump <file> \n"));
1087 d_printf(_("Opening %s...."), argv
[0]);
1088 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1089 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1092 d_printf(_("ok\n"));
1094 /* get the root of the registry file */
1096 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1097 d_fprintf(stderr
, _("Could not get rootkey\n"));
1098 regfio_close( registry
);
1101 d_printf("[%s]\n", nk
->keyname
);
1105 dump_registry_tree( registry
, nk
, nk
->keyname
);
1108 talloc_report_full( registry
->mem_ctx
, stderr
);
1110 d_printf(_("Closing registry..."));
1111 regfio_close( registry
);
1112 d_printf(_("ok\n"));
1117 /********************************************************************
1118 ********************************************************************/
1120 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1122 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1126 if (argc
!= 2 || c
->display_usage
) {
1127 d_printf(_("Usage:"),_(" net rpc registry copy <srcfile> "
1132 d_printf(_("Opening %s...."), argv
[0]);
1133 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1134 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1137 d_printf(_("ok\n"));
1139 d_printf(_("Opening %s...."), argv
[1]);
1140 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1141 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1144 d_printf(_("ok\n"));
1146 /* get the root of the registry file */
1148 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1149 d_fprintf(stderr
, _("Could not get rootkey\n"));
1152 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1154 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1160 d_printf(_("Closing %s..."), argv
[1]);
1162 regfio_close( outfile
);
1164 d_printf(_("ok\n"));
1166 d_printf(_("Closing %s..."), argv
[0]);
1168 regfio_close( infile
);
1170 d_printf(_("ok\n"));
1175 /********************************************************************
1176 ********************************************************************/
1178 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1179 const DOM_SID
*domain_sid
,
1180 const char *domain_name
,
1181 struct cli_state
*cli
,
1182 struct rpc_pipe_client
*pipe_hnd
,
1183 TALLOC_CTX
*mem_ctx
,
1187 struct policy_handle pol_hive
, pol_key
;
1189 enum ndr_err_code ndr_err
;
1190 struct KeySecurityData
*sd
= NULL
;
1193 struct security_descriptor sec_desc
;
1194 uint32_t access_mask
= REG_KEY_READ
|
1195 SEC_FLAG_MAXIMUM_ALLOWED
|
1196 SEC_FLAG_SYSTEM_SECURITY
;
1198 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1199 d_printf(_("Usage:"),_(" net rpc registry getsd <path> "
1201 d_printf(_("Example:")," net rpc registry getsd "
1202 "'HKLM\\Software\\Samba'\n");
1203 return NT_STATUS_INVALID_PARAMETER
;
1206 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1208 &pol_hive
, &pol_key
);
1209 if (!NT_STATUS_IS_OK(status
)) {
1210 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1215 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1217 status
= NT_STATUS_NO_MEMORY
;
1224 sscanf(argv
[1], "%x", &sec_info
);
1226 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1229 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1230 if (!NT_STATUS_IS_OK(status
)) {
1231 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1236 blob
.data
= sd
->data
;
1237 blob
.length
= sd
->size
;
1239 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, NULL
, &sec_desc
,
1240 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1241 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1242 status
= ndr_map_error2ntstatus(ndr_err
);
1245 status
= NT_STATUS_OK
;
1247 display_sec_desc(&sec_desc
);
1250 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1251 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1257 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1259 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1260 rpc_registry_getsd_internal
, argc
, argv
);
1263 /********************************************************************
1264 ********************************************************************/
1266 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1268 struct functable func
[] = {
1271 rpc_registry_enumerate
,
1273 N_("Enumerate registry keys and values"),
1274 N_("net rpc registry enumerate\n"
1275 " Enumerate registry keys and values")
1279 rpc_registry_createkey
,
1281 N_("Create a new registry key"),
1282 N_("net rpc registry createkey\n"
1283 " Create a new registry key")
1287 rpc_registry_deletekey
,
1289 N_("Delete a registry key"),
1290 N_("net rpc registry deletekey\n"
1291 " Delete a registry key")
1295 rpc_registry_getvalue
,
1297 N_("Print a registry value"),
1298 N_("net rpc registry getvalue\n"
1299 " Print a registry value")
1303 rpc_registry_getvalueraw
,
1305 N_("Print a registry value"),
1306 N_("net rpc registry getvalueraw\n"
1307 " Print a registry value (raw version)")
1311 rpc_registry_setvalue
,
1313 N_("Set a new registry value"),
1314 N_("net rpc registry setvalue\n"
1315 " Set a new registry value")
1319 rpc_registry_deletevalue
,
1321 N_("Delete a registry value"),
1322 N_("net rpc registry deletevalue\n"
1323 " Delete a registry value")
1329 N_("Save a registry file"),
1330 N_("net rpc registry save\n"
1331 " Save a registry file")
1337 N_("Dump a registry file"),
1338 N_("net rpc registry dump\n"
1339 " Dump a registry file")
1345 N_("Copy a registry file"),
1346 N_("net rpc registry copy\n"
1347 " Copy a registry file")
1353 N_("Get security descriptor"),
1354 N_("net rpc registry getsd\n"
1355 " Get security descriptior")
1357 {NULL
, NULL
, 0, NULL
, NULL
}
1360 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);