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 3 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, see <http://www.gnu.org/licenses/>. */
21 #include "utils/net.h"
23 #include "reg_objects.h"
25 static BOOL reg_hive_key(const char *fullname, uint32 *reg_type,
26 const char **key_name)
31 sep = strchr_m(fullname, '\\');
38 len = strlen(fullname);
42 if (strnequal(fullname, "HKLM", len) ||
43 strnequal(fullname, "HKEY_LOCAL_MACHINE", len))
44 (*reg_type) = HKEY_LOCAL_MACHINE;
45 else if (strnequal(fullname, "HKCR", len) ||
46 strnequal(fullname, "HKEY_CLASSES_ROOT", len))
47 (*reg_type) = HKEY_CLASSES_ROOT;
48 else if (strnequal(fullname, "HKU", len) ||
49 strnequal(fullname, "HKEY_USERS", len))
50 (*reg_type) = HKEY_USERS;
51 else if (strnequal(fullname, "HKPD", len) ||
52 strnequal(fullname, "HKEY_PERFORMANCE_DATA", len))
53 (*reg_type) = HKEY_PERFORMANCE_DATA;
55 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
63 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
64 struct rpc_pipe_client *pipe_hnd,
65 const char *name, uint32 access_mask,
66 struct policy_handle *hive_hnd,
67 struct policy_handle *key_hnd)
71 struct winreg_String key;
75 if (!reg_hive_key(name, &hive, &key.name)) {
76 return NT_STATUS_INVALID_PARAMETER;
79 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
81 if (!(NT_STATUS_IS_OK(status))) {
85 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
86 access_mask, key_hnd);
87 if (!(NT_STATUS_IS_OK(status))) {
88 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd);
95 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
96 struct rpc_pipe_client *pipe_hnd,
97 struct policy_handle *key_hnd,
98 uint32 *pnum_keys, char ***pnames,
99 char ***pclasses, NTTIME ***pmodtimes)
103 uint32 num_subkeys, max_subkeylen, max_classlen;
104 uint32 num_values, max_valnamelen, max_valbufsize;
106 NTTIME last_changed_time;
108 struct winreg_String classname;
109 char **names, **classes;
112 if (!(mem_ctx = talloc_new(ctx))) {
113 return NT_STATUS_NO_MEMORY;
116 ZERO_STRUCT(classname);
117 status = rpccli_winreg_QueryInfoKey(
118 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
119 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
120 &max_valbufsize, &secdescsize, &last_changed_time );
122 if (!NT_STATUS_IS_OK(status)) {
126 if (num_subkeys == 0) {
128 TALLOC_FREE(mem_ctx);
132 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
133 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
134 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
136 status = NT_STATUS_NO_MEMORY;
140 for (i=0; i<num_subkeys; i++) {
142 struct winreg_StringBuf class_buf;
143 struct winreg_StringBuf name_buf;
148 class_buf.size = max_classlen+2;
152 name_buf.size = max_subkeylen+2;
154 ZERO_STRUCT(modtime);
156 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
157 i, &name_buf, &class_buf,
160 if (W_ERROR_EQUAL(ntstatus_to_werror(status),
161 WERR_NO_MORE_ITEMS) ) {
162 status = NT_STATUS_OK;
165 if (!NT_STATUS_IS_OK(status)) {
171 if (class_buf.name &&
172 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
173 status = NT_STATUS_NO_MEMORY;
177 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
178 status = NT_STATUS_NO_MEMORY;
182 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
183 modtimes, &modtime, sizeof(modtime))))) {
184 status = NT_STATUS_NO_MEMORY;
189 *pnum_keys = num_subkeys;
192 *pnames = talloc_move(ctx, &names);
195 *pclasses = talloc_move(ctx, &classes);
198 *pmodtimes = talloc_move(ctx, &modtimes);
201 status = NT_STATUS_OK;
204 TALLOC_FREE(mem_ctx);
208 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
209 struct rpc_pipe_client *pipe_hnd,
210 struct policy_handle *key_hnd,
211 uint32 *pnum_values, char ***pvalnames,
212 struct registry_value ***pvalues)
216 uint32 num_subkeys, max_subkeylen, max_classlen;
217 uint32 num_values, max_valnamelen, max_valbufsize;
219 NTTIME last_changed_time;
221 struct winreg_String classname;
222 struct registry_value **values;
225 if (!(mem_ctx = talloc_new(ctx))) {
226 return NT_STATUS_NO_MEMORY;
229 ZERO_STRUCT(classname);
230 status = rpccli_winreg_QueryInfoKey(
231 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
232 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
233 &max_valbufsize, &secdescsize, &last_changed_time );
235 if (!NT_STATUS_IS_OK(status)) {
239 if (num_values == 0) {
241 TALLOC_FREE(mem_ctx);
245 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
246 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
248 status = NT_STATUS_NO_MEMORY;
252 for (i=0; i<num_values; i++) {
253 enum winreg_Type type = REG_NONE;
259 struct winreg_ValNameBuf name_buf;
264 name_buf.size = max_valnamelen + 2;
266 data_size = max_valbufsize;
267 data = (uint8 *)TALLOC(mem_ctx, data_size);
270 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
275 if ( W_ERROR_EQUAL(ntstatus_to_werror(status),
276 WERR_NO_MORE_ITEMS) ) {
277 status = NT_STATUS_OK;
281 if (!(NT_STATUS_IS_OK(status))) {
285 if (name_buf.name == NULL) {
286 status = NT_STATUS_INVALID_PARAMETER;
290 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
291 status = NT_STATUS_NO_MEMORY;
295 err = registry_pull_value(values, &values[i], type, data,
296 data_size, value_length);
297 if (!W_ERROR_IS_OK(err)) {
298 status = werror_to_ntstatus(err);
303 *pnum_values = num_values;
306 *pvalnames = talloc_move(ctx, &names);
309 *pvalues = talloc_move(ctx, &values);
312 status = NT_STATUS_OK;
315 TALLOC_FREE(mem_ctx);
319 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
320 struct rpc_pipe_client *pipe_hnd,
321 struct policy_handle *key_hnd,
323 const struct registry_value *value)
325 struct winreg_String name_string;
330 err = registry_push_value(mem_ctx, value, &blob);
331 if (!W_ERROR_IS_OK(err)) {
332 return werror_to_ntstatus(err);
335 ZERO_STRUCT(name_string);
337 name_string.name = name;
338 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
339 name_string, value->type,
340 blob.data, blob.length);
341 TALLOC_FREE(blob.data);
345 static NTSTATUS rpc_registry_setvalue_internal(const DOM_SID *domain_sid,
346 const char *domain_name,
347 struct cli_state *cli,
348 struct rpc_pipe_client *pipe_hnd,
353 struct policy_handle hive_hnd, key_hnd;
355 struct registry_value value;
357 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
358 SEC_RIGHTS_MAXIMUM_ALLOWED,
359 &hive_hnd, &key_hnd);
360 if (!NT_STATUS_IS_OK(status)) {
361 d_fprintf(stderr, "registry_openkey failed: %s\n",
366 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
367 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
368 return NT_STATUS_NOT_IMPLEMENTED;
371 if (strequal(argv[2], "dword")) {
372 value.type = REG_DWORD;
373 value.v.dword = strtoul(argv[3], NULL, 10);
375 else if (strequal(argv[2], "sz")) {
377 value.v.sz.len = strlen(argv[3])+1;
378 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
381 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
382 status = NT_STATUS_NOT_IMPLEMENTED;
386 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
389 if (!NT_STATUS_IS_OK(status)) {
390 d_fprintf(stderr, "registry_setvalue failed: %s\n",
395 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
396 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
401 static int rpc_registry_setvalue( int argc, const char **argv )
404 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
405 "<valuename> <type> [<val>]+\n");
409 return run_rpc_command( NULL, PI_WINREG, 0,
410 rpc_registry_setvalue_internal, argc, argv );
413 static NTSTATUS rpc_registry_deletevalue_internal(const DOM_SID *domain_sid,
414 const char *domain_name,
415 struct cli_state *cli,
416 struct rpc_pipe_client *pipe_hnd,
421 struct policy_handle hive_hnd, key_hnd;
423 struct winreg_String valuename;
425 ZERO_STRUCT(valuename);
427 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
428 SEC_RIGHTS_MAXIMUM_ALLOWED,
429 &hive_hnd, &key_hnd);
430 if (!NT_STATUS_IS_OK(status)) {
431 d_fprintf(stderr, "registry_openkey failed: %s\n",
436 valuename.name = argv[1];
438 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
441 if (!NT_STATUS_IS_OK(status)) {
442 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
446 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
447 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
452 static int rpc_registry_deletevalue( int argc, const char **argv )
455 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
460 return run_rpc_command( NULL, PI_WINREG, 0,
461 rpc_registry_deletevalue_internal, argc, argv );
464 static NTSTATUS rpc_registry_createkey_internal(const DOM_SID *domain_sid,
465 const char *domain_name,
466 struct cli_state *cli,
467 struct rpc_pipe_client *pipe_hnd,
473 struct policy_handle hive_hnd, key_hnd;
474 struct winreg_String key, keyclass;
475 enum winreg_CreateAction action;
479 ZERO_STRUCT(keyclass);
481 if (!reg_hive_key(argv[0], &hive, &key.name)) {
482 return NT_STATUS_INVALID_PARAMETER;
485 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
486 SEC_RIGHTS_MAXIMUM_ALLOWED,
488 if (!(NT_STATUS_IS_OK(status))) {
492 action = REG_ACTION_NONE;
495 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
496 keyclass, 0, REG_KEY_READ, NULL,
498 if (!NT_STATUS_IS_OK(status)) {
499 d_fprintf(stderr, "createkey returned %s\n",
501 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
506 case REG_ACTION_NONE:
507 d_printf("createkey did nothing -- huh?\n");
509 case REG_CREATED_NEW_KEY:
510 d_printf("createkey created %s\n", argv[0]);
512 case REG_OPENED_EXISTING_KEY:
513 d_printf("createkey opened existing %s\n", argv[0]);
517 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
518 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
523 static int rpc_registry_createkey( int argc, const char **argv )
526 d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
530 return run_rpc_command( NULL, PI_WINREG, 0,
531 rpc_registry_createkey_internal, argc, argv );
534 static NTSTATUS rpc_registry_deletekey_internal(const DOM_SID *domain_sid,
535 const char *domain_name,
536 struct cli_state *cli,
537 struct rpc_pipe_client *pipe_hnd,
543 struct policy_handle hive_hnd;
544 struct winreg_String key;
549 if (!reg_hive_key(argv[0], &hive, &key.name)) {
550 return NT_STATUS_INVALID_PARAMETER;
553 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
554 SEC_RIGHTS_MAXIMUM_ALLOWED,
556 if (!(NT_STATUS_IS_OK(status))) {
560 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key);
561 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
563 if (!NT_STATUS_IS_OK(status)) {
564 d_fprintf(stderr, "deletekey returned %s\n",
571 static int rpc_registry_deletekey( int argc, const char **argv )
574 d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
578 return run_rpc_command( NULL, PI_WINREG, 0,
579 rpc_registry_deletekey_internal, argc, argv );
582 /********************************************************************
583 ********************************************************************/
585 static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
586 const char *domain_name,
587 struct cli_state *cli,
588 struct rpc_pipe_client *pipe_hnd,
593 POLICY_HND pol_hive, pol_key;
595 uint32 num_subkeys = 0;
596 uint32 num_values = 0;
597 char **names = NULL, **classes = NULL;
598 NTTIME **modtimes = NULL;
600 struct registry_value **values = NULL;
603 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
604 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
608 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
609 &pol_hive, &pol_key);
610 if (!NT_STATUS_IS_OK(status)) {
611 d_fprintf(stderr, "registry_openkey failed: %s\n",
616 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
617 &names, &classes, &modtimes);
618 if (!NT_STATUS_IS_OK(status)) {
619 d_fprintf(stderr, "enumerating keys failed: %s\n",
624 for (i=0; i<num_subkeys; i++) {
625 d_printf("Keyname = %s\n", names[i]);
626 d_printf("Modtime = %s\n", modtimes[i]
627 ? http_timestring(nt_time_to_unix(*modtimes[i]))
632 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
634 if (!NT_STATUS_IS_OK(status)) {
635 d_fprintf(stderr, "enumerating values failed: %s\n",
640 for (i=0; i<num_values; i++) {
641 struct registry_value *v = values[i];
642 d_printf("Valuename = %s\n", names[i]);
643 d_printf("Type = %s\n",
644 reg_type_lookup(v->type));
647 d_printf("Value = %d\n", v->v.dword);
651 d_printf("Value = \"%s\"\n", v->v.sz.str);
655 for (j = 0; j < v->v.multi_sz.num_strings; j++) {
656 d_printf("Value[%3.3d] = \"%s\"\n", j,
657 v->v.multi_sz.strings[j]);
662 d_printf("Value = %d bytes\n",
663 (int)v->v.binary.length);
666 d_printf("Value = <unprintable>\n");
673 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
674 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
679 /********************************************************************
680 ********************************************************************/
682 static int rpc_registry_enumerate( int argc, const char **argv )
684 return run_rpc_command( NULL, PI_WINREG, 0,
685 rpc_registry_enumerate_internal, argc, argv );
688 /********************************************************************
689 ********************************************************************/
691 static NTSTATUS rpc_registry_save_internal(const DOM_SID *domain_sid,
692 const char *domain_name,
693 struct cli_state *cli,
694 struct rpc_pipe_client *pipe_hnd,
699 WERROR result = WERR_GENERAL_FAILURE;
700 POLICY_HND pol_hive, pol_key;
701 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
702 struct winreg_String filename;
705 d_printf("Usage: net rpc backup <path> <file> \n");
709 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
710 &pol_hive, &pol_key);
711 if (!NT_STATUS_IS_OK(status)) {
712 d_fprintf(stderr, "registry_openkey failed: %s\n",
717 filename.name = argv[1];
718 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL );
719 if ( !W_ERROR_IS_OK(result) ) {
720 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
725 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
726 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
731 /********************************************************************
732 ********************************************************************/
734 static int rpc_registry_save( int argc, const char **argv )
736 return run_rpc_command( NULL, PI_WINREG, 0,
737 rpc_registry_save_internal, argc, argv );
741 /********************************************************************
742 ********************************************************************/
744 static void dump_values( REGF_NK_REC *nk )
748 uint32 data_size, data;
753 for ( i=0; i<nk->num_values; i++ ) {
754 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
755 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
757 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
758 switch ( nk->values[i].type ) {
760 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
761 d_printf( "%s", data_str );
765 for ( j=0; j<data_size; j++ ) {
766 d_printf( "%c", nk->values[i].data[j] );
770 data = IVAL( nk->values[i].data, 0 );
771 d_printf("0x%x", data );
774 for ( j=0; j<data_size; j++ ) {
775 d_printf( "%x", nk->values[i].data[j] );
788 /********************************************************************
789 ********************************************************************/
791 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
796 /* depth first dump of the registry tree */
798 while ( (key = regfio_fetch_subkey( file, nk )) ) {
799 pstr_sprintf( regpath, "%s\\%s", parent, key->keyname );
800 d_printf("[%s]\n", regpath );
803 dump_registry_tree( file, key, regpath );
809 /********************************************************************
810 ********************************************************************/
812 static BOOL write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
813 REGF_NK_REC *parent, REGF_FILE *outfile,
814 const char *parentpath )
816 REGF_NK_REC *key, *subkey;
818 REGSUBKEY_CTR *subkeys;
822 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
823 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
827 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
828 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
832 /* copy values into the REGVAL_CTR */
834 for ( i=0; i<nk->num_values; i++ ) {
835 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
836 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
839 /* copy subkeys into the REGSUBKEY_CTR */
841 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
842 regsubkey_ctr_addkey( subkeys, subkey->keyname );
845 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
847 /* write each one of the subkeys out */
849 pstr_sprintf( path, "%s%s%s", parentpath, parent ? "\\" : "", nk->keyname );
850 nk->subkey_index = 0;
851 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
852 write_registry_tree( infile, subkey, key, outfile, path );
855 TALLOC_FREE( subkeys );
857 d_printf("[%s]\n", path );
862 /********************************************************************
863 ********************************************************************/
865 static int rpc_registry_dump( int argc, const char **argv )
871 d_printf("Usage: net rpc dump <file> \n");
875 d_printf("Opening %s....", argv[0]);
876 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
877 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
882 /* get the root of the registry file */
884 if ((nk = regfio_rootkey( registry )) == NULL) {
885 d_fprintf(stderr, "Could not get rootkey\n");
886 regfio_close( registry );
889 d_printf("[%s]\n", nk->keyname);
893 dump_registry_tree( registry, nk, nk->keyname );
896 talloc_report_full( registry->mem_ctx, stderr );
898 d_printf("Closing registry...");
899 regfio_close( registry );
905 /********************************************************************
906 ********************************************************************/
908 static int rpc_registry_copy( int argc, const char **argv )
910 REGF_FILE *infile = NULL, *outfile = NULL;
915 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
919 d_printf("Opening %s....", argv[0]);
920 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
921 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
926 d_printf("Opening %s....", argv[1]);
927 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
928 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
933 /* get the root of the registry file */
935 if ((nk = regfio_rootkey( infile )) == NULL) {
936 d_fprintf(stderr, "Could not get rootkey\n");
939 d_printf("RootKey: [%s]\n", nk->keyname);
941 write_registry_tree( infile, nk, NULL, outfile, "" );
947 d_printf("Closing %s...", argv[1]);
949 regfio_close( outfile );
953 d_printf("Closing %s...", argv[0]);
955 regfio_close( infile );
962 /********************************************************************
963 ********************************************************************/
965 int net_rpc_registry(int argc, const char **argv)
967 struct functable2 func[] = {
968 { "enumerate", rpc_registry_enumerate,
969 "Enumerate registry keys and values" },
970 { "createkey", rpc_registry_createkey,
971 "Create a new registry key" },
972 { "deletekey", rpc_registry_deletekey,
973 "Delete a registry key" },
974 { "setvalue", rpc_registry_setvalue,
975 "Set a new registry value" },
976 { "deletevalue", rpc_registry_deletevalue,
977 "Delete a registry value" },
978 { "save", rpc_registry_save,
979 "Save a registry file" },
980 { "dump", rpc_registry_dump,
981 "Dump a registry file" },
982 { "copy", rpc_registry_copy,
983 "Copy a registry file" },
987 return net_run_function2(argc, argv, "net rpc registry", func);