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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include "utils/net.h"
24 #include "reg_objects.h"
26 /********************************************************************
27 ********************************************************************/
29 void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
36 rpcstr_pull( string, buffer->buffer, sizeof(string), -1, STR_TERMINATE );
37 d_printf("%s\n", string);
45 if (!NT_STATUS_IS_OK(reg_pull_multi_sz(NULL, buffer->buffer,
49 d_printf("reg_pull_multi_sz failed\n");
53 for (i=0; i<num_values; i++) {
54 d_printf("%s\n", values[i]);
60 value = IVAL( buffer->buffer, 0 );
61 d_printf( "0x%x\n", value );
69 d_printf( "\tUnknown type [%d]\n", type );
73 /********************************************************************
74 ********************************************************************/
76 static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
77 const char *domain_name,
78 struct cli_state *cli,
79 struct rpc_pipe_client *pipe_hnd,
84 WERROR result = WERR_GENERAL_FAILURE;
87 POLICY_HND pol_hive, pol_key;
90 struct winreg_String subkeyname;
91 struct winreg_String classname;
92 uint32 num_subkeys, max_subkeylen, max_classlen;
93 uint32 num_values, max_valnamelen, max_valbufsize;
95 NTTIME last_changed_time;
96 struct winreg_StringBuf subkey_namebuf;
101 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
102 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
106 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
107 d_fprintf(stderr, "invalid registry path\n");
111 /* open the top level hive and then the registry key */
113 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
114 if ( !NT_STATUS_IS_OK(status) ) {
115 d_fprintf(stderr, "Unable to connect to remote registry: "
116 "%s\n", nt_errstr(status));
120 subkeyname.name = subpath;
121 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, &pol_hive, subkeyname,
122 0, MAXIMUM_ALLOWED_ACCESS, &pol_key );
123 if ( !NT_STATUS_IS_OK(status) ) {
124 d_fprintf(stderr, "Unable to open [%s]: %s\n", argv[0],
126 return werror_to_ntstatus(result);
129 classname.name = NULL;
130 status = rpccli_winreg_QueryInfoKey( pipe_hnd, mem_ctx, &pol_key,
131 &classname, &num_subkeys, &max_subkeylen,
132 &max_classlen, &num_values, &max_valnamelen,
133 &max_valbufsize, &secdescsize, &last_changed_time );
135 if ( !NT_STATUS_IS_OK(status) ) {
136 d_fprintf(stderr, "Unable to determine subkeys (%s)\n",
141 /* values do not include the terminating NULL */
146 if ( (name_buffer = TALLOC_ARRAY( mem_ctx, char, max_subkeylen )) == NULL ) {
147 d_fprintf(stderr, "Memory allocation error.\n");
148 return NT_STATUS_NO_MEMORY;
151 /* get the subkeys */
153 status = NT_STATUS_OK;
155 while ( NT_STATUS_IS_OK(status) ) {
156 struct winreg_StringBuf class_namebuf;
157 struct winreg_StringBuf *p_class_namebuf = &class_namebuf;
160 NTTIME *p_modtime = &modtime;
162 class_namebuf.name = NULL;
163 class_namebuf.size = 0;
164 class_namebuf.length = 0;
166 /* zero out each time */
168 subkey_namebuf.length = 0;
169 subkey_namebuf.size = max_subkeylen;
170 memset( name_buffer, 0x0, max_subkeylen );
171 subkey_namebuf.name = name_buffer;
173 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, &pol_key,
174 idx, &subkey_namebuf,
175 &p_class_namebuf, &p_modtime);
177 if ( W_ERROR_EQUAL(ntstatus_to_werror(status), WERR_NO_MORE_ITEMS) ) {
178 status = NT_STATUS_OK;
182 if ( !NT_STATUS_IS_OK(status) )
185 StrnCpy( kname, subkey_namebuf.name, MIN(subkey_namebuf.length,sizeof(kname))-1 );
186 kname[MIN(subkey_namebuf.length,sizeof(kname))-1] = '\0';
187 d_printf("Keyname = %s\n", kname);
188 d_printf("Modtime = %s\n",
189 http_timestring(nt_time_to_unix(modtime)) );
195 if ( !NT_STATUS_IS_OK(status) )
198 /* TALLOC_FREE( name_buffer ); */
200 if ( (name_buffer = TALLOC_ARRAY( mem_ctx, char, max_valnamelen )) == NULL ) {
201 d_fprintf(stderr, "Memory allocation error.\n");
202 return NT_STATUS_NO_MEMORY;
205 if ( (value_buffer = TALLOC_ARRAY( mem_ctx, uint8, max_valbufsize )) == NULL ) {
206 d_fprintf(stderr, "Memory allocation error.\n");
207 return NT_STATUS_NO_MEMORY;
212 status = NT_STATUS_OK;
214 while ( NT_STATUS_IS_OK(status) ) {
215 enum winreg_Type type = REG_NONE;
216 enum winreg_Type *ptype = &type;
219 uint32 data_size, value_length;
220 uint32 *pdata_size = &data_size;
221 uint32 *pvalue_length = &value_length;
222 struct winreg_StringBuf value_namebuf;
226 ZERO_STRUCT( value );
228 memset( name_buffer, 0x0, max_valnamelen );
229 value_namebuf.name = name_buffer;
230 value_namebuf.length = 0;
231 value_namebuf.size = max_valnamelen;
233 memset( value_buffer, 0x0, max_valbufsize );
235 data_size = max_valbufsize;
238 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, &pol_key,
239 idx, &value_namebuf, &ptype,
243 if ( W_ERROR_EQUAL(ntstatus_to_werror(status), WERR_NO_MORE_ITEMS) ) {
244 status = NT_STATUS_OK;
248 if ( !NT_STATUS_IS_OK(status) )
251 init_regval_buffer( &value, data, value_length );
253 StrnCpy( name, value_namebuf.name, MIN(max_valnamelen, sizeof(name)-1) );
254 name[MIN(max_valnamelen, sizeof(name)-1)] = '\0';
256 d_printf("Valuename = %s\n", name );
257 d_printf("Type = %s\n", reg_type_lookup(type));
258 d_printf("Data = " );
259 dump_regval_buffer( type, &value );
268 if ( strlen( subpath ) != 0 )
269 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
270 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
275 /********************************************************************
276 ********************************************************************/
278 static int rpc_registry_enumerate( int argc, const char **argv )
280 return run_rpc_command( NULL, PI_WINREG, 0,
281 rpc_registry_enumerate_internal, argc, argv );
284 /********************************************************************
285 ********************************************************************/
287 static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
288 const char *domain_name,
289 struct cli_state *cli,
290 struct rpc_pipe_client *pipe_hnd,
295 WERROR result = WERR_GENERAL_FAILURE;
298 POLICY_HND pol_hive, pol_key;
299 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
300 struct winreg_String subkeyname;
301 struct winreg_String filename;
304 d_printf("Usage: net rpc backup <path> <file> \n");
308 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
309 d_fprintf(stderr, "invalid registry path\n");
313 /* open the top level hive and then the registry key */
315 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
316 if ( !NT_STATUS_IS_OK(status) ) {
317 d_fprintf(stderr, "Unable to connect to remote registry\n");
321 subkeyname.name = subpath;
322 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, &pol_hive, subkeyname,
323 0, MAXIMUM_ALLOWED_ACCESS, &pol_key );
324 if ( !NT_STATUS_IS_OK(status) ) {
325 d_fprintf(stderr, "Unable to open [%s]\n", argv[0]);
326 return werror_to_ntstatus(result);
329 filename.name = argv[1];
330 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL );
331 if ( !W_ERROR_IS_OK(result) ) {
332 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
337 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
338 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
343 /********************************************************************
344 ********************************************************************/
346 static int rpc_registry_save( int argc, const char **argv )
348 return run_rpc_command( NULL, PI_WINREG, 0,
349 rpc_registry_save_internal, argc, argv );
353 /********************************************************************
354 ********************************************************************/
356 static void dump_values( REGF_NK_REC *nk )
360 uint32 data_size, data;
365 for ( i=0; i<nk->num_values; i++ ) {
366 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
367 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
369 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
370 switch ( nk->values[i].type ) {
372 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
373 d_printf( "%s", data_str );
377 for ( j=0; j<data_size; j++ ) {
378 d_printf( "%c", nk->values[i].data[j] );
382 data = IVAL( nk->values[i].data, 0 );
383 d_printf("0x%x", data );
386 for ( j=0; j<data_size; j++ ) {
387 d_printf( "%x", nk->values[i].data[j] );
400 /********************************************************************
401 ********************************************************************/
403 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
408 /* depth first dump of the registry tree */
410 while ( (key = regfio_fetch_subkey( file, nk )) ) {
411 pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
412 d_printf("[%s]\n", regpath );
415 dump_registry_tree( file, key, regpath );
421 /********************************************************************
422 ********************************************************************/
424 static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
425 REGF_NK_REC *parent, REGF_FILE *outfile,
426 const char *parentpath )
428 REGF_NK_REC *key, *subkey;
430 REGSUBKEY_CTR *subkeys;
434 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
435 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
439 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
440 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
444 /* copy values into the REGVAL_CTR */
446 for ( i=0; i<nk->num_values; i++ ) {
447 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
448 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
451 /* copy subkeys into the REGSUBKEY_CTR */
453 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
454 regsubkey_ctr_addkey( subkeys, subkey->keyname );
457 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
459 /* write each one of the subkeys out */
461 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
462 nk->subkey_index = 0;
463 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
464 write_registry_tree( infile, subkey, key, outfile, path );
467 TALLOC_FREE( subkeys );
469 d_printf("[%s]\n", path );
474 /********************************************************************
475 ********************************************************************/
477 static int rpc_registry_dump( int argc, const char **argv )
483 d_printf("Usage: net rpc dump <file> \n");
487 d_printf("Opening %s....", argv[0]);
488 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
489 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
494 /* get the root of the registry file */
496 if ((nk = regfio_rootkey( registry )) == NULL) {
497 d_fprintf(stderr, "Could not get rootkey\n");
498 regfio_close( registry );
501 d_printf("[%s]\n", nk->keyname);
505 dump_registry_tree( registry, nk, nk->keyname );
508 talloc_report_full( registry->mem_ctx, stderr );
510 d_printf("Closing registry...");
511 regfio_close( registry );
517 /********************************************************************
518 ********************************************************************/
520 static int rpc_registry_copy( int argc, const char **argv )
522 REGF_FILE *infile = NULL, *outfile = NULL;
527 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
531 d_printf("Opening %s....", argv[0]);
532 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
533 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
538 d_printf("Opening %s....", argv[1]);
539 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
540 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
545 /* get the root of the registry file */
547 if ((nk = regfio_rootkey( infile )) == NULL) {
548 d_fprintf(stderr, "Could not get rootkey\n");
551 d_printf("RootKey: [%s]\n", nk->keyname);
553 write_registry_tree( infile, nk, NULL, outfile, "" );
559 d_printf("Closing %s...", argv[1]);
561 regfio_close( outfile );
565 d_printf("Closing %s...", argv[0]);
567 regfio_close( infile );
574 /********************************************************************
575 ********************************************************************/
577 static int net_help_registry( int argc, const char **argv )
579 d_printf("net rpc registry enumerate <path> [recurse] Enumerate the subkeya and values for a given registry path\n");
580 d_printf("net rpc registry save <path> <file> Backup a registry tree to a file on the server\n");
581 d_printf("net rpc registry dump <file> Dump the contents of a registry file to stdout\n");
586 /********************************************************************
587 ********************************************************************/
589 int net_rpc_registry(int argc, const char **argv)
591 struct functable func[] = {
592 {"enumerate", rpc_registry_enumerate},
593 {"save", rpc_registry_save},
594 {"dump", rpc_registry_dump},
595 {"copy", rpc_registry_copy},
600 return net_run_function( argc, argv, func, net_help_registry );
602 return net_help_registry( argc, argv );