r18799: Prepare query_disp_info to use the next idx from the last result entry
[Samba/bb.git] / source / utils / net_rpc_registry.c
blob3eaff901554be71987f6e861237e70c343192c04
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"
25 /********************************************************************
26 ********************************************************************/
28 void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
30 pstring string;
31 uint32 value;
33 switch (type) {
34 case REG_SZ:
35 rpcstr_pull( string, buffer->buffer, sizeof(string), -1, STR_TERMINATE );
36 d_printf("%s\n", string);
37 break;
38 case REG_MULTI_SZ: {
39 int i, num_values;
40 char **values;
42 d_printf("\n");
44 if (!NT_STATUS_IS_OK(reg_pull_multi_sz(NULL, buffer->buffer,
45 buffer->buf_len,
46 &num_values,
47 &values))) {
48 d_printf("reg_pull_multi_sz failed\n");
49 break;
52 for (i=0; i<num_values; i++) {
53 d_printf("%s\n", values[i]);
55 TALLOC_FREE(values);
56 break;
58 case REG_DWORD:
59 value = IVAL( buffer->buffer, 0 );
60 d_printf( "0x%x\n", value );
61 break;
62 case REG_BINARY:
63 d_printf("\n");
64 break;
67 default:
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,
79 TALLOC_CTX *mem_ctx,
80 int argc,
81 const char **argv )
83 WERROR result = WERR_GENERAL_FAILURE;
84 uint32 hive;
85 pstring subpath;
86 POLICY_HND pol_hive, pol_key;
87 uint32 idx;
89 if (argc != 1 ) {
90 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
91 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
92 return NT_STATUS_OK;
95 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
96 d_fprintf(stderr, "invalid registry path\n");
97 return NT_STATUS_OK;
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],
113 dos_errstr(result));
114 return werror_to_ntstatus(result);
117 /* get the subkeys */
119 result = WERR_OK;
120 idx = 0;
121 while ( W_ERROR_IS_OK(result) ) {
122 time_t modtime;
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) ) {
129 result = WERR_OK;
130 break;
133 d_printf("Keyname = %s\n", keyname );
134 d_printf("Classname = %s\n", classname );
135 d_printf("Modtime = %s\n", http_timestring(modtime) );
136 d_printf("\n" );
138 idx++;
141 if ( !W_ERROR_IS_OK(result) )
142 goto out;
144 /* get the values */
146 result = WERR_OK;
147 idx = 0;
148 while ( W_ERROR_IS_OK(result) ) {
149 uint32 type;
150 fstring name;
151 REGVAL_BUFFER value;
153 fstrcpy( name, "" );
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) ) {
160 result = WERR_OK;
161 break;
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 );
168 d_printf("\n" );
170 idx++;
174 out:
175 /* cleanup */
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,
200 TALLOC_CTX *mem_ctx,
201 int argc,
202 const char **argv )
204 WERROR result = WERR_GENERAL_FAILURE;
205 uint32 hive;
206 pstring subpath;
207 POLICY_HND pol_hive, pol_key;
209 if (argc != 2 ) {
210 d_printf("Usage: net rpc backup <path> <file> \n");
211 return NT_STATUS_OK;
214 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
215 d_fprintf(stderr, "invalid registry path\n");
216 return NT_STATUS_OK;
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]);
239 /* cleanup */
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 )
262 int i, j;
263 pstring data_str;
264 uint32 data_size, data;
266 if ( !nk->values )
267 return;
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 ) {
275 case REG_SZ:
276 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
277 d_printf( "%s", data_str );
278 break;
279 case REG_MULTI_SZ:
280 case REG_EXPAND_SZ:
281 for ( j=0; j<data_size; j++ ) {
282 d_printf( "%c", nk->values[i].data[j] );
284 break;
285 case REG_DWORD:
286 data = IVAL( nk->values[i].data, 0 );
287 d_printf("0x%x", data );
288 break;
289 case REG_BINARY:
290 for ( j=0; j<data_size; j++ ) {
291 d_printf( "%x", nk->values[i].data[j] );
293 break;
294 default:
295 d_printf("unknown");
296 break;
299 d_printf( "\n" );
304 /********************************************************************
305 ********************************************************************/
307 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
309 REGF_NK_REC *key;
310 pstring regpath;
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 );
317 dump_values( key );
318 d_printf("\n");
319 dump_registry_tree( file, key, regpath );
322 return True;
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;
333 REGVAL_CTR *values;
334 REGSUBKEY_CTR *subkeys;
335 int i;
336 pstring path;
338 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
339 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
340 return False;
343 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
344 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
345 return False;
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 );
375 return True;
378 /********************************************************************
379 ********************************************************************/
381 static int rpc_registry_dump( int argc, const char **argv )
383 REGF_FILE *registry;
384 REGF_NK_REC *nk;
386 if (argc != 1 ) {
387 d_printf("Usage: net rpc dump <file> \n");
388 return 0;
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]);
394 return 1;
396 d_printf("ok\n");
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 );
403 return 1;
405 d_printf("[%s]\n", nk->keyname);
406 dump_values( nk );
407 d_printf("\n");
409 dump_registry_tree( registry, nk, nk->keyname );
411 #if 0
412 talloc_report_full( registry->mem_ctx, stderr );
413 #endif
414 d_printf("Closing registry...");
415 regfio_close( registry );
416 d_printf("ok\n");
418 return 0;
421 /********************************************************************
422 ********************************************************************/
424 static int rpc_registry_copy( int argc, const char **argv )
426 REGF_FILE *infile = NULL, *outfile = NULL;
427 REGF_NK_REC *nk;
428 int result = 1;
430 if (argc != 2 ) {
431 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
432 return 0;
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]);
438 return 1;
440 d_printf("ok\n");
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]);
445 goto out;
447 d_printf("ok\n");
449 /* get the root of the registry file */
451 if ((nk = regfio_rootkey( infile )) == NULL) {
452 d_fprintf(stderr, "Could not get rootkey\n");
453 goto out;
455 d_printf("RootKey: [%s]\n", nk->keyname);
457 write_registry_tree( infile, nk, NULL, outfile, "" );
459 result = 0;
461 out:
463 d_printf("Closing %s...", argv[1]);
464 if (outfile) {
465 regfio_close( outfile );
467 d_printf("ok\n");
469 d_printf("Closing %s...", argv[0]);
470 if (infile) {
471 regfio_close( infile );
473 d_printf("ok\n");
475 return( result);
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");
487 return -1;
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},
500 {NULL, NULL}
503 if ( argc )
504 return net_run_function( argc, argv, func, net_help_registry );
506 return net_help_registry( argc, argv );