00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "includes.h"
00021 #include "utils/net.h"
00022 #include "regfio.h"
00023 #include "reg_objects.h"
00024
00025
00026
00027
00028 char* dump_regval_type( uint32 type )
00029 {
00030 static fstring string;
00031
00032 switch (type) {
00033 case REG_SZ:
00034 fstrcpy( string, "REG_SZ" );
00035 break;
00036 case REG_MULTI_SZ:
00037 fstrcpy( string, "REG_MULTI_SZ" );
00038 break;
00039 case REG_EXPAND_SZ:
00040 fstrcpy( string, "REG_EXPAND_SZ" );
00041 break;
00042 case REG_DWORD:
00043 fstrcpy( string, "REG_DWORD" );
00044 break;
00045 case REG_BINARY:
00046 fstrcpy( string, "REG_BINARY" );
00047 break;
00048 default:
00049 fstr_sprintf( string, "UNKNOWN [%d]", type );
00050 }
00051
00052 return string;
00053 }
00054
00055
00056
00057 void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
00058 {
00059 pstring string;
00060 uint32 value;
00061
00062 switch (type) {
00063 case REG_SZ:
00064 rpcstr_pull( string, buffer->buffer, sizeof(string), -1, STR_TERMINATE );
00065 d_printf("%s\n", string);
00066 break;
00067 case REG_MULTI_SZ:
00068 d_printf("\n");
00069 break;
00070 case REG_DWORD:
00071 value = IVAL( buffer->buffer, 0 );
00072 d_printf( "0x%x\n", value );
00073 break;
00074 case REG_BINARY:
00075 d_printf("\n");
00076 break;
00077
00078
00079 default:
00080 d_printf( "\tUnknown type [%d]\n", type );
00081 }
00082 }
00083
00084
00085
00086
00087 static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
00088 const char *domain_name,
00089 struct cli_state *cli,
00090 struct rpc_pipe_client *pipe_hnd,
00091 TALLOC_CTX *mem_ctx,
00092 int argc,
00093 const char **argv )
00094 {
00095 WERROR result = WERR_GENERAL_FAILURE;
00096 uint32 hive;
00097 pstring subpath;
00098 POLICY_HND pol_hive, pol_key;
00099 uint32 idx;
00100
00101 if (argc != 1 ) {
00102 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
00103 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
00104 return NT_STATUS_OK;
00105 }
00106
00107 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
00108 d_fprintf(stderr, "invalid registry path\n");
00109 return NT_STATUS_OK;
00110 }
00111
00112
00113
00114 result = rpccli_reg_connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
00115 if ( !W_ERROR_IS_OK(result) ) {
00116 d_fprintf(stderr, "Unable to connect to remote registry\n");
00117 return werror_to_ntstatus(result);
00118 }
00119
00120 if ( strlen( subpath ) != 0 ) {
00121 result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
00122 if ( !W_ERROR_IS_OK(result) ) {
00123 d_fprintf(stderr, "Unable to open [%s]\n", argv[0]);
00124 return werror_to_ntstatus(result);
00125 }
00126 }
00127
00128
00129
00130 result = WERR_OK;
00131 idx = 0;
00132 while ( W_ERROR_IS_OK(result) ) {
00133 time_t modtime;
00134 fstring keyname, classname;
00135
00136 result = rpccli_reg_enum_key(pipe_hnd, mem_ctx, &pol_key, idx,
00137 keyname, classname, &modtime );
00138
00139 if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
00140 result = WERR_OK;
00141 break;
00142 }
00143
00144 d_printf("Keyname = %s\n", keyname );
00145 d_printf("Classname = %s\n", classname );
00146 d_printf("Modtime = %s\n", http_timestring(modtime) );
00147 d_printf("\n" );
00148
00149 idx++;
00150 }
00151
00152 if ( !W_ERROR_IS_OK(result) )
00153 goto out;
00154
00155
00156
00157 result = WERR_OK;
00158 idx = 0;
00159 while ( W_ERROR_IS_OK(result) ) {
00160 uint32 type;
00161 fstring name;
00162 REGVAL_BUFFER value;
00163
00164 fstrcpy( name, "" );
00165 ZERO_STRUCT( value );
00166
00167 result = rpccli_reg_enum_val(pipe_hnd, mem_ctx, &pol_key, idx,
00168 name, &type, &value );
00169
00170 if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
00171 result = WERR_OK;
00172 break;
00173 }
00174
00175 d_printf("Valuename = %s\n", name );
00176 d_printf("Type = %s\n", dump_regval_type(type) );
00177 d_printf("Data = " );
00178 dump_regval_buffer( type, &value );
00179 d_printf("\n" );
00180
00181 idx++;
00182 }
00183
00184
00185 out:
00186
00187
00188 if ( strlen( subpath ) != 0 )
00189 rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
00190 rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
00191
00192 return werror_to_ntstatus(result);
00193 }
00194
00195
00196
00197
00198 static int rpc_registry_enumerate( int argc, const char **argv )
00199 {
00200 return run_rpc_command( NULL, PI_WINREG, 0,
00201 rpc_registry_enumerate_internal, argc, argv );
00202 }
00203
00204
00205
00206
00207 static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
00208 const char *domain_name,
00209 struct cli_state *cli,
00210 struct rpc_pipe_client *pipe_hnd,
00211 TALLOC_CTX *mem_ctx,
00212 int argc,
00213 const char **argv )
00214 {
00215 WERROR result = WERR_GENERAL_FAILURE;
00216 uint32 hive;
00217 pstring subpath;
00218 POLICY_HND pol_hive, pol_key;
00219
00220 if (argc != 2 ) {
00221 d_printf("Usage: net rpc backup <path> <file> \n");
00222 return NT_STATUS_OK;
00223 }
00224
00225 if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
00226 d_fprintf(stderr, "invalid registry path\n");
00227 return NT_STATUS_OK;
00228 }
00229
00230
00231
00232 result = rpccli_reg_connect(pipe_hnd, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
00233 if ( !W_ERROR_IS_OK(result) ) {
00234 d_fprintf(stderr, "Unable to connect to remote registry\n");
00235 return werror_to_ntstatus(result);
00236 }
00237
00238 result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
00239 if ( !W_ERROR_IS_OK(result) ) {
00240 d_fprintf(stderr, "Unable to open [%s]\n", argv[0]);
00241 return werror_to_ntstatus(result);
00242 }
00243
00244 result = rpccli_reg_save_key(pipe_hnd, mem_ctx, &pol_key, argv[1] );
00245 if ( !W_ERROR_IS_OK(result) ) {
00246 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
00247 }
00248
00249
00250
00251
00252 rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
00253 rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
00254
00255 return werror_to_ntstatus(result);
00256 }
00257
00258
00259
00260
00261 static int rpc_registry_save( int argc, const char **argv )
00262 {
00263 return run_rpc_command( NULL, PI_WINREG, 0,
00264 rpc_registry_save_internal, argc, argv );
00265 }
00266
00267
00268
00269
00270
00271 static void dump_values( REGF_NK_REC *nk )
00272 {
00273 int i, j;
00274 pstring data_str;
00275 uint32 data_size, data;
00276
00277 if ( !nk->values )
00278 return;
00279
00280 for ( i=0; i<nk->num_values; i++ ) {
00281 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
00282 d_printf( "(%s) ", dump_regval_type( nk->values[i].type ) );
00283
00284 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
00285 switch ( nk->values[i].type ) {
00286 case REG_SZ:
00287 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
00288 d_printf( "%s", data_str );
00289 break;
00290 case REG_MULTI_SZ:
00291 case REG_EXPAND_SZ:
00292 for ( j=0; j<data_size; j++ ) {
00293 d_printf( "%c", nk->values[i].data[j] );
00294 }
00295 break;
00296 case REG_DWORD:
00297 data = IVAL( nk->values[i].data, 0 );
00298 d_printf("0x%x", data );
00299 break;
00300 case REG_BINARY:
00301 for ( j=0; j<data_size; j++ ) {
00302 d_printf( "%x", nk->values[i].data[j] );
00303 }
00304 break;
00305 default:
00306 d_printf("unknown");
00307 break;
00308 }
00309
00310 d_printf( "\n" );
00311 }
00312
00313 }
00314
00315
00316
00317
00318 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
00319 {
00320 REGF_NK_REC *key;
00321 pstring regpath;
00322
00323
00324
00325 while ( (key = regfio_fetch_subkey( file, nk )) ) {
00326 pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
00327 d_printf("[%s]\n", regpath );
00328 dump_values( key );
00329 d_printf("\n");
00330 dump_registry_tree( file, key, regpath );
00331 }
00332
00333 return True;
00334 }
00335
00336
00337
00338
00339 static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
00340 REGF_NK_REC *parent, REGF_FILE *outfile,
00341 const char *parentpath )
00342 {
00343 REGF_NK_REC *key, *subkey;
00344 REGVAL_CTR *values;
00345 REGSUBKEY_CTR *subkeys;
00346 int i;
00347 pstring path;
00348
00349 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
00350 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
00351 return False;
00352 }
00353
00354 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
00355 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
00356 return False;
00357 }
00358
00359
00360
00361 for ( i=0; i<nk->num_values; i++ ) {
00362 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
00363 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
00364 }
00365
00366
00367
00368 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
00369 regsubkey_ctr_addkey( subkeys, subkey->keyname );
00370 }
00371
00372 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
00373
00374
00375
00376 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
00377 nk->subkey_index = 0;
00378 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
00379 write_registry_tree( infile, subkey, key, outfile, path );
00380 }
00381
00382 TALLOC_FREE( subkeys );
00383
00384 d_printf("[%s]\n", path );
00385
00386 return True;
00387 }
00388
00389
00390
00391
00392 static int rpc_registry_dump( int argc, const char **argv )
00393 {
00394 REGF_FILE *registry;
00395 REGF_NK_REC *nk;
00396
00397 if (argc != 1 ) {
00398 d_printf("Usage: net rpc dump <file> \n");
00399 return 0;
00400 }
00401
00402 d_printf("Opening %s....", argv[0]);
00403 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
00404 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
00405 return 1;
00406 }
00407 d_printf("ok\n");
00408
00409
00410
00411 if ((nk = regfio_rootkey( registry )) == NULL) {
00412 d_fprintf(stderr, "Could not get rootkey\n");
00413 regfio_close( registry );
00414 return 1;
00415 }
00416 d_printf("[%s]\n", nk->keyname);
00417 dump_values( nk );
00418 d_printf("\n");
00419
00420 dump_registry_tree( registry, nk, nk->keyname );
00421
00422 #if 0
00423 talloc_report_full( registry->mem_ctx, stderr );
00424 #endif
00425 d_printf("Closing registry...");
00426 regfio_close( registry );
00427 d_printf("ok\n");
00428
00429 return 0;
00430 }
00431
00432
00433
00434
00435 static int rpc_registry_copy( int argc, const char **argv )
00436 {
00437 REGF_FILE *infile = NULL, *outfile = NULL;
00438 REGF_NK_REC *nk;
00439 int result = 1;
00440
00441 if (argc != 2 ) {
00442 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
00443 return 0;
00444 }
00445
00446 d_printf("Opening %s....", argv[0]);
00447 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
00448 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
00449 return 1;
00450 }
00451 d_printf("ok\n");
00452
00453 d_printf("Opening %s....", argv[1]);
00454 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
00455 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
00456 goto out;
00457 }
00458 d_printf("ok\n");
00459
00460
00461
00462 if ((nk = regfio_rootkey( infile )) == NULL) {
00463 d_fprintf(stderr, "Could not get rootkey\n");
00464 goto out;
00465 }
00466 d_printf("RootKey: [%s]\n", nk->keyname);
00467
00468 write_registry_tree( infile, nk, NULL, outfile, "" );
00469
00470 result = 0;
00471
00472 out:
00473
00474 d_printf("Closing %s...", argv[1]);
00475 if (outfile) {
00476 regfio_close( outfile );
00477 }
00478 d_printf("ok\n");
00479
00480 d_printf("Closing %s...", argv[0]);
00481 if (infile) {
00482 regfio_close( infile );
00483 }
00484 d_printf("ok\n");
00485
00486 return( result);
00487 }
00488
00489
00490
00491
00492 static int net_help_registry( int argc, const char **argv )
00493 {
00494 d_printf("net rpc registry enumerate <path> [recurse] Enumerate the subkeya and values for a given registry path\n");
00495 d_printf("net rpc registry save <path> <file> Backup a registry tree to a file on the server\n");
00496 d_printf("net rpc registry dump <file> Dump the contents of a registry file to stdout\n");
00497
00498 return -1;
00499 }
00500
00501
00502
00503
00504 int net_rpc_registry(int argc, const char **argv)
00505 {
00506 struct functable func[] = {
00507 {"enumerate", rpc_registry_enumerate},
00508 {"save", rpc_registry_save},
00509 {"dump", rpc_registry_dump},
00510 {"copy", rpc_registry_copy},
00511 {NULL, NULL}
00512 };
00513
00514 if ( argc )
00515 return net_run_function( argc, argv, func, net_help_registry );
00516
00517 return net_help_registry( argc, argv );
00518 }