~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/utils/net_rpc_registry.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Samba Unix/Linux SMB client library 
3
 
   Distributed SMB/CIFS Server Management Utility 
4
 
   Copyright (C) Gerald (Jerry) Carter          2005
5
 
 
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.
10
 
   
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.
15
 
   
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.  */
19
 
 
20
 
#include "includes.h"
21
 
#include "utils/net.h"
22
 
#include "regfio.h"
23
 
#include "reg_objects.h"
24
 
 
25
 
/********************************************************************
26
 
********************************************************************/
27
 
 
28
 
void dump_regval_buffer( uint32 type, REGVAL_BUFFER *buffer )
29
 
{
30
 
        pstring string;
31
 
        uint32 value;
32
 
        
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;
41
 
 
42
 
                d_printf("\n");
43
 
 
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;
50
 
                }
51
 
 
52
 
                for (i=0; i<num_values; i++) {
53
 
                        d_printf("%s\n", values[i]);
54
 
                }
55
 
                TALLOC_FREE(values);
56
 
                break;
57
 
        }
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;
65
 
        
66
 
        
67
 
        default:
68
 
                d_printf( "\tUnknown type [%d]\n", type );
69
 
        }
70
 
}
71
 
 
72
 
/********************************************************************
73
 
********************************************************************/
74
 
 
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 )
82
 
{
83
 
        WERROR result = WERR_GENERAL_FAILURE;
84
 
        uint32 hive;
85
 
        pstring subpath;
86
 
        POLICY_HND pol_hive, pol_key; 
87
 
        uint32 idx;
88
 
        
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;
93
 
        }
94
 
        
95
 
        if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
96
 
                d_fprintf(stderr, "invalid registry path\n");
97
 
                return NT_STATUS_OK;
98
 
        }
99
 
        
100
 
        /* open the top level hive and then the registry key */
101
 
        
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);
107
 
        }
108
 
        
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);
115
 
        }
116
 
        
117
 
        /* get the subkeys */
118
 
        
119
 
        result = WERR_OK;
120
 
        idx = 0;
121
 
        while ( W_ERROR_IS_OK(result) ) {
122
 
                time_t modtime;
123
 
                fstring keyname, classname;
124
 
                
125
 
                result = rpccli_reg_enum_key(pipe_hnd, mem_ctx, &pol_key, idx, 
126
 
                        keyname, classname, &modtime );
127
 
                        
128
 
                if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
129
 
                        result = WERR_OK;
130
 
                        break;
131
 
                }
132
 
                        
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" );
137
 
 
138
 
                idx++;
139
 
        }
140
 
 
141
 
        if ( !W_ERROR_IS_OK(result) )
142
 
                goto out;
143
 
        
144
 
        /* get the values */
145
 
        
146
 
        result = WERR_OK;
147
 
        idx = 0;
148
 
        while ( W_ERROR_IS_OK(result) ) {
149
 
                uint32 type;
150
 
                fstring name;
151
 
                REGVAL_BUFFER value;
152
 
                
153
 
                fstrcpy( name, "" );
154
 
                ZERO_STRUCT( value );
155
 
                
156
 
                result = rpccli_reg_enum_val(pipe_hnd, mem_ctx, &pol_key, idx, 
157
 
                        name, &type, &value );
158
 
                        
159
 
                if ( W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
160
 
                        result = WERR_OK;
161
 
                        break;
162
 
                }
163
 
                        
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" );
169
 
 
170
 
                idx++;
171
 
        }
172
 
        
173
 
        
174
 
out:
175
 
        /* cleanup */
176
 
        
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 );
180
 
 
181
 
        return werror_to_ntstatus(result);
182
 
}
183
 
 
184
 
/********************************************************************
185
 
********************************************************************/
186
 
 
187
 
static int rpc_registry_enumerate( int argc, const char **argv )
188
 
{
189
 
        return run_rpc_command( NULL, PI_WINREG, 0, 
190
 
                rpc_registry_enumerate_internal, argc, argv );
191
 
}
192
 
 
193
 
/********************************************************************
194
 
********************************************************************/
195
 
 
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 )
203
 
{
204
 
        WERROR result = WERR_GENERAL_FAILURE;
205
 
        uint32 hive;
206
 
        pstring subpath;
207
 
        POLICY_HND pol_hive, pol_key; 
208
 
        
209
 
        if (argc != 2 ) {
210
 
                d_printf("Usage:    net rpc backup <path> <file> \n");
211
 
                return NT_STATUS_OK;
212
 
        }
213
 
        
214
 
        if ( !reg_split_hive( argv[0], &hive, subpath ) ) {
215
 
                d_fprintf(stderr, "invalid registry path\n");
216
 
                return NT_STATUS_OK;
217
 
        }
218
 
        
219
 
        /* open the top level hive and then the registry key */
220
 
        
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);
225
 
        }
226
 
        
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);
231
 
        }
232
 
        
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]);
236
 
        }
237
 
        
238
 
        
239
 
        /* cleanup */
240
 
        
241
 
        rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
242
 
        rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
243
 
 
244
 
        return werror_to_ntstatus(result);
245
 
}
246
 
 
247
 
/********************************************************************
248
 
********************************************************************/
249
 
 
250
 
static int rpc_registry_save( int argc, const char **argv )
251
 
{
252
 
        return run_rpc_command( NULL, PI_WINREG, 0, 
253
 
                rpc_registry_save_internal, argc, argv );
254
 
}
255
 
 
256
 
 
257
 
/********************************************************************
258
 
********************************************************************/
259
 
 
260
 
static void dump_values( REGF_NK_REC *nk )
261
 
