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"
26 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
27 uint32
*reg_type
, const char **key_name
)
30 char *hivename
= NULL
;
31 char *tmp_keyname
= NULL
;
33 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
35 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
36 if (!W_ERROR_IS_OK(werr
)) {
40 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
41 if (*key_name
== NULL
) {
45 if (strequal(hivename
, "HKLM") ||
46 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
48 (*reg_type
) = HKEY_LOCAL_MACHINE
;
49 } else if (strequal(hivename
, "HKCR") ||
50 strequal(hivename
, "HKEY_CLASSES_ROOT"))
52 (*reg_type
) = HKEY_CLASSES_ROOT
;
53 } else if (strequal(hivename
, "HKU") ||
54 strequal(hivename
, "HKEY_USERS"))
56 (*reg_type
) = HKEY_USERS
;
57 } else if (strequal(hivename
, "HKCU") ||
58 strequal(hivename
, "HKEY_CURRENT_USER"))
60 (*reg_type
) = HKEY_CURRENT_USER
;
61 } else if (strequal(hivename
, "HKPD") ||
62 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
64 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
66 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
78 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
79 struct rpc_pipe_client
*pipe_hnd
,
80 const char *name
, uint32 access_mask
,
81 struct policy_handle
*hive_hnd
,
82 struct policy_handle
*key_hnd
)
86 struct winreg_String key
;
90 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
91 return NT_STATUS_INVALID_PARAMETER
;
94 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
96 if (!(NT_STATUS_IS_OK(status
))) {
100 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
101 access_mask
, key_hnd
, NULL
);
102 if (!(NT_STATUS_IS_OK(status
))) {
103 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
110 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
111 struct rpc_pipe_client
*pipe_hnd
,
112 struct policy_handle
*key_hnd
,
113 uint32
*pnum_keys
, char ***pnames
,
114 char ***pclasses
, NTTIME
***pmodtimes
)
118 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
119 uint32 num_values
, max_valnamelen
, max_valbufsize
;
121 NTTIME last_changed_time
;
123 struct winreg_String classname
;
124 char **names
, **classes
;
127 if (!(mem_ctx
= talloc_new(ctx
))) {
128 return NT_STATUS_NO_MEMORY
;
131 ZERO_STRUCT(classname
);
132 status
= rpccli_winreg_QueryInfoKey(
133 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
134 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
135 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
137 if (!NT_STATUS_IS_OK(status
)) {
141 if (num_subkeys
== 0) {
143 TALLOC_FREE(mem_ctx
);
147 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
148 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
149 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
151 status
= NT_STATUS_NO_MEMORY
;
155 for (i
=0; i
<num_subkeys
; i
++) {
157 struct winreg_StringBuf class_buf
;
158 struct winreg_StringBuf name_buf
;
164 class_buf
.size
= max_classlen
+2;
168 name_buf
.size
= max_subkeylen
+2;
170 ZERO_STRUCT(modtime
);
172 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
173 i
, &name_buf
, &class_buf
,
176 if (W_ERROR_EQUAL(werr
,
177 WERR_NO_MORE_ITEMS
) ) {
178 status
= NT_STATUS_OK
;
181 if (!NT_STATUS_IS_OK(status
)) {
187 if (class_buf
.name
&&
188 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
189 status
= NT_STATUS_NO_MEMORY
;
193 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
194 status
= NT_STATUS_NO_MEMORY
;
198 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
199 modtimes
, &modtime
, sizeof(modtime
))))) {
200 status
= NT_STATUS_NO_MEMORY
;
205 *pnum_keys
= num_subkeys
;
208 *pnames
= talloc_move(ctx
, &names
);
211 *pclasses
= talloc_move(ctx
, &classes
);
214 *pmodtimes
= talloc_move(ctx
, &modtimes
);
217 status
= NT_STATUS_OK
;
220 TALLOC_FREE(mem_ctx
);
224 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
225 struct rpc_pipe_client
*pipe_hnd
,
226 struct policy_handle
*key_hnd
,
227 uint32
*pnum_values
, char ***pvalnames
,
228 struct registry_value
***pvalues
)
232 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
233 uint32 num_values
, max_valnamelen
, max_valbufsize
;
235 NTTIME last_changed_time
;
237 struct winreg_String classname
;
238 struct registry_value
**values
;
241 if (!(mem_ctx
= talloc_new(ctx
))) {
242 return NT_STATUS_NO_MEMORY
;
245 ZERO_STRUCT(classname
);
246 status
= rpccli_winreg_QueryInfoKey(
247 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
248 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
249 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
251 if (!NT_STATUS_IS_OK(status
)) {
255 if (num_values
== 0) {
257 TALLOC_FREE(mem_ctx
);
261 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
262 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
264 status
= NT_STATUS_NO_MEMORY
;
268 for (i
=0; i
<num_values
; i
++) {
269 enum winreg_Type type
= REG_NONE
;
275 struct winreg_ValNameBuf name_buf
;
280 name_buf
.size
= max_valnamelen
+ 2;
282 data_size
= max_valbufsize
;
283 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
286 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
289 &value_length
, &err
);
291 if ( W_ERROR_EQUAL(err
,
292 WERR_NO_MORE_ITEMS
) ) {
293 status
= NT_STATUS_OK
;
297 if (!(NT_STATUS_IS_OK(status
))) {
301 if (name_buf
.name
== NULL
) {
302 status
= NT_STATUS_INVALID_PARAMETER
;
306 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
307 status
= NT_STATUS_NO_MEMORY
;
311 err
= registry_pull_value(values
, &values
[i
], type
, data
,
312 data_size
, value_length
);
313 if (!W_ERROR_IS_OK(err
)) {
314 status
= werror_to_ntstatus(err
);
319 *pnum_values
= num_values
;
322 *pvalnames
= talloc_move(ctx
, &names
);
325 *pvalues
= talloc_move(ctx
, &values
);
328 status
= NT_STATUS_OK
;
331 TALLOC_FREE(mem_ctx
);
335 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
336 struct rpc_pipe_client
*pipe_hnd
,
337 struct policy_handle
*key_hnd
,
339 struct KeySecurityData
*sd
)
341 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
346 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
347 struct rpc_pipe_client
*pipe_hnd
,
348 struct policy_handle
*key_hnd
,
350 const struct registry_value
*value
)
352 struct winreg_String name_string
;
357 err
= registry_push_value(mem_ctx
, value
, &blob
);
358 if (!W_ERROR_IS_OK(err
)) {
359 return werror_to_ntstatus(err
);
362 ZERO_STRUCT(name_string
);
364 name_string
.name
= name
;
365 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
366 name_string
, value
->type
,
367 blob
.data
, blob
.length
, NULL
);
368 TALLOC_FREE(blob
.data
);
372 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
373 const DOM_SID
*domain_sid
,
374 const char *domain_name
,
375 struct cli_state
*cli
,
376 struct rpc_pipe_client
*pipe_hnd
,
381 struct policy_handle hive_hnd
, key_hnd
;
383 struct registry_value value
;
385 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
386 SEC_FLAG_MAXIMUM_ALLOWED
,
387 &hive_hnd
, &key_hnd
);
388 if (!NT_STATUS_IS_OK(status
)) {
389 d_fprintf(stderr
, "registry_openkey failed: %s\n",
394 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
395 d_fprintf(stderr
, "Too many args for type %s\n", argv
[2]);
396 return NT_STATUS_NOT_IMPLEMENTED
;
399 if (strequal(argv
[2], "dword")) {
400 value
.type
= REG_DWORD
;
401 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
403 else if (strequal(argv
[2], "sz")) {
405 value
.v
.sz
.len
= strlen(argv
[3])+1;
406 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
409 d_fprintf(stderr
, "type \"%s\" not implemented\n", argv
[2]);
410 status
= NT_STATUS_NOT_IMPLEMENTED
;
414 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
417 if (!NT_STATUS_IS_OK(status
)) {
418 d_fprintf(stderr
, "registry_setvalue failed: %s\n",
423 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
424 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
429 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
432 if (argc
< 4 || c
->display_usage
) {
433 d_fprintf(stderr
, "usage: net rpc registry setvalue <key> "
434 "<valuename> <type> [<val>]+\n");
438 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
439 rpc_registry_setvalue_internal
, argc
, argv
);
442 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
443 const DOM_SID
*domain_sid
,
444 const char *domain_name
,
445 struct cli_state
*cli
,
446 struct rpc_pipe_client
*pipe_hnd
,
451 struct policy_handle hive_hnd
, key_hnd
;
453 struct winreg_String valuename
;
455 ZERO_STRUCT(valuename
);
457 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
458 SEC_FLAG_MAXIMUM_ALLOWED
,
459 &hive_hnd
, &key_hnd
);
460 if (!NT_STATUS_IS_OK(status
)) {
461 d_fprintf(stderr
, "registry_openkey failed: %s\n",
466 valuename
.name
= argv
[1];
468 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
471 if (!NT_STATUS_IS_OK(status
)) {
472 d_fprintf(stderr
, "registry_deletevalue failed: %s\n",
476 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
477 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
482 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
485 if (argc
!= 2 || c
->display_usage
) {
486 d_fprintf(stderr
, "usage: net rpc registry deletevalue <key> "
491 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
492 rpc_registry_deletevalue_internal
, argc
, argv
);
495 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
496 const DOM_SID
*domain_sid
,
497 const char *domain_name
,
498 struct cli_state
*cli
,
499 struct rpc_pipe_client
*pipe_hnd
,
505 struct policy_handle hive_hnd
, key_hnd
;
508 struct winreg_String valuename
;
509 struct registry_value
*value
= NULL
;
510 enum winreg_Type type
= REG_NONE
;
511 uint8_t *data
= NULL
;
512 uint32_t data_size
= 0;
513 uint32_t value_length
= 0;
514 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
516 ZERO_STRUCT(valuename
);
518 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
519 SEC_FLAG_MAXIMUM_ALLOWED
,
520 &hive_hnd
, &key_hnd
);
521 if (!NT_STATUS_IS_OK(status
)) {
522 d_fprintf(stderr
, "registry_openkey failed: %s\n",
527 valuename
.name
= argv
[1];
530 * call QueryValue once with data == NULL to get the
531 * needed memory size to be allocated, then allocate
532 * data buffer and call again.
534 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
542 if (!NT_STATUS_IS_OK(status
)) {
543 d_fprintf(stderr
, "registry_queryvalue failed: %s\n",
548 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
551 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
559 if (!NT_STATUS_IS_OK(status
)) {
560 d_fprintf(stderr
, "registry_queryvalue failed: %s\n",
565 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
566 data_size
, value_length
);
567 if (!W_ERROR_IS_OK(werr
)) {
568 status
= werror_to_ntstatus(werr
);
572 print_registry_value(value
, raw
);
575 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
576 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
578 TALLOC_FREE(tmp_ctx
);
583 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
584 const DOM_SID
*domain_sid
,
585 const char *domain_name
,
586 struct cli_state
*cli
,
587 struct rpc_pipe_client
*pipe_hnd
,
592 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
593 cli
, pipe_hnd
, mem_ctx
, false,
597 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
600 if (argc
!= 2 || c
->display_usage
) {
601 d_fprintf(stderr
, "usage: net rpc registry getvalue <key> "
606 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
607 rpc_registry_getvalue_full
, argc
, argv
);
610 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
611 const DOM_SID
*domain_sid
,
612 const char *domain_name
,
613 struct cli_state
*cli
,
614 struct rpc_pipe_client
*pipe_hnd
,
619 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
620 cli
, pipe_hnd
, mem_ctx
, true,
624 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
627 if (argc
!= 2 || c
->display_usage
) {
628 d_fprintf(stderr
, "usage: net rpc registry getvalue <key> "
633 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
634 rpc_registry_getvalue_raw
, argc
, argv
);
637 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
638 const DOM_SID
*domain_sid
,
639 const char *domain_name
,
640 struct cli_state
*cli
,
641 struct rpc_pipe_client
*pipe_hnd
,
647 struct policy_handle hive_hnd
, key_hnd
;
648 struct winreg_String key
, keyclass
;
649 enum winreg_CreateAction action
;
653 ZERO_STRUCT(keyclass
);
655 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
656 return NT_STATUS_INVALID_PARAMETER
;
659 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
660 SEC_FLAG_MAXIMUM_ALLOWED
,
662 if (!(NT_STATUS_IS_OK(status
))) {
666 action
= REG_ACTION_NONE
;
669 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
670 keyclass
, 0, REG_KEY_READ
, NULL
,
671 &key_hnd
, &action
, NULL
);
672 if (!NT_STATUS_IS_OK(status
)) {
673 d_fprintf(stderr
, "createkey returned %s\n",
675 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
680 case REG_ACTION_NONE
:
681 d_printf("createkey did nothing -- huh?\n");
683 case REG_CREATED_NEW_KEY
:
684 d_printf("createkey created %s\n", argv
[0]);
686 case REG_OPENED_EXISTING_KEY
:
687 d_printf("createkey opened existing %s\n", argv
[0]);
691 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
692 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
697 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
700 if (argc
!= 1 || c
->display_usage
) {
701 d_fprintf(stderr
, "usage: net rpc registry createkey <key>\n");
705 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
706 rpc_registry_createkey_internal
, argc
, argv
);
709 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
710 const DOM_SID
*domain_sid
,
711 const char *domain_name
,
712 struct cli_state
*cli
,
713 struct rpc_pipe_client
*pipe_hnd
,
719 struct policy_handle hive_hnd
;
720 struct winreg_String key
;
725 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
726 return NT_STATUS_INVALID_PARAMETER
;
729 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
730 SEC_FLAG_MAXIMUM_ALLOWED
,
732 if (!(NT_STATUS_IS_OK(status
))) {
736 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
737 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
739 if (!NT_STATUS_IS_OK(status
)) {
740 d_fprintf(stderr
, "deletekey returned %s\n",
747 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
749 if (argc
!= 1 || c
->display_usage
) {
750 d_fprintf(stderr
, "usage: net rpc registry deletekey <key>\n");
754 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
755 rpc_registry_deletekey_internal
, argc
, argv
);
758 /********************************************************************
759 ********************************************************************/
761 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
762 const DOM_SID
*domain_sid
,
763 const char *domain_name
,
764 struct cli_state
*cli
,
765 struct rpc_pipe_client
*pipe_hnd
,
770 struct policy_handle pol_hive
, pol_key
;
772 uint32 num_subkeys
= 0;
773 uint32 num_values
= 0;
774 char **names
= NULL
, **classes
= NULL
;
775 NTTIME
**modtimes
= NULL
;
777 struct registry_value
**values
= NULL
;
779 if (argc
!= 1 || c
->display_usage
) {
780 d_printf("Usage: net rpc registry enumerate <path>\n");
781 d_printf("Example: net rpc registry enumerate 'HKLM\\Software\\Samba'\n");
782 return NT_STATUS_INVALID_PARAMETER
;
785 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
786 &pol_hive
, &pol_key
);
787 if (!NT_STATUS_IS_OK(status
)) {
788 d_fprintf(stderr
, "registry_openkey failed: %s\n",
793 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
794 &names
, &classes
, &modtimes
);
795 if (!NT_STATUS_IS_OK(status
)) {
796 d_fprintf(stderr
, "enumerating keys failed: %s\n",
801 for (i
=0; i
<num_subkeys
; i
++) {
802 print_registry_key(names
[i
], modtimes
[i
]);
805 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
807 if (!NT_STATUS_IS_OK(status
)) {
808 d_fprintf(stderr
, "enumerating values failed: %s\n",
813 for (i
=0; i
<num_values
; i
++) {
814 print_registry_value_with_name(names
[i
], values
[i
]);
817 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
818 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
823 /********************************************************************
824 ********************************************************************/
826 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
829 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
830 rpc_registry_enumerate_internal
, argc
, argv
);
833 /********************************************************************
834 ********************************************************************/
836 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
837 const DOM_SID
*domain_sid
,
838 const char *domain_name
,
839 struct cli_state
*cli
,
840 struct rpc_pipe_client
*pipe_hnd
,
845 WERROR result
= WERR_GENERAL_FAILURE
;
846 struct policy_handle pol_hive
, pol_key
;
847 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
848 struct winreg_String filename
;
850 if (argc
!= 2 || c
->display_usage
) {
851 d_printf("Usage: net rpc registry backup <path> <file> \n");
852 return NT_STATUS_INVALID_PARAMETER
;
855 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
856 &pol_hive
, &pol_key
);
857 if (!NT_STATUS_IS_OK(status
)) {
858 d_fprintf(stderr
, "registry_openkey failed: %s\n",
863 filename
.name
= argv
[1];
864 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
865 if ( !W_ERROR_IS_OK(result
) ) {
866 d_fprintf(stderr
, "Unable to save [%s] to %s:%s\n", argv
[0], cli
->desthost
, argv
[1]);
871 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
872 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
877 /********************************************************************
878 ********************************************************************/
880 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
882 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
883 rpc_registry_save_internal
, argc
, argv
);
887 /********************************************************************
888 ********************************************************************/
890 static void dump_values( REGF_NK_REC
*nk
)
893 char *data_str
= NULL
;
894 uint32 data_size
, data
;
899 for ( i
=0; i
<nk
->num_values
; i
++ ) {
900 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
901 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
903 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
904 switch ( nk
->values
[i
].type
) {
906 rpcstr_pull_talloc(talloc_tos(),
914 d_printf( "%s", data_str
);
918 for ( j
=0; j
<data_size
; j
++ ) {
919 d_printf( "%c", nk
->values
[i
].data
[j
] );
923 data
= IVAL( nk
->values
[i
].data
, 0 );
924 d_printf("0x%x", data
);
927 for ( j
=0; j
<data_size
; j
++ ) {
928 d_printf( "%x", nk
->values
[i
].data
[j
] );
941 /********************************************************************
942 ********************************************************************/
944 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
948 /* depth first dump of the registry tree */
950 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
952 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
955 d_printf("[%s]\n", regpath
);
958 dump_registry_tree( file
, key
, regpath
);
965 /********************************************************************
966 ********************************************************************/
968 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
969 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
970 const char *parentpath
)
972 REGF_NK_REC
*key
, *subkey
;
973 REGVAL_CTR
*values
= NULL
;
974 struct regsubkey_ctr
*subkeys
= NULL
;
979 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
980 if (!W_ERROR_IS_OK(werr
)) {
981 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
982 "%s\n", win_errstr(werr
)));
986 if ( !(values
= TALLOC_ZERO_P( subkeys
, REGVAL_CTR
)) ) {
987 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
988 TALLOC_FREE(subkeys
);
992 /* copy values into the REGVAL_CTR */
994 for ( i
=0; i
<nk
->num_values
; i
++ ) {
995 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
996 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
999 /* copy subkeys into the struct regsubkey_ctr */
1001 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1002 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1005 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1007 /* write each one of the subkeys out */
1009 path
= talloc_asprintf(subkeys
,
1015 TALLOC_FREE(subkeys
);
1019 nk
->subkey_index
= 0;
1020 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1021 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1024 d_printf("[%s]\n", path
);
1025 TALLOC_FREE(subkeys
);
1030 /********************************************************************
1031 ********************************************************************/
1033 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1035 REGF_FILE
*registry
;
1038 if (argc
!= 1 || c
->display_usage
) {
1039 d_printf("Usage: net rpc registry dump <file> \n");
1043 d_printf("Opening %s....", argv
[0]);
1044 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1045 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
1050 /* get the root of the registry file */
1052 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1053 d_fprintf(stderr
, "Could not get rootkey\n");
1054 regfio_close( registry
);
1057 d_printf("[%s]\n", nk
->keyname
);
1061 dump_registry_tree( registry
, nk
, nk
->keyname
);
1064 talloc_report_full( registry
->mem_ctx
, stderr
);
1066 d_printf("Closing registry...");
1067 regfio_close( registry
);
1073 /********************************************************************
1074 ********************************************************************/
1076 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1078 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1082 if (argc
!= 2 || c
->display_usage
) {
1083 d_printf("Usage: net rpc registry copy <srcfile> <newfile>\n");
1087 d_printf("Opening %s....", argv
[0]);
1088 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1089 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
1094 d_printf("Opening %s....", argv
[1]);
1095 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1096 d_fprintf(stderr
, "Failed to open %s for writing\n", argv
[1]);
1101 /* get the root of the registry file */
1103 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1104 d_fprintf(stderr
, "Could not get rootkey\n");
1107 d_printf("RootKey: [%s]\n", nk
->keyname
);
1109 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1115 d_printf("Closing %s...", argv
[1]);
1117 regfio_close( outfile
);
1121 d_printf("Closing %s...", argv
[0]);
1123 regfio_close( infile
);
1130 /********************************************************************
1131 ********************************************************************/
1133 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1134 const DOM_SID
*domain_sid
,
1135 const char *domain_name
,
1136 struct cli_state
*cli
,
1137 struct rpc_pipe_client
*pipe_hnd
,
1138 TALLOC_CTX
*mem_ctx
,
1142 struct policy_handle pol_hive
, pol_key
;
1144 enum ndr_err_code ndr_err
;
1145 struct KeySecurityData
*sd
= NULL
;
1148 struct security_descriptor sec_desc
;
1149 uint32_t access_mask
= REG_KEY_READ
|
1150 SEC_FLAG_MAXIMUM_ALLOWED
|
1151 SEC_FLAG_SYSTEM_SECURITY
;
1153 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1154 d_printf("Usage: net rpc registry getsd <path> <secinfo>\n");
1155 d_printf("Example: net rpc registry getsd 'HKLM\\Software\\Samba'\n");
1156 return NT_STATUS_INVALID_PARAMETER
;
1159 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1161 &pol_hive
, &pol_key
);
1162 if (!NT_STATUS_IS_OK(status
)) {
1163 d_fprintf(stderr
, "registry_openkey failed: %s\n",
1168 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1170 status
= NT_STATUS_NO_MEMORY
;
1177 sscanf(argv
[1], "%x", &sec_info
);
1179 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1182 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1183 if (!NT_STATUS_IS_OK(status
)) {
1184 d_fprintf(stderr
, "getting sd failed: %s\n",
1189 blob
.data
= sd
->data
;
1190 blob
.length
= sd
->size
;
1192 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, NULL
, &sec_desc
,
1193 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1194 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1195 status
= ndr_map_error2ntstatus(ndr_err
);
1198 status
= NT_STATUS_OK
;
1200 display_sec_desc(&sec_desc
);
1203 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1204 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1210 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1212 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1213 rpc_registry_getsd_internal
, argc
, argv
);
1216 /********************************************************************
1217 ********************************************************************/
1219 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1221 struct functable func
[] = {
1224 rpc_registry_enumerate
,
1226 "Enumerate registry keys and values",
1227 "net rpc registry enumerate\n"
1228 " Enumerate registry keys and values"
1232 rpc_registry_createkey
,
1234 "Create a new registry key",
1235 "net rpc registry createkey\n"
1236 " Create a new registry key"
1240 rpc_registry_deletekey
,
1242 "Delete a registry key",
1243 "net rpc registry deletekey\n"
1244 " Delete a registry key"
1248 rpc_registry_getvalue
,
1250 "Print a registry value",
1251 "net rpc registry getvalue\n"
1252 " Print a registry value"
1256 rpc_registry_getvalueraw
,
1258 "Print a registry value",
1259 "net rpc registry getvalueraw\n"
1260 " Print a registry value (raw version)"
1264 rpc_registry_setvalue
,
1266 "Set a new registry value",
1267 "net rpc registry setvalue\n"
1268 " Set a new registry value"
1272 rpc_registry_deletevalue
,
1274 "Delete a registry value",
1275 "net rpc registry deletevalue\n"
1276 " Delete a registry value"
1282 "Save a registry file",
1283 "net rpc registry save\n"
1284 " Save a registry file"
1290 "Dump a registry file",
1291 "net rpc registry dump\n"
1292 " Dump a registry file"
1298 "Copy a registry file",
1299 "net rpc registry copy\n"
1300 " Copy a registry file"
1306 "Get security descriptor",
1307 "net rpc registry getsd\n"
1308 " Get security descriptior"
1310 {NULL
, NULL
, 0, NULL
, NULL
}
1313 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);