r7691: * add .gdbinit to the svn:ignore files
[Samba/gbeck.git] / source / utils / net_rpc_registry.c
blob8a97f64584a14db6d13e54cd4e6dd310b5da695d
1 /*
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. */
20 #include "includes.h"
21 #include "utils/net.h"
22 #include "regfio.h"
23 #include "reg_objects.h"
26 /********************************************************************
27 ********************************************************************/
29 char* dump_regval_type( uint32 type )
31 static fstring string;
33 switch (type) {
34 case REG_SZ:
35 fstrcpy( string, "REG_SZ" );
36 break;
37 case REG_MULTI_SZ:
38 fstrcpy( string, "REG_MULTI_SZ" );
39 break;
40 case REG_EXPAND_SZ:
41 fstrcpy( string, "REG_EXPAND_SZ" );
42 break;
43 case REG_DWORD:
44 fstrcpy( string, "REG_DWORD" );
45 break;
46 case REG_BINARY:
47 fstrcpy( string, "REG_BINARY" );
48 break;
49 default:
50 fstr_sprintf( string, "UNKNOWN [%d]", type );
53 return string;
55 /********************************************************************
56 ********************************************************************/
58 void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
60 pstring string;
61 uint32 value;
63 switch (type) {
64 case REG_SZ:
65 rpcstr_pull( string, buffer->buffer, sizeof(string), -1, STR_TERMINATE );
66 d_printf("%s\n", string);
67 break;
68 case REG_MULTI_SZ:
69 d_printf("\n");
70 break;
71 case REG_DWORD:
72 value = IVAL( buffer->buffer, 0 );
73 d_printf( "0x%x\n", value );
74 break;
75 case REG_BINARY:
76 d_printf("\n");
77 break;
80 default:
81 d_printf( "\tUnknown type [%d]\n", type );
85 /********************************************************************
86 ********************************************************************/
88 static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, const char *domain_name,
89 struct cli_state *cli, TALLOC_CTX *mem_ctx,
90 int argc, const char **argv )
92 WERROR result = WERR_GENERAL_FAILURE;
93 uint32 hive;
94 pstring subpath;
95 POLICY_HND pol_hive, pol_key;
96 uint32 idx;
98 if (argc != 1 ) {
99 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
100 d_printf("Example:: net rpc enumerate 'HKLM\\Software\\Samba'\n");
101 return NT_STATUS_OK;
104 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
105 d_printf("invalid registry path\n");
106 return NT_STATUS_OK;
109 /* open the top level hive and then the registry key */
111 result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
112 if ( !W_ERROR_IS_OK(result) ) {
113 d_printf("Unable to connect to remote registry\n");
114 return werror_to_ntstatus(result);
117 result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
118 if ( !W_ERROR_IS_OK(result) ) {
119 d_printf("Unable to open [%s]\n", argv[0]);
120 return werror_to_ntstatus(result);
123 /* get the subkeys */
125 result = WERR_OK;
126 idx = 0;
127 while ( W_ERROR_IS_OK(result) ) {
128 time_t modtime;
129 fstring keyname, classname;
131 result = cli_reg_enum_key( cli, mem_ctx, &pol_key, idx,
132 keyname, classname, &modtime );
134 if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
135 result = WERR_OK;
136 break;
139 d_printf("Keyname = %s\n", keyname );
140 d_printf("Classname = %s\n", classname );
141 d_printf("Modtime = %s\n", http_timestring(modtime) );
142 d_printf("\n" );
144 idx++;
147 if ( !W_ERROR_IS_OK(result) )
148 goto out;
150 /* get the values */
152 result = WERR_OK;
153 idx = 0;
154 while ( W_ERROR_IS_OK(result) ) {
155 uint32 type;
156 fstring name;
157 REGVAL_BUFFER value;
159 fstrcpy( name, "" );
160 ZERO_STRUCT( value );
162 result = cli_reg_enum_val( cli, mem_ctx, &pol_key, idx,
163 name, &type, &value );
165 if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
166 result = WERR_OK;
167 break;
170 d_printf("Valuename = %s\n", name );
171 d_printf("Type = %s\n", dump_regval_type(type) );
172 d_printf("Data = " );
173 dump_regval_buffer( type, &value );
174 d_printf("\n" );
176 idx++;
180 out:
181 /* cleanup */
183 cli_reg_close( cli, mem_ctx, &pol_key );
184 cli_reg_close( cli, mem_ctx, &pol_hive );
186 return werror_to_ntstatus(result);
189 /********************************************************************
190 ********************************************************************/
192 static int rpc_registry_enumerate( int argc, const char **argv )
194 return run_rpc_command( NULL, PI_WINREG, 0,
195 rpc_registry_enumerate_internal, argc, argv );
198 /********************************************************************
199 ********************************************************************/
201 static NTSTATUS rpc_registry_save_internal( const DOM_SID *domain_sid, const char *domain_name,
202 struct cli_state *cli, TALLOC_CTX *mem_ctx,
203 int argc, const char **argv )
205 WERROR result = WERR_GENERAL_FAILURE;
206 uint32 hive;
207 pstring subpath;
208 POLICY_HND pol_hive, pol_key;
210 if (argc != 2 ) {
211 d_printf("Usage: net rpc backup <path> <file> \n");
212 return NT_STATUS_OK;
215 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
216 d_printf("invalid registry path\n");
217 return NT_STATUS_OK;
220 /* open the top level hive and then the registry key */
222 result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
223 if ( !W_ERROR_IS_OK(result) ) {
224 d_printf("Unable to connect to remote registry\n");
225 return werror_to_ntstatus(result);
228 result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
229 if ( !W_ERROR_IS_OK(result) ) {
230 d_printf("Unable to open [%s]\n", argv[0]);
231 return werror_to_ntstatus(result);
234 result = cli_reg_save_key( cli, mem_ctx, &pol_key, argv[1] );
235 if ( !W_ERROR_IS_OK(result) ) {
236 d_printf("Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
240 /* cleanup */
242 cli_reg_close( cli, mem_ctx, &pol_key );
243 cli_reg_close( cli, mem_ctx, &pol_hive );
245 return werror_to_ntstatus(result);
248 /********************************************************************
249 ********************************************************************/
251 static int rpc_registry_save( int argc, const char **argv )
253 return run_rpc_command( NULL, PI_WINREG, 0,
254 rpc_registry_save_internal, argc, argv );
258 /********************************************************************
259 ********************************************************************/
261 static void dump_values( REGF_NK_REC *nk )
263 int i, j;
264 pstring data_str;
265 uint32 data_size, data;
267 if ( !nk->values )
268 return;
270 for ( i=0; i<nk->num_values; i++ ) {
271 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
272 d_printf( "(%s) ", dump_regval_type( nk->values[i].type ) );
274 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
275 switch ( nk->values[i].type ) {
276 case REG_SZ:
277 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
278 d_printf( "%s", data_str );
279 break;
280 case REG_MULTI_SZ:
281 case REG_EXPAND_SZ:
282 for ( j=0; j<data_size; j++ ) {
283 d_printf( "%c", nk->values[i].data[j] );
285 break;
286 case REG_DWORD:
287 data = IVAL( nk->values[i].data, 0 );
288 d_printf("0x%x", data );
289 break;
290 case REG_BINARY:
291 for ( j=0; j<data_size; j++ ) {
292 d_printf( "%x", nk->values[i].data[j] );
294 break;
295 default:
296 d_printf("unknown");
297 break;
300 d_printf( "\n" );
305 /********************************************************************
306 ********************************************************************/
308 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
310 REGF_NK_REC *key;
311 pstring regpath;
313 /* depth first dump of the registry tree */
315 while ( (key = regfio_fetch_subkey( file, nk )) ) {
316 pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
317 d_printf("[%s]\n", regpath );
318 dump_values( key );
319 d_printf("\n");
320 dump_registry_tree( file, key, regpath );
323 return True;
326 /********************************************************************
327 ********************************************************************/
329 static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
330 REGF_NK_REC *parent, REGF_FILE *outfile,
331 const char *parentpath )
333 REGF_NK_REC *key, *subkey;
334 REGVAL_CTR values;
335 REGSUBKEY_CTR subkeys;
336 int i;
337 pstring path;
339 regsubkey_ctr_init( &subkeys );
340 regval_ctr_init( &values );
342 /* copy values into the REGVAL_CTR */
344 for ( i=0; i<nk->num_values; i++ ) {
345 regval_ctr_addvalue( &values, nk->values[i].valuename, nk->values[i].type,
346 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
349 /* copy subkeys into the REGSUBKEY_CTR */
351 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
352 regsubkey_ctr_addkey( &subkeys, subkey->keyname );
355 key = regfio_write_key( outfile, nk->keyname, &values, &subkeys, nk->sec_desc->sec_desc, parent );
357 /* write each one of the subkeys out */
359 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
360 nk->subkey_index = 0;
361 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
362 write_registry_tree( infile, subkey, key, outfile, path );
365 regval_ctr_destroy( &values );
366 regsubkey_ctr_destroy( &subkeys );
368 d_printf("[%s]\n", path );
370 return True;
373 /********************************************************************
374 ********************************************************************/
376 static int rpc_registry_dump( int argc, const char **argv )
378 REGF_FILE *registry;
379 REGF_NK_REC *nk;
381 if (argc != 1 ) {
382 d_printf("Usage: net rpc dump <file> \n");
383 return 0;
386 d_printf("Opening %s....", argv[0]);
387 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
388 d_printf("Failed to open %s for reading\n", argv[0]);
389 return 1;
391 d_printf("ok\n");
393 /* get the root of the registry file */
395 nk = regfio_rootkey( registry );
396 d_printf("[%s]\n", nk->keyname);
397 dump_values( nk );
398 d_printf("\n");
400 dump_registry_tree( registry, nk, nk->keyname );
402 #if 0
403 talloc_report_full( registry->mem_ctx, stderr );
404 #endif
405 d_printf("Closing registry...");
406 regfio_close( registry );
407 d_printf("ok\n");
409 return 0;
412 /********************************************************************
413 ********************************************************************/
415 static int rpc_registry_copy( int argc, const char **argv )
417 REGF_FILE *infile, *outfile;
418 REGF_NK_REC *nk;
420 if (argc != 2 ) {
421 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
422 return 0;
425 d_printf("Opening %s....", argv[0]);
426 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
427 d_printf("Failed to open %s for reading\n", argv[0]);
428 return 1;
430 d_printf("ok\n");
432 d_printf("Opening %s....", argv[1]);
433 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
434 d_printf("Failed to open %s for writing\n", argv[1]);
435 return 1;
437 d_printf("ok\n");
439 /* get the root of the registry file */
441 nk = regfio_rootkey( infile );
442 d_printf("RootKey: [%s]\n", nk->keyname);
444 write_registry_tree( infile, nk, NULL, outfile, "" );
446 d_printf("Closing %s...", argv[1]);
447 regfio_close( outfile );
448 d_printf("ok\n");
450 d_printf("Closing %s...", argv[0]);
451 regfio_close( infile );
452 d_printf("ok\n");
454 return 0;
457 /********************************************************************
458 ********************************************************************/
460 static int net_help_registry( int argc, const char **argv )
462 d_printf("net rpc registry enumerate <path> [recurse] Enumerate the subkeya and values for a given registry path\n");
463 d_printf("net rpc registry save <path> <file> Backup a registry tree to a file on the server\n");
464 d_printf("net rpc registry dump <file> Dump the contents of a registry file to stdout\n");
466 return -1;
469 /********************************************************************
470 ********************************************************************/
472 int net_rpc_registry(int argc, const char **argv)
474 struct functable func[] = {
475 {"enumerate", rpc_registry_enumerate},
476 {"save", rpc_registry_save},
477 {"dump", rpc_registry_dump},
478 {"copy", rpc_registry_copy},
479 {NULL, NULL}
482 if ( argc )
483 return net_run_function( argc, argv, func, net_help_registry );
485 return net_help_registry( argc, argv );