r22747: Fix some C++ warnings
[Samba/gebeck_regimport.git] / source / utils / net_rpc_registry.c
blobb439f50ee44d1b040d69b2870c0be5f26907dd8d
1 /*
2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "includes.h"
22 #include "utils/net.h"
23 #include "regfio.h"
24 #include "reg_objects.h"
26 static BOOL reg_hive_key(const char *fullname, uint32 *reg_type,
27 const char **key_name)
29 const char *sep;
30 ptrdiff_t len;
32 sep = strchr_m(fullname, '\\');
34 if (sep != NULL) {
35 len = sep - fullname;
36 *key_name = sep+1;
38 else {
39 len = strlen(fullname);
40 *key_name = "";
43 if (strnequal(fullname, "HKLM", len) ||
44 strnequal(fullname, "HKEY_LOCAL_MACHINE", len))
45 (*reg_type) = HKEY_LOCAL_MACHINE;
46 else if (strnequal(fullname, "HKCR", len) ||
47 strnequal(fullname, "HKEY_CLASSES_ROOT", len))
48 (*reg_type) = HKEY_CLASSES_ROOT;
49 else if (strnequal(fullname, "HKU", len) ||
50 strnequal(fullname, "HKEY_USERS", len))
51 (*reg_type) = HKEY_USERS;
52 else if (strnequal(fullname, "HKPD", len) ||
53 strnequal(fullname, "HKEY_PERFORMANCE_DATA", len))
54 (*reg_type) = HKEY_PERFORMANCE_DATA;
55 else {
56 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
57 fullname));
58 return False;
61 return True;
64 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
65 struct rpc_pipe_client *pipe_hnd,
66 const char *name, uint32 access_mask,
67 struct policy_handle *hive_hnd,
68 struct policy_handle *key_hnd)
70 uint32 hive;
71 NTSTATUS status;
72 struct winreg_String key;
74 if (!reg_hive_key(name, &hive, &key.name)) {
75 return NT_STATUS_INVALID_PARAMETER;
78 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
79 hive_hnd);
80 if (!(NT_STATUS_IS_OK(status))) {
81 return status;
84 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
85 access_mask, key_hnd);
86 if (!(NT_STATUS_IS_OK(status))) {
87 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd);
88 return status;
91 return NT_STATUS_OK;
94 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
95 struct rpc_pipe_client *pipe_hnd,
96 struct policy_handle *key_hnd,
97 uint32 *pnum_keys, char ***pnames,
98 char ***pclasses, NTTIME ***pmodtimes)
100 TALLOC_CTX *mem_ctx;
101 NTSTATUS status;
102 uint32 num_subkeys, max_subkeylen, max_classlen;
103 uint32 num_values, max_valnamelen, max_valbufsize;
104 uint32 i;
105 NTTIME last_changed_time;
106 uint32 secdescsize;
107 struct winreg_String classname;
108 char **names, **classes;
109 NTTIME **modtimes;
111 if (!(mem_ctx = talloc_new(ctx))) {
112 return NT_STATUS_NO_MEMORY;
115 ZERO_STRUCT(classname);
116 status = rpccli_winreg_QueryInfoKey(
117 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
118 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
119 &max_valbufsize, &secdescsize, &last_changed_time );
121 if (!NT_STATUS_IS_OK(status)) {
122 goto error;
125 if (num_subkeys == 0) {
126 *pnum_keys = 0;
127 TALLOC_FREE(mem_ctx);
128 return NT_STATUS_OK;
131 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
132 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
133 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
134 num_subkeys)))) {
135 status = NT_STATUS_NO_MEMORY;
136 goto error;
139 for (i=0; i<num_subkeys; i++) {
140 char c, n;
141 struct winreg_StringBuf class_buf;
142 struct winreg_StringBuf name_buf;
143 NTTIME modtime;
145 c = '\0';
146 class_buf.name = &c;
147 class_buf.size = max_classlen+2;
149 n = '\0';
150 name_buf.name = &n;
151 name_buf.size = max_subkeylen+2;
153 ZERO_STRUCT(modtime);
155 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
156 i, &name_buf, &class_buf,
157 &modtime);
159 if (W_ERROR_EQUAL(ntstatus_to_werror(status),
160 WERR_NO_MORE_ITEMS) ) {
161 status = NT_STATUS_OK;
162 break;
164 if (!NT_STATUS_IS_OK(status)) {
165 goto error;
168 classes[i] = NULL;
170 if (class_buf.name &&
171 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
172 status = NT_STATUS_NO_MEMORY;
173 goto error;
176 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
177 status = NT_STATUS_NO_MEMORY;
178 goto error;
181 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
182 modtimes, &modtime, sizeof(modtime))))) {
183 status = NT_STATUS_NO_MEMORY;
184 goto error;
188 *pnum_keys = num_subkeys;
190 if (pnames) {
191 *pnames = talloc_move(ctx, &names);
193 if (pclasses) {
194 *pclasses = talloc_move(ctx, &classes);
196 if (pmodtimes) {
197 *pmodtimes = talloc_move(ctx, &modtimes);
200 status = NT_STATUS_OK;
202 error:
203 TALLOC_FREE(mem_ctx);
204 return status;
207 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
208 struct rpc_pipe_client *pipe_hnd,
209 struct policy_handle *key_hnd,
210 uint32 *pnum_values, char ***pvalnames,
211 struct registry_value ***pvalues)
213 TALLOC_CTX *mem_ctx;
214 NTSTATUS status;
215 uint32 num_subkeys, max_subkeylen, max_classlen;
216 uint32 num_values, max_valnamelen, max_valbufsize;
217 uint32 i;
218 NTTIME last_changed_time;
219 uint32 secdescsize;
220 struct winreg_String classname;
221 struct registry_value **values;
222 char **names;
224 if (!(mem_ctx = talloc_new(ctx))) {
225 return NT_STATUS_NO_MEMORY;
228 ZERO_STRUCT(classname);
229 status = rpccli_winreg_QueryInfoKey(
230 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
231 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
232 &max_valbufsize, &secdescsize, &last_changed_time );
234 if (!NT_STATUS_IS_OK(status)) {
235 goto error;
238 if (num_values == 0) {
239 *pnum_values = 0;
240 TALLOC_FREE(mem_ctx);
241 return NT_STATUS_OK;
244 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
245 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
246 num_values)))) {
247 status = NT_STATUS_NO_MEMORY;
248 goto error;
251 for (i=0; i<num_values; i++) {
252 enum winreg_Type type = REG_NONE;
253 uint8 *data = NULL;
254 uint32 data_size;
255 uint32 value_length;
257 char n;
258 struct winreg_ValNameBuf name_buf;
259 WERROR err;
261 n = '\0';
262 name_buf.name = &n;
263 name_buf.size = max_valnamelen + 2;
265 data_size = max_valbufsize;
266 data = (uint8 *)TALLOC(mem_ctx, data_size);
267 value_length = 0;
269 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
270 i, &name_buf, &type,
271 data, &data_size,
272 &value_length );
274 if ( W_ERROR_EQUAL(ntstatus_to_werror(status),
275 WERR_NO_MORE_ITEMS) ) {
276 status = NT_STATUS_OK;
277 break;
280 if (!(NT_STATUS_IS_OK(status))) {
281 goto error;
284 if (name_buf.name == NULL) {
285 status = NT_STATUS_INVALID_PARAMETER;
286 goto error;
289 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
290 status = NT_STATUS_NO_MEMORY;
291 goto error;
294 err = registry_pull_value(values, &values[i], type, data,
295 data_size, value_length);
296 if (!W_ERROR_IS_OK(err)) {
297 status = werror_to_ntstatus(err);
298 goto error;
302 *pnum_values = num_values;
304 if (pvalnames) {
305 *pvalnames = talloc_move(ctx, &names);
307 if (pvalues) {
308 *pvalues = talloc_move(ctx, &values);
311 status = NT_STATUS_OK;
313 error:
314 TALLOC_FREE(mem_ctx);
315 return status;
318 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
319 struct rpc_pipe_client *pipe_hnd,
320 struct policy_handle *key_hnd,
321 const char *name,
322 const struct registry_value *value)
324 struct winreg_String name_string;
325 DATA_BLOB blob;
326 NTSTATUS result;
327 WERROR err;
329 err = registry_push_value(mem_ctx, value, &blob);
330 if (!W_ERROR_IS_OK(err)) {
331 return werror_to_ntstatus(err);
334 name_string.name = name;
335 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
336 name_string, value->type,
337 blob.data, blob.length);
338 TALLOC_FREE(blob.data);
339 return result;
342 static NTSTATUS rpc_registry_setvalue_internal(const DOM_SID *domain_sid,
343 const char *domain_name,
344 struct cli_state *cli,
345 struct rpc_pipe_client *pipe_hnd,
346 TALLOC_CTX *mem_ctx,
347 int argc,
348 const char **argv )
350 struct policy_handle hive_hnd, key_hnd;
351 NTSTATUS status;
352 struct registry_value value;
354 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_WRITE,
355 &hive_hnd, &key_hnd);
356 if (!NT_STATUS_IS_OK(status)) {
357 d_fprintf(stderr, "registry_openkey failed: %s\n",
358 nt_errstr(status));
359 return status;
362 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
363 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
364 return NT_STATUS_NOT_IMPLEMENTED;
367 if (strequal(argv[2], "dword")) {
368 value.type = REG_DWORD;
369 value.v.dword = strtoul(argv[3], NULL, 10);
371 else if (strequal(argv[2], "sz")) {
372 value.type = REG_SZ;
373 value.v.sz.len = strlen(argv[3])+1;
374 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
376 else {
377 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
378 status = NT_STATUS_NOT_IMPLEMENTED;
379 goto error;
382 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
383 argv[1], &value);
385 if (!NT_STATUS_IS_OK(status)) {
386 d_fprintf(stderr, "registry_setvalue failed: %s\n",
387 nt_errstr(status));
390 error:
391 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
392 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
394 return NT_STATUS_OK;
397 static int rpc_registry_setvalue( int argc, const char **argv )
399 if (argc < 4) {
400 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
401 "<valuename> <type> [<val>]+\n");
402 return -1;
405 return run_rpc_command( NULL, PI_WINREG, 0,
406 rpc_registry_setvalue_internal, argc, argv );
409 static NTSTATUS rpc_registry_deletevalue_internal(const DOM_SID *domain_sid,
410 const char *domain_name,
411 struct cli_state *cli,
412 struct rpc_pipe_client *pipe_hnd,
413 TALLOC_CTX *mem_ctx,
414 int argc,
415 const char **argv )
417 struct policy_handle hive_hnd, key_hnd;
418 NTSTATUS status;
419 struct winreg_String valuename;
421 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_WRITE,
422 &hive_hnd, &key_hnd);
423 if (!NT_STATUS_IS_OK(status)) {
424 d_fprintf(stderr, "registry_openkey failed: %s\n",
425 nt_errstr(status));
426 return status;
429 valuename.name = argv[1];
431 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
432 valuename);
434 if (!NT_STATUS_IS_OK(status)) {
435 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
436 nt_errstr(status));
439 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
440 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
442 return NT_STATUS_OK;
445 static int rpc_registry_deletevalue( int argc, const char **argv )
447 if (argc != 2) {
448 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
449 "<valuename>\n");
450 return -1;
453 return run_rpc_command( NULL, PI_WINREG, 0,
454 rpc_registry_deletevalue_internal, argc, argv );
457 static NTSTATUS rpc_registry_createkey_internal(const DOM_SID *domain_sid,
458 const char *domain_name,
459 struct cli_state *cli,
460 struct rpc_pipe_client *pipe_hnd,
461 TALLOC_CTX *mem_ctx,
462 int argc,
463 const char **argv )
465 uint32 hive;
466 struct policy_handle hive_hnd, key_hnd;
467 struct winreg_String key, keyclass;
468 enum winreg_CreateAction action;
469 NTSTATUS status;
471 if (!reg_hive_key(argv[0], &hive, &key.name)) {
472 return NT_STATUS_INVALID_PARAMETER;
475 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
476 REG_KEY_READ|REG_KEY_WRITE,
477 &hive_hnd);
478 if (!(NT_STATUS_IS_OK(status))) {
479 return status;
482 action = REG_ACTION_NONE;
483 keyclass.name = "";
485 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
486 keyclass, 0, REG_KEY_READ, NULL,
487 &key_hnd, &action);
488 if (!NT_STATUS_IS_OK(status)) {
489 d_fprintf(stderr, "createkey returned %s\n",
490 nt_errstr(status));
491 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
492 return status;
495 switch (action) {
496 case REG_ACTION_NONE:
497 d_printf("createkey did nothing -- huh?\n");
498 break;
499 case REG_CREATED_NEW_KEY:
500 d_printf("createkey created %s\n", argv[0]);
501 break;
502 case REG_OPENED_EXISTING_KEY:
503 d_printf("createkey opened existing %s\n", argv[0]);
504 break;
507 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
508 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
510 return status;
513 static int rpc_registry_createkey( int argc, const char **argv )
515 if (argc != 1) {
516 d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
517 return -1;
520 return run_rpc_command( NULL, PI_WINREG, 0,
521 rpc_registry_createkey_internal, argc, argv );
524 static NTSTATUS rpc_registry_deletekey_internal(const DOM_SID *domain_sid,
525 const char *domain_name,
526 struct cli_state *cli,
527 struct rpc_pipe_client *pipe_hnd,
528 TALLOC_CTX *mem_ctx,
529 int argc,
530 const char **argv )
532 uint32 hive;
533 struct policy_handle hive_hnd;
534 struct winreg_String key;
535 NTSTATUS status;
537 if (!reg_hive_key(argv[0], &hive, &key.name)) {
538 return NT_STATUS_INVALID_PARAMETER;
541 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, REG_KEY_WRITE,
542 &hive_hnd);
543 if (!(NT_STATUS_IS_OK(status))) {
544 return status;
547 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key);
548 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
550 if (!NT_STATUS_IS_OK(status)) {
551 d_fprintf(stderr, "deletekey returned %s\n",
552 nt_errstr(status));
555 return status;
558 static int rpc_registry_deletekey( int argc, const char **argv )
560 if (argc != 1) {
561 d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
562 return -1;
565 return run_rpc_command( NULL, PI_WINREG, 0,
566 rpc_registry_deletekey_internal, argc, argv );
569 /********************************************************************
570 ********************************************************************/
572 static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
573 const char *domain_name,
574 struct cli_state *cli,
575 struct rpc_pipe_client *pipe_hnd,
576 TALLOC_CTX *mem_ctx,
577 int argc,
578 const char **argv )
580 POLICY_HND pol_hive, pol_key;
581 NTSTATUS status;
582 uint32 num_subkeys = 0;
583 uint32 num_values = 0;
584 char **names = NULL, **classes = NULL;
585 NTTIME **modtimes = NULL;
586 uint32 i;
587 struct registry_value **values = NULL;
589 if (argc != 1 ) {
590 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
591 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
592 return NT_STATUS_OK;
595 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
596 &pol_hive, &pol_key);
597 if (!NT_STATUS_IS_OK(status)) {
598 d_fprintf(stderr, "registry_openkey failed: %s\n",
599 nt_errstr(status));
600 return status;
603 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
604 &names, &classes, &modtimes);
605 if (!NT_STATUS_IS_OK(status)) {
606 d_fprintf(stderr, "enumerating keys failed: %s\n",
607 nt_errstr(status));
608 return status;
611 for (i=0; i<num_subkeys; i++) {
612 d_printf("Keyname = %s\n", names[i]);
613 d_printf("Modtime = %s\n", modtimes[i]
614 ? http_timestring(nt_time_to_unix(*modtimes[i]))
615 : "None");
616 d_printf("\n" );
619 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
620 &names, &values);
621 if (!NT_STATUS_IS_OK(status)) {
622 d_fprintf(stderr, "enumerating values failed: %s\n",
623 nt_errstr(status));
624 return status;
627 for (i=0; i<num_values; i++) {
628 struct registry_value *v = values[i];
629 d_printf("Valuename = %s\n", names[i]);
630 d_printf("Type = %s\n",
631 reg_type_lookup(v->type));
632 switch(v->type) {
633 case REG_DWORD:
634 d_printf("Value = %d\n", v->v.dword);
635 break;
636 case REG_SZ:
637 case REG_EXPAND_SZ:
638 d_printf("Value = \"%s\"\n", v->v.sz.str);
639 break;
640 case REG_MULTI_SZ: {
641 uint32 j;
642 for (j = 0; j < v->v.multi_sz.num_strings; j++) {
643 d_printf("Value[%3.3d] = \"%s\"\n", j,
644 v->v.multi_sz.strings[j]);
646 break;
648 case REG_BINARY:
649 d_printf("Value = %d bytes\n",
650 (int)v->v.binary.length);
651 break;
652 default:
653 d_printf("Value = <unprintable>\n");
654 break;
657 d_printf("\n");
660 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
661 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
663 return status;
666 /********************************************************************
667 ********************************************************************/
669 static int rpc_registry_enumerate( int argc, const char **argv )
671 return run_rpc_command( NULL, PI_WINREG, 0,
672 rpc_registry_enumerate_internal, argc, argv );
675 /********************************************************************
676 ********************************************************************/
678 static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
679 const char *domain_name,
680 struct cli_state *cli,
681 struct rpc_pipe_client *pipe_hnd,
682 TALLOC_CTX *mem_ctx,
683 int argc,
684 const char **argv )
686 WERROR result = WERR_GENERAL_FAILURE;
687 POLICY_HND pol_hive, pol_key;
688 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
689 struct winreg_String filename;
691 if (argc != 2 ) {
692 d_printf("Usage: net rpc backup <path> <file> \n");
693 return NT_STATUS_OK;
696 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
697 &pol_hive, &pol_key);
698 if (!NT_STATUS_IS_OK(status)) {
699 d_fprintf(stderr, "registry_openkey failed: %s\n",
700 nt_errstr(status));
701 return status;
704 filename.name = argv[1];
705 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL );
706 if ( !W_ERROR_IS_OK(result) ) {
707 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
710 /* cleanup */
712 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
713 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
715 return status;
718 /********************************************************************
719 ********************************************************************/
721 static int rpc_registry_save( int argc, const char **argv )
723 return run_rpc_command( NULL, PI_WINREG, 0,
724 rpc_registry_save_internal, argc, argv );
728 /********************************************************************
729 ********************************************************************/
731 static void dump_values( REGF_NK_REC *nk )
733 int i, j;
734 pstring data_str;
735 uint32 data_size, data;
737 if ( !nk->values )
738 return;
740 for ( i=0; i<nk->num_values; i++ ) {
741 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
742 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
744 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
745 switch ( nk->values[i].type ) {
746 case REG_SZ:
747 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
748 d_printf( "%s", data_str );
749 break;
750 case REG_MULTI_SZ:
751 case REG_EXPAND_SZ:
752 for ( j=0; j<data_size; j++ ) {
753 d_printf( "%c", nk->values[i].data[j] );
755 break;
756 case REG_DWORD:
757 data = IVAL( nk->values[i].data, 0 );
758 d_printf("0x%x", data );
759 break;
760 case REG_BINARY:
761 for ( j=0; j<data_size; j++ ) {
762 d_printf( "%x", nk->values[i].data[j] );
764 break;
765 default:
766 d_printf("unknown");
767 break;
770 d_printf( "\n" );
775 /********************************************************************
776 ********************************************************************/
778 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
780 REGF_NK_REC *key;
781 pstring regpath;
783 /* depth first dump of the registry tree */
785 while ( (key = regfio_fetch_subkey( file, nk )) ) {
786 pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
787 d_printf("[%s]\n", regpath );
788 dump_values( key );
789 d_printf("\n");
790 dump_registry_tree( file, key, regpath );
793 return True;
796 /********************************************************************
797 ********************************************************************/
799 static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
800 REGF_NK_REC *parent, REGF_FILE *outfile,
801 const char *parentpath )
803 REGF_NK_REC *key, *subkey;
804 REGVAL_CTR *values;
805 REGSUBKEY_CTR *subkeys;
806 int i;
807 pstring path;
809 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
810 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
811 return False;
814 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
815 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
816 return False;
819 /* copy values into the REGVAL_CTR */
821 for ( i=0; i<nk->num_values; i++ ) {
822 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
823 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
826 /* copy subkeys into the REGSUBKEY_CTR */
828 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
829 regsubkey_ctr_addkey( subkeys, subkey->keyname );
832 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
834 /* write each one of the subkeys out */
836 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
837 nk->subkey_index = 0;
838 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
839 write_registry_tree( infile, subkey, key, outfile, path );
842 TALLOC_FREE( subkeys );
844 d_printf("[%s]\n", path );
846 return True;
849 /********************************************************************
850 ********************************************************************/
852 static int rpc_registry_dump( int argc, const char **argv )
854 REGF_FILE *registry;
855 REGF_NK_REC *nk;
857 if (argc != 1 ) {
858 d_printf("Usage: net rpc dump <file> \n");
859 return 0;
862 d_printf("Opening %s....", argv[0]);
863 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
864 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
865 return 1;
867 d_printf("ok\n");
869 /* get the root of the registry file */
871 if ((nk = regfio_rootkey( registry )) == NULL) {
872 d_fprintf(stderr, "Could not get rootkey\n");
873 regfio_close( registry );
874 return 1;
876 d_printf("[%s]\n", nk->keyname);
877 dump_values( nk );
878 d_printf("\n");
880 dump_registry_tree( registry, nk, nk->keyname );
882 #if 0
883 talloc_report_full( registry->mem_ctx, stderr );
884 #endif
885 d_printf("Closing registry...");
886 regfio_close( registry );
887 d_printf("ok\n");
889 return 0;
892 /********************************************************************
893 ********************************************************************/
895 static int rpc_registry_copy( int argc, const char **argv )
897 REGF_FILE *infile = NULL, *outfile = NULL;
898 REGF_NK_REC *nk;
899 int result = 1;
901 if (argc != 2 ) {
902 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
903 return 0;
906 d_printf("Opening %s....", argv[0]);
907 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
908 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
909 return 1;
911 d_printf("ok\n");
913 d_printf("Opening %s....", argv[1]);
914 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
915 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
916 goto out;
918 d_printf("ok\n");
920 /* get the root of the registry file */
922 if ((nk = regfio_rootkey( infile )) == NULL) {
923 d_fprintf(stderr, "Could not get rootkey\n");
924 goto out;
926 d_printf("RootKey: [%s]\n", nk->keyname);
928 write_registry_tree( infile, nk, NULL, outfile, "" );
930 result = 0;
932 out:
934 d_printf("Closing %s...", argv[1]);
935 if (outfile) {
936 regfio_close( outfile );
938 d_printf("ok\n");
940 d_printf("Closing %s...", argv[0]);
941 if (infile) {
942 regfio_close( infile );
944 d_printf("ok\n");
946 return( result);
949 /********************************************************************
950 ********************************************************************/
952 int net_rpc_registry(int argc, const char **argv)
954 struct functable2 func[] = {
955 { "enumerate", rpc_registry_enumerate,
956 "Enumerate registry keys and values" },
957 { "createkey", rpc_registry_createkey,
958 "Create a new registry key" },
959 { "deletekey", rpc_registry_deletekey,
960 "Delete a registry key" },
961 { "setvalue", rpc_registry_setvalue,
962 "Set a new registry value" },
963 { "deletevalue", rpc_registry_deletevalue,
964 "Delete a registry value" },
965 { "save", rpc_registry_save,
966 "Save a registry file" },
967 { "dump", rpc_registry_dump,
968 "Dump a registry file" },
969 { "copy", rpc_registry_copy,
970 "Copy a registry file" },
971 {NULL, NULL, NULL}
974 return net_run_function2(argc, argv, "net rpc registry", func);