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. */
22 #include "utils/net.h"
24 #include "reg_objects.h"
26 static BOOL reg_hive_key(const char *fullname, uint32 *reg_type,
27 const char **key_name)
32 sep = strchr_m(fullname, '\\');
39 len = strlen(fullname);
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;
56 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
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)
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,
80 if (!(NT_STATUS_IS_OK(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);
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)
102 uint32 num_subkeys, max_subkeylen, max_classlen;
103 uint32 num_values, max_valnamelen, max_valbufsize;
105 NTTIME last_changed_time;
107 struct winreg_String classname;
108 char **names, **classes;
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)) {
125 if (num_subkeys == 0) {
127 TALLOC_FREE(mem_ctx);
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 *,
135 status = NT_STATUS_NO_MEMORY;
139 for (i=0; i<num_subkeys; i++) {
141 struct winreg_StringBuf class_buf;
142 struct winreg_StringBuf name_buf;
147 class_buf.size = max_classlen+2;
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,
159 if (W_ERROR_EQUAL(ntstatus_to_werror(status),
160 WERR_NO_MORE_ITEMS) ) {
161 status = NT_STATUS_OK;
164 if (!NT_STATUS_IS_OK(status)) {
170 if (class_buf.name &&
171 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
172 status = NT_STATUS_NO_MEMORY;
176 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
177 status = NT_STATUS_NO_MEMORY;
181 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
182 modtimes, &modtime, sizeof(modtime))))) {
183 status = NT_STATUS_NO_MEMORY;
188 *pnum_keys = num_subkeys;
191 *pnames = talloc_move(ctx, &names);
194 *pclasses = talloc_move(ctx, &classes);
197 *pmodtimes = talloc_move(ctx, &modtimes);
200 status = NT_STATUS_OK;
203 TALLOC_FREE(mem_ctx);
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)
215 uint32 num_subkeys, max_subkeylen, max_classlen;
216 uint32 num_values, max_valnamelen, max_valbufsize;
218 NTTIME last_changed_time;
220 struct winreg_String classname;
221 struct registry_value **values;
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)) {
238 if (num_values == 0) {
240 TALLOC_FREE(mem_ctx);
244 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
245 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
247 status = NT_STATUS_NO_MEMORY;
251 for (i=0; i<num_values; i++) {
252 enum winreg_Type type = REG_NONE;
258 struct winreg_ValNameBuf name_buf;
263 name_buf.size = max_valnamelen + 2;
265 data_size = max_valbufsize;
266 data = TALLOC(mem_ctx, data_size);
269 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
274 if ( W_ERROR_EQUAL(ntstatus_to_werror(status),
275 WERR_NO_MORE_ITEMS) ) {
276 status = NT_STATUS_OK;
280 if (!(NT_STATUS_IS_OK(status))) {
284 if (name_buf.name == NULL) {
285 status = NT_STATUS_INVALID_PARAMETER;
289 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
290 status = NT_STATUS_NO_MEMORY;
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);
302 *pnum_values = num_values;
305 *pvalnames = talloc_move(ctx, &names);
308 *pvalues = talloc_move(ctx, &values);
311 status = NT_STATUS_OK;
314 TALLOC_FREE(mem_ctx);
318 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
319 struct rpc_pipe_client *pipe_hnd,
320 struct policy_handle *key_hnd,
322 const struct registry_value *value)
324 struct winreg_String name_string;
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);
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,
350 struct policy_handle hive_hnd, key_hnd;
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",
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")) {
373 value.v.sz.len = strlen(argv[3])+1;
374 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
377 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
378 status = NT_STATUS_NOT_IMPLEMENTED;
382 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
385 if (!NT_STATUS_IS_OK(status)) {
386 d_fprintf(stderr, "registry_setvalue failed: %s\n",
391 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
392 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
397 static int rpc_registry_setvalue( int argc, const char **argv )
400 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
401 "<valuename> <type> [<val>]+\n");
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,
417 struct policy_handle hive_hnd, key_hnd;
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",
429 valuename.name = argv[1];
431 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
434 if (!NT_STATUS_IS_OK(status)) {
435 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
439 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
440 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
445 static int rpc_registry_deletevalue( int argc, const char **argv )
448 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
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,
466 struct policy_handle hive_hnd, key_hnd;
467 struct winreg_String key, keyclass;
468 enum winreg_CreateAction action;
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,
478 if (!(NT_STATUS_IS_OK(status))) {
482 action = REG_ACTION_NONE;
485 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
486 keyclass, 0, REG_KEY_READ, NULL,
488 if (!NT_STATUS_IS_OK(status)) {
489 d_fprintf(stderr, "createkey returned %s\n",
491 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
496 case REG_ACTION_NONE:
497 d_printf("createkey did nothing -- huh?\n");
499 case REG_CREATED_NEW_KEY:
500 d_printf("createkey created %s\n", argv[0]);
502 case REG_OPENED_EXISTING_KEY:
503 d_printf("createkey opened existing %s\n", argv[0]);
507 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd);
508 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd);
513 static int rpc_registry_createkey( int argc, const char **argv )
516 d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
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,
533 struct policy_handle hive_hnd;
534 struct winreg_String key;
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,
543 if (!(NT_STATUS_IS_OK(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",
558 static int rpc_registry_deletekey( int argc, const char **argv )
561 d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
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,
580 POLICY_HND pol_hive, pol_key;
582 uint32 num_subkeys = 0;
583 uint32 num_values = 0;
584 char **names = NULL, **classes = NULL;
585 NTTIME **modtimes = NULL;
587 struct registry_value **values = NULL;
590 d_printf("Usage: net rpc enumerate <path> [recurse]\n");
591 d_printf("Example: net rpc enumerate 'HKLM\\Software\\Samba'\n");
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",
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",
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]))
619 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
621 if (!NT_STATUS_IS_OK(status)) {
622 d_fprintf(stderr, "enumerating values failed: %s\n",
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));
634 d_printf("Value = %d\n", v->v.dword);
638 d_printf("Value = \"%s\"\n", v->v.sz.str);
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]);
649 d_printf("Value = %d bytes\n",
650 (int)v->v.binary.length);
653 d_printf("Value = <unprintable>\n");
660 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
661 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
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,
686 WERROR result = WERR_GENERAL_FAILURE;
687 POLICY_HND pol_hive, pol_key;
688 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
689 struct winreg_String filename;
692 d_printf("Usage: net rpc backup <path> <file> \n");
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",
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]);
712 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key );
713 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive );
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 )
735 uint32 data_size, data;
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 ) {
747 rpcstr_pull( data_str, nk->values[i].data, sizeof(data_str), -1, STR_TERMINATE );
748 d_printf( "%s", data_str );
752 for ( j=0; j<data_size; j++ ) {
753 d_printf( "%c", nk->values[i].data[j] );
757 data = IVAL( nk->values[i].data, 0 );
758 d_printf("0x%x", data );
761 for ( j=0; j<data_size; j++ ) {
762 d_printf( "%x", nk->values[i].data[j] );
775 /********************************************************************
776 ********************************************************************/
778 static BOOL dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
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 );
790 dump_registry_tree( file, key, regpath );
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;
805 REGSUBKEY_CTR *subkeys;
809 if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) {
810 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
814 if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) {
815 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
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 );
849 /********************************************************************
850 ********************************************************************/
852 static int rpc_registry_dump( int argc, const char **argv )
858 d_printf("Usage: net rpc dump <file> \n");
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]);
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 );
876 d_printf("[%s]\n", nk->keyname);
880 dump_registry_tree( registry, nk, nk->keyname );
883 talloc_report_full( registry->mem_ctx, stderr );
885 d_printf("Closing registry...");
886 regfio_close( registry );
892 /********************************************************************
893 ********************************************************************/
895 static int rpc_registry_copy( int argc, const char **argv )
897 REGF_FILE *infile = NULL, *outfile = NULL;
902 d_printf("Usage: net rpc copy <srcfile> <newfile>\n");
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]);
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]);
920 /* get the root of the registry file */
922 if ((nk = regfio_rootkey( infile )) == NULL) {
923 d_fprintf(stderr, "Could not get rootkey\n");
926 d_printf("RootKey: [%s]\n", nk->keyname);
928 write_registry_tree( infile, nk, NULL, outfile, "" );
934 d_printf("Closing %s...", argv[1]);
936 regfio_close( outfile );
940 d_printf("Closing %s...", argv[0]);
942 regfio_close( infile );
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" },
974 return net_run_function2(argc, argv, "net rpc registry", func);