summaryrefslogtreecommitdiff
path: root/source3/utils/net_rpc_registry.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-05-23 16:25:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:56:57 -0500
commitf0c650a38286c07b9f3e83139c15bfbadc70ad5f (patch)
tree2c63cd42bf12e46c94628a82a40b19db47fd0aae /source3/utils/net_rpc_registry.c
parente2404c81295fe3468c9b635b549f1b16f5c5f323 (diff)
downloadsamba-f0c650a38286c07b9f3e83139c15bfbadc70ad5f.tar.gz
samba-f0c650a38286c07b9f3e83139c15bfbadc70ad5f.tar.bz2
samba-f0c650a38286c07b9f3e83139c15bfbadc70ad5f.zip
r6942: * merging the registry changes back to the 3.0 tree
* removing the testprns tool (This used to be commit 81ffb0dbbbd244623507880c323a3c37e2b8dc4d)
Diffstat (limited to 'source3/utils/net_rpc_registry.c')
-rw-r--r--source3/utils/net_rpc_registry.c495
1 files changed, 495 insertions, 0 deletions
diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c
new file mode 100644
index 0000000000..53378fadef
--- /dev/null
+++ b/source3/utils/net_rpc_registry.c
@@ -0,0 +1,495 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+ Copyright (C) Gerald (Jerry) Carter 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "includes.h"
+#include "utils/net.h"
+#include "regfio.h"
+#include "reg_objects.h"
+
+
+/********************************************************************
+********************************************************************/
+
+char* dump_regval_type( uint32 type )
+{
+ static fstring string;
+
+ switch (type) {
+ case REG_SZ:
+ fstrcpy( string, "REG_SZ" );
+ break;
+ case REG_MULTI_SZ:
+ fstrcpy( string, "REG_MULTI_SZ" );
+ break;
+ case REG_EXPAND_SZ:
+ fstrcpy( string, "REG_EXPAND_SZ" );
+ break;
+ case REG_DWORD:
+ fstrcpy( string, "REG_DWORD" );
+ break;
+ case REG_BINARY:
+ fstrcpy( string, "REG_BINARY" );
+ break;
+ default:
+ fstr_sprintf( string, "UNKNOWN [%d]", type );
+ }
+
+ return string;
+}
+/********************************************************************
+********************************************************************/
+
+void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
+{
+ pstring string;
+ uint32 value;
+
+ switch (type) {
+ case REG_SZ:
+ rpcstr_pull( string, buffer->buffer, sizeof(string), -1, STR_TERMINATE );
+ d_printf("%s\n", string);
+ break;
+ case REG_MULTI_SZ:
+ d_printf("\n");
+ break;
+ case REG_DWORD:
+ value = IVAL( buffer->buffer, 0 );
+ d_printf( "0x%x\n", value );
+ break;
+ case REG_BINARY:
+ d_printf("\n");
+ break;
+
+
+ default:
+ d_printf( "\tUnknown type [%d]\n", type );
+ }
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_registry_enumerate_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ WERROR result = WERR_GENERAL_FAILURE;
+ uint32 hive;
+ pstring subpath;
+ POLICY_HND pol_hive, pol_key;
+ uint32 idx;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc enumerate <path> [recurse]\n");
+ d_printf("Example:: net rpc enumerate 'HKLM\\Software\\Samba'\n");
+ return NT_STATUS_OK;
+ }
+
+ if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
+ d_printf("invalid registry path\n");
+ return NT_STATUS_OK;
+ }
+
+ /* open the top level hive and then the registry key */
+
+ result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Unable to connect to remote registry\n");
+ return werror_to_ntstatus(result);
+ }
+
+ result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Unable to open [%s]\n", argv[0]);
+ return werror_to_ntstatus(result);
+ }
+
+ /* get the subkeys */
+
+ result = WERR_OK;
+ idx = 0;
+ while ( W_ERROR_IS_OK(result) ) {
+ time_t modtime;
+ fstring keyname, classname;
+
+ result = cli_reg_enum_key( cli, mem_ctx, &pol_key, idx,
+ keyname, classname, &modtime );
+
+ if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
+ result = WERR_OK;
+ break;
+ }
+
+ d_printf("Keyname = %s\n", keyname );
+ d_printf("Classname = %s\n", classname );
+ d_printf("Modtime = %s\n", http_timestring(modtime) );
+ d_printf("\n" );
+
+ idx++;
+ }
+
+ if ( !W_ERROR_IS_OK(result) )
+ goto out;
+
+ /* get the values */
+
+ result = WERR_OK;
+ idx = 0;
+ while ( W_ERROR_IS_OK(result) ) {
+ uint32 type;
+ fstring name;
+ REGVAL_BUFFER value;
+
+ fstrcpy( name, "" );
+ ZERO_STRUCT( value );
+
+ result = cli_reg_enum_val( cli, mem_ctx, &pol_key, idx,
+ name, &type, &value );
+
+ if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
+ result = WERR_OK;
+ break;
+ }
+
+ d_printf("Valuename = %s\n", name );
+ d_printf("Type = %s\n", dump_regval_type(type) );
+ d_printf("Data = " );
+ dump_regval_buffer( type, &value );
+ d_printf("\n" );
+
+ idx++;
+ }
+
+
+out:
+ /* cleanup */
+
+ cli_reg_close( cli, mem_ctx, &pol_key );
+ cli_reg_close( cli, mem_ctx, &pol_hive );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_registry_enumerate( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_WINREG, 0,
+ rpc_registry_enumerate_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_registry_backup_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ WERROR result = WERR_GENERAL_FAILURE;
+ uint32 hive;
+ pstring subpath;
+ POLICY_HND pol_hive, pol_key;
+ REGF_FILE *regfile;
+
+ if (argc != 2 ) {
+ d_printf("Usage: net rpc backup <path> <file> \n");
+ return NT_STATUS_OK;
+ }
+
+ if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
+ d_printf("invalid registry path\n");
+ return NT_STATUS_OK;
+ }
+
+ /* open the top level hive and then the registry key */
+
+ result = cli_reg_connect( cli, mem_ctx, hive, MAXIMUM_ALLOWED_ACCESS, &pol_hive );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Unable to connect to remote registry\n");
+ return werror_to_ntstatus(result);
+ }
+
+ result = cli_reg_open_entry( cli, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
+ if ( !W_ERROR_IS_OK(result) ) {
+ d_printf("Unable to open [%s]\n", argv[0]);
+ return werror_to_ntstatus(result);
+ }
+
+ /* open the file */
+
+ if ( !(regfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), 0600 )) ) {
+ d_printf("Unable to open registry file [%s]\n", argv[1]);
+ return werror_to_ntstatus(WERR_GENERAL_FAILURE);
+ }
+
+
+ /* cleanup */
+
+ regfio_close( regfile );
+ cli_reg_close( cli, mem_ctx, &pol_key );
+ cli_reg_close( cli, mem_ctx, &pol_hive );
+
+ return werror_to_ntstatus(result);
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_registry_backup( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_WINREG, 0,
+ rpc_registry_backup_internal, argc, argv );
+}
+
+
+/********************************************************************
+********************************************************************/
+
+static void dump_values( REGF_NK_REC *nk )
+{
+ int i, j;
+ pstring data_str;
+ uint32 data_size, data;
+
+ if ( !nk->values )
+ return;
+
+ for ( i=0; i<nk->num_values; i++ ) {
+ d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
+ d_printf( "(%s) ", dump_regval_type( nk->values[i].type ) );
+
+ data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
+ switch ( nk->values[i].type ) {
+ case REG_SZ:
+ rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
+ d_printf( "%s", data_str );
+ break;
+ case REG_MULTI_SZ:
+ case REG_EXPAND_SZ:
+ for ( j=0; j<data_size; j++ ) {
+ d_printf( "%c", nk->values[i].data[j] );
+ }
+ break;
+ case REG_DWORD:
+ data = IVAL( nk->values[i].data, 0 );
+ d_printf("0x%x", data );
+ break;
+ case REG_BINARY:
+ for ( j=0; j<data_size; j++ ) {
+ d_printf( "%x", nk->values[i].data[j] );
+ }
+ break;
+ default:
+ d_printf("unknown");
+ break;
+ }
+
+ d_printf( "\n" );
+ }
+
+}
+
+/********************************************************************
+********************************************************************/
+
+static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
+{
+ REGF_NK_REC *key;
+ pstring regpath;
+
+ /* depth first dump of the registry tree */
+
+ while ( (key = regfio_fetch_subkey( file, nk )) ) {
+ pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
+ d_printf("[%s]\n", regpath );
+ dump_values( key );
+ d_printf("\n");
+ dump_registry_tree( file, key, regpath );
+ }
+
+ return True;
+}
+
+/********************************************************************
+********************************************************************/
+
+static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
+ REGF_NK_REC *parent, REGF_FILE *outfile,
+ const char *parentpath )
+{
+ REGF_NK_REC *key, *subkey;
+ REGVAL_CTR values;
+ REGSUBKEY_CTR subkeys;
+ int i;
+ pstring path;
+
+ ZERO_STRUCT( values );
+ ZERO_STRUCT( subkeys );
+
+ regsubkey_ctr_init( &subkeys );
+ regval_ctr_init( &values );
+
+ /* copy values into the REGVAL_CTR */
+
+ for ( i=0; i<nk->num_values; i++ ) {
+ regval_ctr_addvalue( &values, nk->values[i].valuename, nk->values[i].type,
+ nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
+ }
+
+ /* copy subkeys into the REGSUBKEY_CTR */
+
+ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
+ regsubkey_ctr_addkey( &subkeys, subkey->keyname );
+ }
+
+ key = regfio_write_key( outfile, nk->keyname, &values, &subkeys, nk->sec_desc->sec_desc, parent );
+
+ /* write each one of the subkeys out */
+
+ pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
+ nk->subkey_index = 0;
+ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
+ write_registry_tree( infile, subkey, key, outfile, path );
+ }
+
+ regval_ctr_destroy( &values );
+ regsubkey_ctr_destroy( &subkeys );
+
+ d_printf("[%s]\n", path );
+
+ return True;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_registry_dump( int argc, const char **argv )
+{
+ REGF_FILE *registry;
+ REGF_NK_REC *nk;
+
+ if (argc != 1 ) {
+ d_printf("Usage: net rpc dump <file> \n");
+ return 0;
+ }
+
+ d_printf("Opening %s....", argv[0]);
+ if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
+ d_printf("Failed to open %s for reading\n", argv[0]);
+ return 1;
+ }
+ d_printf("ok\n");
+
+ /* get the root of the registry file */
+
+ nk = regfio_rootkey( registry );
+ d_printf("[%s]\n", nk->keyname);
+ dump_values( nk );
+ d_printf("\n");
+
+ dump_registry_tree( registry, nk, nk->keyname );
+
+#if 0
+ talloc_report_full( registry->mem_ctx, stderr );
+#endif
+ d_printf("Closing registry...");
+ regfio_close( registry );
+ d_printf("ok\n");
+
+ return 0;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_registry_copy( int argc, const char **argv )
+{
+ REGF_FILE *infile, *outfile;
+ REGF_NK_REC *nk;
+
+ if (argc != 2 ) {
+ d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
+ return 0;
+ }
+
+ d_printf("Opening %s....", argv[0]);
+ if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
+ d_printf("Failed to open %s for reading\n", argv[0]);
+ return 1;
+ }
+ d_printf("ok\n");
+
+ d_printf("Opening %s....", argv[1]);
+ if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
+ d_printf("Failed to open %s for writing\n", argv[1]);
+ return 1;
+ }
+ d_printf("ok\n");
+
+ /* get the root of the registry file */
+
+ nk = regfio_rootkey( infile );
+ d_printf("RootKey: [%s]\n", nk->keyname);
+
+ write_registry_tree( infile, nk, NULL, outfile, "" );
+
+ d_printf("Closing %s...", argv[1]);
+ regfio_close( outfile );
+ d_printf("ok\n");
+
+ d_printf("Closing %s...", argv[0]);
+ regfio_close( infile );
+ d_printf("ok\n");
+
+ return 0;
+}
+
+/********************************************************************
+********************************************************************/
+
+static int net_help_registry( int argc, const char **argv )
+{
+ d_printf("net rpc registry enumerate <path> [recurse] Enumerate the subkeya and values for a given registry path\n");
+ d_printf("net rpc registry backup <path> <file> Backup a registry tree to a local file\n");
+ d_printf("net rpc registry dump <file> Dump the contents of a registry file to stdout\n");
+
+ return -1;
+}
+
+/********************************************************************
+********************************************************************/
+
+int net_rpc_registry(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"enumerate", rpc_registry_enumerate},
+ {"backup", rpc_registry_backup},
+ {"dump", rpc_registry_dump},
+ {"copy", rpc_registry_copy},
+ {NULL, NULL}
+ };
+
+ if ( argc )
+ return net_run_function( argc, argv, func, net_help_registry );
+
+ return net_help_registry( argc, argv );
+}
+
+