{
262
 
        int i, j;
263
 
        pstring data_str;
264
 
        uint32 data_size, data;
265
 
 
266
 
        if ( !nk->values )
267
 
                return;
268
 
 
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 ) );
272
 
 
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] );
283
 
                                }
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] );
292
 
                                }
293
 
                                break;
294
 
                        default:
295
 
                                d_printf("unknown");
296
 
                                break;
297
 
                }
298
 
 
299
 
                d_printf( "\n" );
300
 
        }
301
 
 
302
 
}
303
 
 
304
 
/********************************************************************
305
 
********************************************************************/
306
 
 
307
 
static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
308
 
{
309
 
        REGF_NK_REC *key;
310
 
        pstring regpath;
311
 
 
312
 
        /* depth first dump of the registry tree */
313
 
 
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 );
320
 
        }
321
 
 
322
 
        return True;
323
 
}
324
 
 
325
 
/********************************************************************
326
 
********************************************************************/
327
 
 
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 )
331
 
{
332
 
        REGF_NK_REC *key, *subkey;
333
 
        REGVAL_CTR *values;
334
 
        REGSUBKEY_CTR *subkeys;
335
 
        int i;
336
 
        pstring path;
337
 
 
338
 
        if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
339
 
                DEBUG(0,("write_registry_tree: talloc() failed!\n"));
340
 
                return False;
341
 
        }
342
 
 
343
 
        if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
344
 
                DEBUG(0,("write_registry_tree: talloc() failed!\n"));
345
 
                return False;
346
 
        }
347
 
 
348
 
        /* copy values into the REGVAL_CTR */
349
 
        
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) );
353
 
        }
354
 
 
355
 
        /* copy subkeys into the REGSUBKEY_CTR */
356
 
        
357
 
        while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
358
 
                regsubkey_ctr_addkey( subkeys, subkey->keyname );
359
 
        }
360
 
        
361
 
        key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
362
 
 
363
 
        /* write each one of the subkeys out */
364
 
 
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 );
369
 
        }
370
 
 
371
 
        TALLOC_FREE( subkeys );
372
 
 
373
 
        d_printf("[%s]\n", path );
374
 
        
375
 
        return True;
376
 
}
377
 
 
378
 
/********************************************************************
379
 
********************************************************************/
380
 
 
381
 
static int rpc_registry_dump( int argc, const char **argv )
382
 
{
383
 
        REGF_FILE   *registry;
384
 
        REGF_NK_REC *nk;
385
 
        
386
 
        if (argc != 1 ) {
387
 
                d_printf("Usage:    net rpc dump <file> \n");
388
 
                return 0;
389
 
        }
390
 
        
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;
395
 
        }
396
 
        d_printf("ok\n");
397
 
        
398
 
        /* get the root of the registry file */
399
 
        
400
 
        if ((nk = regfio_rootkey( registry )) == NULL) {
401
 
                d_fprintf(stderr, "Could not get rootkey\n");
402
 
                regfio_close( registry );
403
 
                return 1;
404
 
        }
405
 
        d_printf("[%s]\n", nk->keyname);
406
 
        dump_values( nk );
407
 
        d_printf("\n");
408
 
 
409
 
        dump_registry_tree( registry, nk, nk->keyname );
410
 
 
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");
417
 
 
418
 
        return 0;
419
 
}
420
 
 
421
 
/********************************************************************
422
 
********************************************************************/
423
 
 
424
 
static int rpc_registry_copy( int argc, const char **argv )
425
 
{
426
 
        REGF_FILE   *infile = NULL, *outfile = NULL;
427
 
        REGF_NK_REC *nk;
428
 
        int result = 1;
429
 
        
430
 
        if (argc != 2 ) {
431
 
                d_printf("Usage:    net rpc copy <srcfile> <newfile>\n");
432
 
                return 0;
433
 
        }
434
 
        
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;
439
 
        }
440
 
        d_printf("ok\n");
441
 
 
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;
446
 
        }
447
 
        d_printf("ok\n");
448
 
        
449
 
        /* get the root of the registry file */
450
 
        
451
 
        if ((nk = regfio_rootkey( infile )) == NULL) {
452
 
                d_fprintf(stderr, "Could not get rootkey\n");
453
 
                goto out;
454
 
        }
455
 
        d_printf("RootKey: [%s]\n", nk->keyname);
456
 
 
457
 
        write_registry_tree( infile, nk, NULL, outfile, "" );
458
 
 
459
 
        result = 0;
460
 
 
461
 
out:
462
 
 
463
 
        d_printf("Closing %s...", argv[1]);
464
 
        if (outfile) {
465
 
                regfio_close( outfile );
466
 
        }
467
 
        d_printf("ok\n");
468
 
 
469
 
        d_printf("Closing %s...", argv[0]);
470
 
        if (infile) {
471
 
                regfio_close( infile );
472
 
        }
473
 
        d_printf("ok\n");
474
 
 
475
 
        return( result);
476
 
}
477
 
 
478
 
/********************************************************************
479
 
********************************************************************/
480
 
 
481
 
static int net_help_registry( int argc, const char **argv )
482
 
{
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");
486
 
        
487
 
        return -1;
488
 
}
489
 
 
490
 
/********************************************************************
491
 
********************************************************************/
492
 
 
493
 
int net_rpc_registry(int argc, const char **argv) 
494
 
{
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}
501
 
        };
502
 
        
503
 
        if ( argc )
504
 
                return net_run_function( argc, argv, func, net_help_registry );
505
 
                
506
 
        return net_help_registry( argc, argv );
507
 
}