2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
4 Copyright (C) Gerald (Jerry) Carter 2005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "utils/net.h"
23 #include "reg_objects.h"
25 /********************************************************************
26 ********************************************************************/
28 void dump_regval_buffer( uint32 type
, REGVAL_BUFFER
*buffer
)
35 rpcstr_pull( string
, buffer
->buffer
, sizeof(string
), -1, STR_TERMINATE
);
36 d_printf("%s\n", string
);
44 if (!NT_STATUS_IS_OK(reg_pull_multi_sz(NULL
, buffer
->buffer
,
48 d_printf("reg_pull_multi_sz failed\n");
52 for (i
=0; i
<num_values
; i
++) {
53 d_printf("%s\n", values
[i
]);
59 value
= IVAL( buffer
->buffer
, 0 );
60 d_printf( "0x%x\n", value
);
68 d_printf( "\tUnknown type [%d]\n", type
);
72 /********************************************************************
73 ********************************************************************/
75 static NTSTATUS
rpc_registry_enumerate_internal(const DOM_SID
*domain_sid
,
76 const char *domain_name
,
77 struct cli_state
*cli
,
78 struct rpc_pipe_client
*pipe_hnd
,
83 WERROR result
= WERR_GENERAL_FAILURE
;
86 POLICY_HND pol_hive
, pol_key
;
90 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
91 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
95 if ( !reg_split_hive( argv
[0], &hive
, subpath
) ) {
96 d_fprintf(stderr
, "invalid registry path\n");
100 /* open the top level hive and then the registry key */
102 result
= rpccli_reg_connect(pipe_hnd
, mem_ctx
, hive
, MAXIMUM_ALLOWED_ACCESS
, &pol_hive
);
103 if ( !W_ERROR_IS_OK(result
) ) {
104 d_fprintf(stderr
, "Unable to connect to remote registry: "
105 "%s\n", dos_errstr(result
));
106 return werror_to_ntstatus(result
);
109 result
= rpccli_reg_open_entry(pipe_hnd
, mem_ctx
, &pol_hive
, subpath
,
110 MAXIMUM_ALLOWED_ACCESS
, &pol_key
);
111 if ( !W_ERROR_IS_OK(result
) ) {
112 d_fprintf(stderr
, "Unable to open [%s]: %s\n", argv
[0],
114 return werror_to_ntstatus(result
);
117 /* get the subkeys */
121 while ( W_ERROR_IS_OK(result
) ) {
123 fstring keyname
, classname
;
125 result
= rpccli_reg_enum_key(pipe_hnd
, mem_ctx
, &pol_key
, idx
,
126 keyname
, classname
, &modtime
);
128 if ( W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
133 d_printf("Keyname = %s\n", keyname
);
134 d_printf("Classname = %s\n", classname
);
135 d_printf("Modtime = %s\n", http_timestring(modtime
) );
141 if ( !W_ERROR_IS_OK(result
) )
148 while ( W_ERROR_IS_OK(result
) ) {
154 ZERO_STRUCT( value
);
156 result
= rpccli_reg_enum_val(pipe_hnd
, mem_ctx
, &pol_key
, idx
,
157 name
, &type
, &value
);
159 if ( W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
164 d_printf("Valuename = %s\n", name
);
165 d_printf("Type = %s\n", reg_type_lookup(type
));
166 d_printf("Data = " );
167 dump_regval_buffer( type
, &value
);
177 if ( strlen( subpath
) != 0 )
178 rpccli_reg_close(pipe_hnd
, mem_ctx
, &pol_key
);
179 rpccli_reg_close(pipe_hnd
, mem_ctx
, &pol_hive
);
181 return werror_to_ntstatus(result
);
184 /********************************************************************
185 ********************************************************************/
187 static int rpc_registry_enumerate( int argc
, const char **argv
)
189 return run_rpc_command( NULL
, PI_WINREG
, 0,
190 rpc_registry_enumerate_internal
, argc
, argv
);
193 /********************************************************************
194 ********************************************************************/
196 static NTSTATUS
rpc_registry_save_internal(const DOM_SID
*domain_sid
,
197 const char *domain_name
,
198 struct cli_state
*cli
,
199 struct rpc_pipe_client
*pipe_hnd
,
204 WERROR result
= WERR_GENERAL_FAILURE
;
207 POLICY_HND pol_hive
, pol_key
;
210 d_printf("Usage: net rpc backup <path> <file> \n");
214 if ( !reg_split_hive( argv
[0], &hive
, subpath
) ) {
215 d_fprintf(stderr
, "invalid registry path\n");
219 /* open the top level hive and then the registry key */
221 result
= rpccli_reg_connect(pipe_hnd
, mem_ctx
, hive
, MAXIMUM_ALLOWED_ACCESS
, &pol_hive
);
222 if ( !W_ERROR_IS_OK(result
) ) {
223 d_fprintf(stderr
, "Unable to connect to remote registry\n");
224 return werror_to_ntstatus(result
);
227 result
= rpccli_reg_open_entry(pipe_hnd
, mem_ctx
, &pol_hive
, subpath
, MAXIMUM_ALLOWED_ACCESS
, &pol_key
);
228 if ( !W_ERROR_IS_OK(result
) ) {
229 d_fprintf(stderr
, "Unable to open [%s]\n", argv
[0]);
230 return werror_to_ntstatus(result
);
233 result
= rpccli_reg_save_key(pipe_hnd
, mem_ctx
, &pol_key
, argv
[1] );
234 if ( !W_ERROR_IS_OK(result
) ) {
235 d_fprintf(stderr
, "Unable to save [%s] to %s:%s\n", argv
[0], cli
->desthost
, argv
[1]);
241 rpccli_reg_close(pipe_hnd
, mem_ctx
, &pol_key
);
242 rpccli_reg_close(pipe_hnd
, mem_ctx
, &pol_hive
);
244 return werror_to_ntstatus(result
);
247 /********************************************************************
248 ********************************************************************/
250 static int rpc_registry_save( int argc
, const char **argv
)
252 return run_rpc_command( NULL
, PI_WINREG
, 0,
253 rpc_registry_save_internal
, argc
, argv
);
257 /********************************************************************
258 ********************************************************************/
260 static void dump_values( REGF_NK_REC
*nk
)
264 uint32 data_size
, data
;
269 for ( i
=0; i
<nk
->num_values
; i
++ ) {
270 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
271 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
273 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
274 switch ( nk
->values
[i
].type
) {
276 rpcstr_pull( data_str
, nk
->values
[i
].data
, sizeof(data_str
), -1, STR_TERMINATE
);
277 d_printf( "%s", data_str
);
281 for ( j
=0; j
<data_size
; j
++ ) {
282 d_printf( "%c", nk
->values
[i
].data
[j
] );
286 data
= IVAL( nk
->values
[i
].data
, 0 );
287 d_printf("0x%x", data
);
290 for ( j
=0; j
<data_size
; j
++ ) {
291 d_printf( "%x", nk
->values
[i
].data
[j
] );
304 /********************************************************************
305 ********************************************************************/
307 static BOOL
dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
312 /* depth first dump of the registry tree */
314 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
315 pstr_sprintf( regpath
, "%s\\%s", parent
, key
->keyname
);
316 d_printf("[%s]\n", regpath
);
319 dump_registry_tree( file
, key
, regpath
);
325 /********************************************************************
326 ********************************************************************/
328 static BOOL
write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
329 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
330 const char *parentpath
)
332 REGF_NK_REC
*key
, *subkey
;
334 REGSUBKEY_CTR
*subkeys
;
338 if ( !( subkeys
= TALLOC_ZERO_P( infile
->mem_ctx
, REGSUBKEY_CTR
)) ) {
339 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
343 if ( !(values
= TALLOC_ZERO_P( subkeys
, REGVAL_CTR
)) ) {
344 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
348 /* copy values into the REGVAL_CTR */
350 for ( i
=0; i
<nk
->num_values
; i
++ ) {
351 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
352 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
355 /* copy subkeys into the REGSUBKEY_CTR */
357 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
358 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
361 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
363 /* write each one of the subkeys out */
365 pstr_sprintf( path
, "%s%s%s", parentpath
, parent
? "\\" : "", nk
->keyname
);
366 nk
->subkey_index
= 0;
367 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
368 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
371 TALLOC_FREE( subkeys
);
373 d_printf("[%s]\n", path
);
378 /********************************************************************
379 ********************************************************************/
381 static int rpc_registry_dump( int argc
, const char **argv
)
387 d_printf("Usage: net rpc dump <file> \n");
391 d_printf("Opening %s....", argv
[0]);
392 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
393 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
398 /* get the root of the registry file */
400 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
401 d_fprintf(stderr
, "Could not get rootkey\n");
402 regfio_close( registry
);
405 d_printf("[%s]\n", nk
->keyname
);
409 dump_registry_tree( registry
, nk
, nk
->keyname
);
412 talloc_report_full( registry
->mem_ctx
, stderr
);
414 d_printf("Closing registry...");
415 regfio_close( registry
);
421 /********************************************************************
422 ********************************************************************/
424 static int rpc_registry_copy( int argc
, const char **argv
)
426 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
431 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
435 d_printf("Opening %s....", argv
[0]);
436 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
437 d_fprintf(stderr
, "Failed to open %s for reading\n", argv
[0]);
442 d_printf("Opening %s....", argv
[1]);
443 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
444 d_fprintf(stderr
, "Failed to open %s for writing\n", argv
[1]);
449 /* get the root of the registry file */
451 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
452 d_fprintf(stderr
, "Could not get rootkey\n");
455 d_printf("RootKey: [%s]\n", nk
->keyname
);
457 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
463 d_printf("Closing %s...", argv
[1]);
465 regfio_close( outfile
);
469 d_printf("Closing %s...", argv
[0]);
471 regfio_close( infile
);
478 /********************************************************************
479 ********************************************************************/
481 static int net_help_registry( int argc
, const char **argv
)
483 d_printf("net rpc registry enumerate <path> [recurse] Enumerate the subkeya and values for a given registry path\n");
484 d_printf("net rpc registry save <path> <file> Backup a registry tree to a file on the server\n");
485 d_printf("net rpc registry dump <file> Dump the contents of a registry file to stdout\n");
490 /********************************************************************
491 ********************************************************************/
493 int net_rpc_registry(int argc
, const char **argv
)
495 struct functable func
[] = {
496 {"enumerate", rpc_registry_enumerate
},
497 {"save", rpc_registry_save
},
498 {"dump", rpc_registry_dump
},
499 {"copy", rpc_registry_copy
},
504 return net_run_function( argc
, argv
, func
, net_help_registry
);
506 return net_help_registry( argc
, argv
);