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"
23 #include "reg_objects.h"
25 static bool reg_hive_key(const char *fullname
, uint32
*reg_type
,
26 const char **key_name
)
31 sep
= strchr_m(fullname
, '\\');
38 len
= strlen(fullname
);
42 if (strnequal(fullname
, "HKLM", len
) ||
43 strnequal(fullname
, "HKEY_LOCAL_MACHINE", len
))
44 (*reg_type
) = HKEY_LOCAL_MACHINE
;
45 else if (strnequal(fullname
, "HKCR", len
) ||
46 strnequal(fullname
, "HKEY_CLASSES_ROOT", len
))
47 (*reg_type
) = HKEY_CLASSES_ROOT
;
48 else if (strnequal(fullname
, "HKU", len
) ||
49 strnequal(fullname
, "HKEY_USERS", len
))
50 (*reg_type
) = HKEY_USERS
;
51 else if (strnequal(fullname
, "HKCU", len
) ||
52 strnequal(fullname
, "HKEY_CURRENT_USER", len
))
53 (*reg_type
) = HKEY_CURRENT_USER
;
54 else if (strnequal(fullname
, "HKPD", len
) ||
55 strnequal(fullname
, "HKEY_PERFORMANCE_DATA", len
))
56 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
58 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
66 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
67 struct rpc_pipe_client
*pipe_hnd
,
68 const char *name
, uint32 access_mask
,
69 struct policy_handle
*hive_hnd
,
70 struct policy_handle
*key_hnd
)
74 struct winreg_String key
;
78 if (!reg_hive_key(name
, &hive
, &key
.name
)) {
79 return NT_STATUS_INVALID_PARAMETER
;
82 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
84 if (!(NT_STATUS_IS_OK(status
))) {
88 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
89 access_mask
, key_hnd
, NULL
);
90 if (!(NT_STATUS_IS_OK(status
))) {
91 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
98 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
99 struct rpc_pipe_client
*pipe_hnd
,
100 struct policy_handle
*key_hnd
,
101 uint32
*pnum_keys
, char ***pnames
,
102 char ***pclasses
, NTTIME
***pmodtimes
)
106 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
107 uint32 num_values
, max_valnamelen
, max_valbufsize
;
109 NTTIME last_changed_time
;
111 struct winreg_String classname
;
112 char **names
, **classes
;
115 if (!(mem_ctx
= talloc_new(ctx
))) {
116 return NT_STATUS_NO_MEMORY
;
119 ZERO_STRUCT(classname
);
120 status
= rpccli_winreg_QueryInfoKey(
121 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
122 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
123 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
125 if (!NT_STATUS_IS_OK(status
)) {
129 if (num_subkeys
== 0) {
131 TALLOC_FREE(mem_ctx
);
135 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
136 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
137 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
139 status
= NT_STATUS_NO_MEMORY
;
143 for (i
=0; i
<num_subkeys
; i
++) {
145 struct winreg_StringBuf class_buf
;
146 struct winreg_StringBuf name_buf
;
152 class_buf
.size
= max_classlen
+2;
156 name_buf
.size
= max_subkeylen
+2;
158 ZERO_STRUCT(modtime
);
160 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
161 i
, &name_buf
, &class_buf
,
164 if (W_ERROR_EQUAL(werr
,
165 WERR_NO_MORE_ITEMS
) ) {
166 status
= NT_STATUS_OK
;
169 if (!NT_STATUS_IS_OK(status
)) {
175 if (class_buf
.name
&&
176 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
177 status
= NT_STATUS_NO_MEMORY
;
181 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
182 status
= NT_STATUS_NO_MEMORY
;
186 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
187 modtimes
, &modtime
, sizeof(modtime
))))) {
188 status
= NT_STATUS_NO_MEMORY
;
193 *pnum_keys
= num_subkeys
;
196 *pnames
= talloc_move(ctx
, &names
);
199 *pclasses
= talloc_move(ctx
, &classes
);
202 *pmodtimes
= talloc_move(ctx
, &modtimes
);
205 status
= NT_STATUS_OK
;
208 TALLOC_FREE(mem_ctx
);
212 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
213 struct rpc_pipe_client
*pipe_hnd
,
214 struct policy_handle
*key_hnd
,
215 uint32
*pnum_values
, char ***pvalnames
,
216 struct registry_value
***pvalues
)
220 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
221 uint32 num_values
, max_valnamelen
, max_valbufsize
;
223 NTTIME last_changed_time
;
225 struct winreg_String classname
;
226 struct registry_value
**values
;
229 if (!(mem_ctx
= talloc_new(ctx
))) {
230 return NT_STATUS_NO_MEMORY
;
233 ZERO_STRUCT(classname
);
234 status
= rpccli_winreg_QueryInfoKey(
235 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
236 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
237 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
239 if (!NT_STATUS_IS_OK(status
)) {
243 if (num_values
== 0) {
245 TALLOC_FREE(mem_ctx
);
249 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
250 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
252 status
= NT_STATUS_NO_MEMORY
;
256 for (i
=0; i
<num_values
; i
++) {
257 enum winreg_Type type
= REG_NONE
;
263 struct winreg_ValNameBuf name_buf
;
268 name_buf
.size
= max_valnamelen
+ 2;
270 data_size
= max_valbufsize
;
271 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
274 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
277 &value_length
, &err
);
279 if ( W_ERROR_EQUAL(err
,
280 WERR_NO_MORE_ITEMS
) ) {
281 status
= NT_STATUS_OK
;
285 if (!(NT_STATUS_IS_OK(status
))) {
289 if (name_buf
.name
== NULL
) {
290 status
= NT_STATUS_INVALID_PARAMETER
;
294 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
295 status
= NT_STATUS_NO_MEMORY
;
299 err
= registry_pull_value(values
, &values
[i
], type
, data
,
300 data_size
, value_length
);
301 if (!W_ERROR_IS_OK(err
)) {
302 status
= werror_to_ntstatus(err
);
307 *pnum_values
= num_values
;
310 *pvalnames
= talloc_move(ctx
, &names
);
313 *pvalues
= talloc_move(ctx
, &values
);
316 status
= NT_STATUS_OK
;
319 TALLOC_FREE(mem_ctx
);
323 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
324 struct rpc_pipe_client
*pipe_hnd
,
325 struct policy_handle
*key_hnd
,
327 struct KeySecurityData
*sd
)
329 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
334 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
335 struct rpc_pipe_client
*pipe_hnd
,
336 struct policy_handle
*key_hnd
,
338 const struct registry_value
*value
)
340 struct winreg_String name_string
;
345 err
= registry_push_value(mem_ctx
, value
, &blob
);
346 if (!W_ERROR_IS_OK(err
)) {
347 return werror_to_ntstatus(err
);
350 ZERO_STRUCT(name_string
);
352 name_string
.name
= name
;
353 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
354 name_string
, value
->type
,
355 blob
.data
, blob
.length
, NULL
);
356 TALLOC_FREE(blob
.data
);
360 static NTSTATUS
rpc_registry_setvalue_internal(const DOM_SID
*domain_sid
,
361 const char *domain_name
,
362 struct cli_state
*cli
,
363 struct rpc_pipe_client
*pipe_hnd
,
368 struct policy_handle hive_hnd
, key_hnd
;
370 struct registry_value value
;
372 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
373 SEC_RIGHTS_MAXIMUM_ALLOWED
,
374 &hive_hnd
, &key_hnd
);
375 if (!NT_STATUS_IS_OK(status
)) {
376 d_fprintf(stderr
, "registry_openkey failed: %s\n",
381 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
382 d_fprintf(stderr
, "Too many args for type %s\n", argv
[2]);
383 return NT_STATUS_NOT_IMPLEMENTED
;
386 if (strequal(argv
[2], "dword")) {
387 value
.type
= REG_DWORD
;
388 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
390 else if (strequal(argv
[2], "sz")) {
392 value
.v
.sz
.len
= strlen(argv
[3])+1;
393 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
396 d_fprintf(stderr
, "type \"%s\" not implemented\n", argv
[2]);
397 status
= NT_STATUS_NOT_IMPLEMENTED
;
401 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
404 if (!NT_STATUS_IS_OK(status
)) {
405 d_fprintf(stderr
, "registry_setvalue failed: %s\n",
410 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
411 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
416 static int rpc_registry_setvalue( int argc
, const char **argv
)
419 d_fprintf(stderr
, "usage: net rpc registry setvalue <key> "
420 "<valuename> <type> [<val>]+\n");
424 return run_rpc_command( NULL
, PI_WINREG
, 0,
425 rpc_registry_setvalue_internal
, argc
, argv
);
428 static NTSTATUS
rpc_registry_deletevalue_internal(const DOM_SID
*domain_sid
,
429 const char *domain_name
,
430 struct cli_state
*cli
,
431 struct rpc_pipe_client
*pipe_hnd
,
436 struct policy_handle hive_hnd
, key_hnd
;
438 struct winreg_String valuename
;
440 ZERO_STRUCT(valuename
);
442 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
443 SEC_RIGHTS_MAXIMUM_ALLOWED
,
444 &hive_hnd
, &key_hnd
);
445 if (!NT_STATUS_IS_OK(status
)) {
446 d_fprintf(stderr
, "registry_openkey failed: %s\n",
451 valuename
.name
= argv
[1];
453 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
456 if (!NT_STATUS_IS_OK(status
)) {
457 d_fprintf(stderr
, "registry_deletevalue failed: %s\n",
461 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
462 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
467 static int rpc_registry_deletevalue( int argc
, const char **argv
)
470 d_fprintf(stderr
, "usage: net rpc registry deletevalue <key> "
475 return run_rpc_command( NULL
, PI_WINREG
, 0,
476 rpc_registry_deletevalue_internal
, argc
, argv
);
479 static NTSTATUS
rpc_registry_createkey_internal(const DOM_SID
*domain_sid
,
480 const char *domain_name
,
481 struct cli_state
*cli
,
482 struct rpc_pipe_client
*pipe_hnd
,
488 struct policy_handle hive_hnd
, key_hnd
;
489 struct winreg_String key
, keyclass
;
490 enum winreg_CreateAction action
;
494 ZERO_STRUCT(keyclass
);
496 if (!reg_hive_key(argv
[0], &hive
, &key
.name
)) {
497 return NT_STATUS_INVALID_PARAMETER
;
500 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
501 SEC_RIGHTS_MAXIMUM_ALLOWED
,
503 if (!(NT_STATUS_IS_OK(status
))) {
507 action
= REG_ACTION_NONE
;
510 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
511 keyclass
, 0, REG_KEY_READ
, NULL
,
512 &key_hnd
, &action
, NULL
);
513 if (!NT_STATUS_IS_OK(status
)) {
514 d_fprintf(stderr
, "createkey returned %s\n",
516 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
521 case REG_ACTION_NONE
:
522 d_printf("createkey did nothing -- huh?\n");
524 case REG_CREATED_NEW_KEY
:
525 d_printf("createkey created %s\n", argv
[0]);
527 case REG_OPENED_EXISTING_KEY
:
528 d_printf("createkey opened existing %s\n", argv
[0]);
532 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
533 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
538 static int rpc_registry_createkey( int argc
, const char **argv
)
541 d_fprintf(stderr
, "usage: net rpc registry createkey <key>\n");
545 return run_rpc_command( NULL
, PI_WINREG
, 0,
546 rpc_registry_createkey_internal
, argc
, argv
);
549 static NTSTATUS
rpc_registry_deletekey_internal(const DOM_SID
*domain_sid
,
550 const char *domain_name
,
551 struct cli_state
*cli
,
552 struct rpc_pipe_client
*pipe_hnd
,
558 struct policy_handle hive_hnd
;
559 struct winreg_String key
;
564 if (!reg_hive_key(argv
[0], &hive
, &key
.name
)) {
565 return NT_STATUS_INVALID_PARAMETER
;
568 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
569 SEC_RIGHTS_MAXIMUM_ALLOWED
,
571 if (!(NT_STATUS_IS_OK(status
))) {
575 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
576 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
578 if (!NT_STATUS_IS_OK(status
)) {
579 d_fprintf(stderr
, "deletekey returned %s\n",
586 static int rpc_registry_deletekey( int argc
, const char **argv
)
589 d_fprintf(stderr
, "usage: net rpc registry deletekey <key>\n");
593 return run_rpc_command( NULL
, PI_WINREG
, 0,
594 rpc_registry_deletekey_internal
, argc
, argv
);
597 /********************************************************************
598 ********************************************************************/
600 static NTSTATUS
rpc_registry_enumerate_internal(const DOM_SID
*domain_sid
,
601 const char *domain_name
,
602 struct cli_state
*cli
,
603 struct rpc_pipe_client
*pipe_hnd
,
608 POLICY_HND pol_hive
, pol_key
;
610 uint32 num_subkeys
= 0;
611 uint32 num_values
= 0;
612 char **names
= NULL
, **classes
= NULL
;
613 NTTIME
**modtimes
= NULL
;
615 struct registry_value
**values
= NULL
;
618 d_printf("Usage: net rpc registry enumerate <path> [recurse]\n");
619 d_printf("Example: net rpc registry enumerate 'HKLM\\Software\\Samba'\n");
623 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
624 &pol_hive
, &pol_key
);
625 if (!NT_STATUS_IS_OK(status
)) {
626 d_fprintf(stderr
, "registry_openkey failed: %s\n",
631 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
632 &names
, &classes
, &modtimes
);
633 if (!NT_STATUS_IS_OK(status
)) {
634 d_fprintf(stderr
, "enumerating keys failed: %s\n",
639 for (i
=0; i
<num_subkeys
; i
++) {
640 d_printf("Keyname = %s\n", names
[i
]);
641 d_printf("Modtime = %s\n", modtimes
[i
]
642 ? http_timestring(nt_time_to_unix(*modtimes
[i
]))
647 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
649 if (!NT_STATUS_IS_OK(status
)) {
650 d_fprintf(stderr
, "enumerating values failed: %s\n",
655 for (i
=0; i
<num_values
; i
++) {
656 struct registry_value
*v
= values
[i
];
657 d_printf("Valuename = %s\n", names
[i
]);
658 d_printf("Type = %s\n",
659 reg_type_lookup(v
->type
));
662 d_printf("Value = %d\n", v
->v
.dword
);
666 d_printf("Value = \"%s\"\n", v
->v
.sz
.str
);
670 for (j
= 0; j
< v
->v
.multi_sz
.num_strings
; j
++) {
671 d_printf("Value[%3.3d] = \"%s\"\n", j
,
672 v
->v
.multi_sz
.strings
[j
]);
677 d_printf("Value = %d bytes\n",
678 (int)v
->v
.binary
.length
);
681 d_printf("Value = <unprintable>\n");
688 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
689 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
694 /********************************************************************
695 ********************************************************************/
697 static int rpc_registry_enumerate( int argc
, const char **argv
)
699 return run_rpc_command( NULL
, PI_WINREG
, 0,
700 rpc_registry_enumerate_internal
, argc
, argv
);
703 /********************************************************************
704 ********************************************************************/
706 static NTSTATUS
rpc_registry_save_internal(const DOM_SID
*domain_sid
,
707 const char *domain_name
,
708 struct cli_state
*cli
,
709 struct rpc_pipe_client
*pipe_hnd
,
714 WERROR result
= WERR_GENERAL_FAILURE
;
715 POLICY_HND pol_hive
, pol_key
;
716 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
717 struct winreg_String filename
;
720 d_printf("Usage: net rpc registry backup <path> <file> \n");
724 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
725 &pol_hive
, &pol_key
);
726 if (!NT_STATUS_IS_OK(status
)) {
727 d_fprintf(stderr
, "registry_openkey failed: %s\n",
732 filename
.name
= argv
[1];
733 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
734 if ( !W_ERROR_IS_OK(result
) ) {
735 d_fprintf(stderr
, "Unable to save [%s] to %s:%s\n", argv
[0], cli
->desthost
, argv
[1]);
740 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
741 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
746 /********************************************************************
747 ********************************************************************/
749 static int rpc_registry_save( int argc
, const char **argv
)
751 return run_rpc_command( NULL
, PI_WINREG
, 0,
752 rpc_registry_save_internal
, argc
, argv
);
756 /********************************************************************
757 ********************************************************************/
759 static void dump_values( REGF_NK_REC
*nk
)
762 char *data_str
= NULL
;
763 uint32 data_size
, data
;
768 for ( i
=0; i
<nk
->num_values
; i
++ ) {
769 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
770 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
772 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
773 switch ( nk
->values
[i
].type
) {
775 rpcstr_pull_talloc(talloc_tos(),
783 d_printf( "%s", data_str
);
787 for ( j
=0; j
<data_size
; j
++ ) {
788 d_printf( "%c", nk
->values
[i
].data
[j
] );
792 data
= IVAL( nk
->values
[i
].data
, 0 );
793 d_printf("0x%x", data
);
796 for ( j
=0; j
<data_size
; j
++ ) {
797 d_printf( "%x", nk
->values
[i
].data
[j
] );
810 /********************************************************************
811 ********************************************************************/
813 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
817 /* depth first dump of the registry tree */
819 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
821 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
824 d_printf("[%s]\n", regpath
);
827 dump_registry_tree( file
, key
, regpath
);
834 /********************************************************************
835 ********************************************************************/
837 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
838 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
839 const char *parentpath
)
841 REGF_NK_REC
*key
, *subkey
;
842 REGVAL_CTR
*values
= NULL
;
843 REGSUBKEY_CTR
*subkeys
= NULL
;
847 if ( !( subkeys
= TALLOC_ZERO_P( infile
->mem_ctx
, REGSUBKEY_CTR
)) ) {
848 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
852 if ( !(values
= TALLOC_ZERO_P( subkeys
, REGVAL_CTR
)) ) {
853 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
854 TALLOC_FREE(subkeys
);
858 /* copy values into the REGVAL_CTR */
860 for ( i
=0; i
<nk
->num_values
; i
++ ) {
861 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
862 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
865 /* copy subkeys into the REGSUBKEY_CTR */
867 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
868 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
871 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
873 /* write each one of the subkeys out */
875 path
= talloc_asprintf(subkeys
,
881 TALLOC_FREE(subkeys
);
885 nk
->subkey_index
= 0;
886 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
887 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
890 d_printf("[%s]\n", path
);
891 TALLOC_FREE(subkeys
);
896 /********************************************************************
897 ********************************************************************/
899 static int rpc_registry_dump( int argc
, const char **argv
)
905 d_printf("Usage: net rpc registry dump <file> \n");
909 d_printf("Opening %s....", argv
[0]);
910 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
911 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
916 /* get the root of the registry file */
918 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
919 d_fprintf(stderr
, "Could not get rootkey\n");
920 regfio_close( registry
);
923 d_printf("[%s]\n", nk
->keyname
);
927 dump_registry_tree( registry
, nk
, nk
->keyname
);
930 talloc_report_full( registry
->mem_ctx
, stderr
);
932 d_printf("Closing registry...");
933 regfio_close( registry
);
939 /********************************************************************
940 ********************************************************************/
942 static int rpc_registry_copy( int argc
, const char **argv
)
944 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
949 d_printf("Usage: net rpc registry copy <srcfile> <newfile>\n");
953 d_printf("Opening %s....", argv
[0]);
954 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
955 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
960 d_printf("Opening %s....", argv
[1]);
961 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
962 d_fprintf(stderr
, "Failed to open %s for writing\n", argv
[1]);
967 /* get the root of the registry file */
969 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
970 d_fprintf(stderr
, "Could not get rootkey\n");
973 d_printf("RootKey: [%s]\n", nk
->keyname
);
975 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
981 d_printf("Closing %s...", argv
[1]);
983 regfio_close( outfile
);
987 d_printf("Closing %s...", argv
[0]);
989 regfio_close( infile
);
996 /********************************************************************
997 ********************************************************************/
999 static NTSTATUS
rpc_registry_getsd_internal(const DOM_SID
*domain_sid
,
1000 const char *domain_name
,
1001 struct cli_state
*cli
,
1002 struct rpc_pipe_client
*pipe_hnd
,
1003 TALLOC_CTX
*mem_ctx
,
1007 POLICY_HND pol_hive
, pol_key
;
1009 enum ndr_err_code ndr_err
;
1010 struct KeySecurityData
*sd
= NULL
;
1013 struct security_descriptor sec_desc
;
1014 uint32_t access_mask
= REG_KEY_READ
|
1015 SEC_RIGHT_MAXIMUM_ALLOWED
|
1016 SEC_RIGHT_SYSTEM_SECURITY
;
1018 if (argc
<1 || argc
> 2) {
1019 d_printf("Usage: net rpc registry getsd <path> <secinfo>\n");
1020 d_printf("Example: net rpc registry getsd 'HKLM\\Software\\Samba'\n");
1021 return NT_STATUS_OK
;
1024 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1026 &pol_hive
, &pol_key
);
1027 if (!NT_STATUS_IS_OK(status
)) {
1028 d_fprintf(stderr
, "registry_openkey failed: %s\n",
1033 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1035 status
= NT_STATUS_NO_MEMORY
;
1042 sscanf(argv
[1], "%x", &sec_info
);
1044 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1047 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1048 if (!NT_STATUS_IS_OK(status
)) {
1049 d_fprintf(stderr
, "getting sd failed: %s\n",
1054 blob
.data
= sd
->data
;
1055 blob
.length
= sd
->size
;
1057 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, &sec_desc
,
1058 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1059 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1060 status
= ndr_map_error2ntstatus(ndr_err
);
1063 status
= NT_STATUS_OK
;
1065 display_sec_desc(&sec_desc
);
1068 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1069 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1075 static int rpc_registry_getsd(int argc
, const char **argv
)
1077 return run_rpc_command(NULL
, PI_WINREG
, 0,
1078 rpc_registry_getsd_internal
, argc
, argv
);
1081 /********************************************************************
1082 ********************************************************************/
1084 int net_rpc_registry(int argc
, const char **argv
)
1086 struct functable2 func
[] = {
1087 { "enumerate", rpc_registry_enumerate
,
1088 "Enumerate registry keys and values" },
1089 { "createkey", rpc_registry_createkey
,
1090 "Create a new registry key" },
1091 { "deletekey", rpc_registry_deletekey
,
1092 "Delete a registry key" },
1093 { "setvalue", rpc_registry_setvalue
,
1094 "Set a new registry value" },
1095 { "deletevalue", rpc_registry_deletevalue
,
1096 "Delete a registry value" },
1097 { "save", rpc_registry_save
,
1098 "Save a registry file" },
1099 { "dump", rpc_registry_dump
,
1100 "Dump a registry file" },
1101 { "copy", rpc_registry_copy
,
1102 "Copy a registry file" },
1103 { "getsd", rpc_registry_getsd
,
1104 "Get security descriptor" },
1108 return net_run_function2(argc
, argv
, "net rpc registry", func
);