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"
22 #include "utils/net_registry_util.h"
24 #include "reg_objects.h"
25 #include "registry/reg_import.h"
28 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
29 uint32 *reg_type, const char **key_name)
32 char *hivename = NULL;
33 char *tmp_keyname = NULL;
35 TALLOC_CTX *tmp_ctx = talloc_stackframe();
37 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
38 if (!W_ERROR_IS_OK(werr)) {
42 *key_name = talloc_strdup(ctx, tmp_keyname);
43 if (*key_name == NULL) {
47 if (strequal(hivename, "HKLM") ||
48 strequal(hivename, "HKEY_LOCAL_MACHINE"))
50 (*reg_type) = HKEY_LOCAL_MACHINE;
51 } else if (strequal(hivename, "HKCR") ||
52 strequal(hivename, "HKEY_CLASSES_ROOT"))
54 (*reg_type) = HKEY_CLASSES_ROOT;
55 } else if (strequal(hivename, "HKU") ||
56 strequal(hivename, "HKEY_USERS"))
58 (*reg_type) = HKEY_USERS;
59 } else if (strequal(hivename, "HKCU") ||
60 strequal(hivename, "HKEY_CURRENT_USER"))
62 (*reg_type) = HKEY_CURRENT_USER;
63 } else if (strequal(hivename, "HKPD") ||
64 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
66 (*reg_type) = HKEY_PERFORMANCE_DATA;
68 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
80 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
81 struct rpc_pipe_client *pipe_hnd,
82 const char *name, uint32 access_mask,
83 struct policy_handle *hive_hnd,
84 struct policy_handle *key_hnd)
88 struct winreg_String key;
92 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
93 return NT_STATUS_INVALID_PARAMETER;
96 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
98 if (!(NT_STATUS_IS_OK(status))) {
102 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
103 access_mask, key_hnd, NULL);
104 if (!(NT_STATUS_IS_OK(status))) {
105 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
112 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
113 struct rpc_pipe_client *pipe_hnd,
114 struct policy_handle *key_hnd,
115 uint32 *pnum_keys, char ***pnames,
116 char ***pclasses, NTTIME ***pmodtimes)
120 uint32 num_subkeys, max_subkeylen, max_classlen;
121 uint32 num_values, max_valnamelen, max_valbufsize;
123 NTTIME last_changed_time;
125 struct winreg_String classname;
126 char **names, **classes;
129 if (!(mem_ctx = talloc_new(ctx))) {
130 return NT_STATUS_NO_MEMORY;
133 ZERO_STRUCT(classname);
134 status = rpccli_winreg_QueryInfoKey(
135 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
136 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
137 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
139 if (!NT_STATUS_IS_OK(status)) {
143 if (num_subkeys == 0) {
145 TALLOC_FREE(mem_ctx);
149 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
150 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
151 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
153 status = NT_STATUS_NO_MEMORY;
157 for (i=0; i<num_subkeys; i++) {
159 struct winreg_StringBuf class_buf;
160 struct winreg_StringBuf name_buf;
166 class_buf.size = max_classlen+2;
170 name_buf.size = max_subkeylen+2;
172 ZERO_STRUCT(modtime);
174 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
175 i, &name_buf, &class_buf,
178 if (W_ERROR_EQUAL(werr,
179 WERR_NO_MORE_ITEMS) ) {
180 status = NT_STATUS_OK;
183 if (!NT_STATUS_IS_OK(status)) {
189 if (class_buf.name &&
190 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
191 status = NT_STATUS_NO_MEMORY;
195 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
196 status = NT_STATUS_NO_MEMORY;
200 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
201 modtimes, &modtime, sizeof(modtime))))) {
202 status = NT_STATUS_NO_MEMORY;
207 *pnum_keys = num_subkeys;
210 *pnames = talloc_move(ctx, &names);
213 *pclasses = talloc_move(ctx, &classes);
216 *pmodtimes = talloc_move(ctx, &modtimes);
219 status = NT_STATUS_OK;
222 TALLOC_FREE(mem_ctx);
226 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
227 struct rpc_pipe_client *pipe_hnd,
228 struct policy_handle *key_hnd,
229 uint32 *pnum_values, char ***pvalnames,
230 struct registry_value ***pvalues)
234 uint32 num_subkeys, max_subkeylen, max_classlen;
235 uint32 num_values, max_valnamelen, max_valbufsize;
237 NTTIME last_changed_time;
239 struct winreg_String classname;
240 struct registry_value **values;
243 if (!(mem_ctx = talloc_new(ctx))) {
244 return NT_STATUS_NO_MEMORY;
247 ZERO_STRUCT(classname);
248 status = rpccli_winreg_QueryInfoKey(
249 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
250 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
251 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
253 if (!NT_STATUS_IS_OK(status)) {
257 if (num_values == 0) {
259 TALLOC_FREE(mem_ctx);
263 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
264 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
266 status = NT_STATUS_NO_MEMORY;
270 for (i=0; i<num_values; i++) {
271 enum winreg_Type type = REG_NONE;
277 struct winreg_ValNameBuf name_buf;
282 name_buf.size = max_valnamelen + 2;
284 data_size = max_valbufsize;
285 data = (uint8 *)TALLOC(mem_ctx, data_size);
288 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
291 &value_length, &err);
293 if ( W_ERROR_EQUAL(err,
294 WERR_NO_MORE_ITEMS) ) {
295 status = NT_STATUS_OK;
299 if (!(NT_STATUS_IS_OK(status))) {
303 if (name_buf.name == NULL) {
304 status = NT_STATUS_INVALID_PARAMETER;
308 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
309 status = NT_STATUS_NO_MEMORY;
313 err = registry_pull_value(values, &values[i], type, data,
314 data_size, value_length);
315 if (!W_ERROR_IS_OK(err)) {
316 status = werror_to_ntstatus(err);
321 *pnum_values = num_values;
324 *pvalnames = talloc_move(ctx, &names);
327 *pvalues = talloc_move(ctx, &values);
330 status = NT_STATUS_OK;
333 TALLOC_FREE(mem_ctx);
337 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
338 struct rpc_pipe_client *pipe_hnd,
339 struct policy_handle *key_hnd,
341 struct KeySecurityData *sd)
343 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
348 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
349 struct rpc_pipe_client *pipe_hnd,
350 struct policy_handle *key_hnd,
352 const struct registry_value *value)
354 struct winreg_String name_string;
359 err = registry_push_value(mem_ctx, value, &blob);
360 if (!W_ERROR_IS_OK(err)) {
361 return werror_to_ntstatus(err);
364 ZERO_STRUCT(name_string);
366 name_string.name = name;
367 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
368 name_string, value->type,
369 blob.data, blob.length, NULL);
370 TALLOC_FREE(blob.data);
374 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
375 const DOM_SID *domain_sid,
376 const char *domain_name,
377 struct cli_state *cli,
378 struct rpc_pipe_client *pipe_hnd,
383 struct policy_handle hive_hnd, key_hnd;
385 struct registry_value value;
387 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
388 SEC_FLAG_MAXIMUM_ALLOWED,
389 &hive_hnd, &key_hnd);
390 if (!NT_STATUS_IS_OK(status)) {
391 d_fprintf(stderr, "registry_openkey failed: %s\n",
396 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
397 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
398 return NT_STATUS_NOT_IMPLEMENTED;
401 if (strequal(argv[2], "dword")) {
402 value.type = REG_DWORD;
403 value.v.dword = strtoul(argv[3], NULL, 10);
405 else if (strequal(argv[2], "sz")) {
407 value.v.sz.len = strlen(argv[3])+1;
408 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
411 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
412 status = NT_STATUS_NOT_IMPLEMENTED;
416 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
419 if (!NT_STATUS_IS_OK(status)) {
420 d_fprintf(stderr, "registry_setvalue failed: %s\n",
425 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
426 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
431 static int rpc_registry_setvalue(struct net_context *c, int argc,
434 if (argc < 4 || c->display_usage) {
435 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
436 "<valuename> <type> [<val>]+\n");
440 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
441 rpc_registry_setvalue_internal, argc, argv );
444 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
445 const DOM_SID *domain_sid,
446 const char *domain_name,
447 struct cli_state *cli,
448 struct rpc_pipe_client *pipe_hnd,
453 struct policy_handle hive_hnd, key_hnd;
455 struct winreg_String valuename;
457 ZERO_STRUCT(valuename);
459 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
460 SEC_FLAG_MAXIMUM_ALLOWED,
461 &hive_hnd, &key_hnd);
462 if (!NT_STATUS_IS_OK(status)) {
463 d_fprintf(stderr, "registry_openkey failed: %s\n",
468 valuename.name = argv[1];
470 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
473 if (!NT_STATUS_IS_OK(status)) {
474 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
478 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
479 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
484 static int rpc_registry_deletevalue(struct net_context *c, int argc,
487 if (argc != 2 || c->display_usage) {
488 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
493 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
494 rpc_registry_deletevalue_internal, argc, argv );
497 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
498 const DOM_SID *domain_sid,
499 const char *domain_name,
500 struct cli_state *cli,
501 struct rpc_pipe_client *pipe_hnd,
507 struct policy_handle hive_hnd, key_hnd;
510 struct winreg_String valuename;
511 struct registry_value *value = NULL;
512 enum winreg_Type type = REG_NONE;
513 uint8_t *data = NULL;
514 uint32_t data_size = 0;
515 uint32_t value_length = 0;
516 TALLOC_CTX *tmp_ctx = talloc_stackframe();
518 ZERO_STRUCT(valuename);
520 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
521 SEC_FLAG_MAXIMUM_ALLOWED,
522 &hive_hnd, &key_hnd);
523 if (!NT_STATUS_IS_OK(status)) {
524 d_fprintf(stderr, "registry_openkey failed: %s\n",
529 valuename.name = argv[1];
532 * call QueryValue once with data == NULL to get the
533 * needed memory size to be allocated, then allocate
534 * data buffer and call again.
536 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
544 if (!NT_STATUS_IS_OK(status)) {
545 d_fprintf(stderr, "registry_queryvalue failed: %s\n",
550 data = (uint8 *)TALLOC(tmp_ctx, data_size);
553 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
561 if (!NT_STATUS_IS_OK(status)) {
562 d_fprintf(stderr, "registry_queryvalue failed: %s\n",
567 werr = registry_pull_value(tmp_ctx, &value, type, data,
568 data_size, value_length);
569 if (!W_ERROR_IS_OK(werr)) {
570 status = werror_to_ntstatus(werr);
574 print_registry_value(value, raw);
577 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
578 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
580 TALLOC_FREE(tmp_ctx);
585 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
586 const DOM_SID *domain_sid,
587 const char *domain_name,
588 struct cli_state *cli,
589 struct rpc_pipe_client *pipe_hnd,
594 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
595 cli, pipe_hnd, mem_ctx, false,
599 static int rpc_registry_getvalue(struct net_context *c, int argc,
602 if (argc != 2 || c->display_usage) {
603 d_fprintf(stderr, "usage: net rpc registry getvalue <key> "
608 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
609 rpc_registry_getvalue_full, argc, argv);
612 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
613 const DOM_SID *domain_sid,
614 const char *domain_name,
615 struct cli_state *cli,
616 struct rpc_pipe_client *pipe_hnd,
621 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
622 cli, pipe_hnd, mem_ctx, true,
626 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
629 if (argc != 2 || c->display_usage) {
630 d_fprintf(stderr, "usage: net rpc registry getvalue <key> "
635 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
636 rpc_registry_getvalue_raw, argc, argv);
639 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
640 const DOM_SID *domain_sid,
641 const char *domain_name,
642 struct cli_state *cli,
643 struct rpc_pipe_client *pipe_hnd,
649 struct policy_handle hive_hnd, key_hnd;
650 struct winreg_String key, keyclass;
651 enum winreg_CreateAction action;
655 ZERO_STRUCT(keyclass);
657 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
658 return NT_STATUS_INVALID_PARAMETER;
661 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
662 SEC_FLAG_MAXIMUM_ALLOWED,
664 if (!(NT_STATUS_IS_OK(status))) {
668 action = REG_ACTION_NONE;
671 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
672 keyclass, 0, REG_KEY_READ, NULL,
673 &key_hnd, &action, NULL);
674 if (!NT_STATUS_IS_OK(status)) {
675 d_fprintf(stderr, "createkey returned %s\n",
677 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
682 case REG_ACTION_NONE:
683 d_printf("createkey did nothing -- huh?\n");
685 case REG_CREATED_NEW_KEY:
686 d_printf("createkey created %s\n", argv[0]);
688 case REG_OPENED_EXISTING_KEY:
689 d_printf("createkey opened existing %s\n", argv[0]);
693 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
694 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
699 static int rpc_registry_createkey(struct net_context *c, int argc,
702 if (argc != 1 || c->display_usage) {
703 d_fprintf(stderr, "usage: net rpc registry createkey <key>\n");
707 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
708 rpc_registry_createkey_internal, argc, argv );
711 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
712 const DOM_SID *domain_sid,
713 const char *domain_name,
714 struct cli_state *cli,
715 struct rpc_pipe_client *pipe_hnd,
721 struct policy_handle hive_hnd;
722 struct winreg_String key;
727 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
728 return NT_STATUS_INVALID_PARAMETER;
731 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
732 SEC_FLAG_MAXIMUM_ALLOWED,
734 if (!(NT_STATUS_IS_OK(status))) {
738 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
739 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
741 if (!NT_STATUS_IS_OK(status)) {
742 d_fprintf(stderr, "deletekey returned %s\n",
749 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
751 if (argc != 1 || c->display_usage) {
752 d_fprintf(stderr, "usage: net rpc registry deletekey <key>\n");
756 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
757 rpc_registry_deletekey_internal, argc, argv );
760 /********************************************************************
761 ********************************************************************/
763 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
764 const DOM_SID *domain_sid,
765 const char *domain_name,
766 struct cli_state *cli,
767 struct rpc_pipe_client *pipe_hnd,
772 struct policy_handle pol_hive, pol_key;
774 uint32 num_subkeys = 0;
775 uint32 num_values = 0;
776 char **names = NULL, **classes = NULL;
777 NTTIME **modtimes = NULL;
779 struct registry_value **values = NULL;
781 if (argc != 1 || c->display_usage) {
782 d_printf("Usage: net rpc registry enumerate <path>\n");
783 d_printf("Example: net rpc registry enumerate 'HKLM\\Software\\Samba'\n");
784 return NT_STATUS_INVALID_PARAMETER;
787 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
788 &pol_hive, &pol_key);
789 if (!NT_STATUS_IS_OK(status)) {
790 d_fprintf(stderr, "registry_openkey failed: %s\n",
795 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
796 &names, &classes, &modtimes);
797 if (!NT_STATUS_IS_OK(status)) {
798 d_fprintf(stderr, "enumerating keys failed: %s\n",
803 for (i=0; i<num_subkeys; i++) {
804 print_registry_key(names[i], modtimes[i]);
807 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
809 if (!NT_STATUS_IS_OK(status)) {
810 d_fprintf(stderr, "enumerating values failed: %s\n",
815 for (i=0; i<num_values; i++) {
816 print_registry_value_with_name(names[i], values[i]);
819 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
820 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
825 /********************************************************************
826 ********************************************************************/
828 static int rpc_registry_enumerate(struct net_context *c, int argc,
831 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
832 rpc_registry_enumerate_internal, argc, argv );
835 /********************************************************************
836 ********************************************************************/
838 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
839 const DOM_SID *domain_sid,
840 const char *domain_name,
841 struct cli_state *cli,
842 struct rpc_pipe_client *pipe_hnd,
847 WERROR result = WERR_GENERAL_FAILURE;
848 struct policy_handle pol_hive, pol_key;
849 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
850 struct winreg_String filename;
852 if (argc != 2 || c->display_usage) {
853 d_printf("Usage: net rpc registry backup <path> <file> \n");
854 return NT_STATUS_INVALID_PARAMETER;
857 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
858 &pol_hive, &pol_key);
859 if (!NT_STATUS_IS_OK(status)) {
860 d_fprintf(stderr, "registry_openkey failed: %s\n",
865 filename.name = argv[1];
866 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
867 if ( !W_ERROR_IS_OK(result) ) {
868 d_fprintf(stderr, "Unable to save [%s] to %s:%s\n", argv[0], cli->desthost, argv[1]);
873 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
874 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
879 /********************************************************************
880 ********************************************************************/
882 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
884 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
885 rpc_registry_save_internal, argc, argv );
889 /********************************************************************
890 ********************************************************************/
892 static void dump_values( REGF_NK_REC *nk )
895 char *data_str = NULL;
896 uint32 data_size, data;
901 for ( i=0; i<nk->num_values; i++ ) {
902 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
903 d_printf( "(%s) ", reg_type_lookup( nk->values[i].type ) );
905 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
906 switch ( nk->values[i].type ) {
908 rpcstr_pull_talloc(talloc_tos(),
916 d_printf( "%s", data_str );
920 for ( j=0; j<data_size; j++ ) {
921 d_printf( "%c", nk->values[i].data[j] );
925 data = IVAL( nk->values[i].data, 0 );
926 d_printf("0x%x", data );
929 for ( j=0; j<data_size; j++ ) {
930 d_printf( "%x", nk->values[i].data[j] );
943 /********************************************************************
944 ********************************************************************/
946 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
950 /* depth first dump of the registry tree */
952 while ( (key = regfio_fetch_subkey( file, nk )) ) {
954 if (asprintf(®path, "%s\\%s", parent, key->keyname) < 0) {
957 d_printf("[%s]\n", regpath );
960 dump_registry_tree( file, key, regpath );
967 /********************************************************************
968 ********************************************************************/
970 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
971 REGF_NK_REC *parent, REGF_FILE *outfile,
972 const char *parentpath )
974 REGF_NK_REC *key, *subkey;
975 struct regval_ctr *values = NULL;
976 struct regsubkey_ctr *subkeys = NULL;
981 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
982 if (!W_ERROR_IS_OK(werr)) {
983 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
984 "%s\n", win_errstr(werr)));
988 if ( !(values = TALLOC_ZERO_P( subkeys, struct regval_ctr )) ) {
989 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
990 TALLOC_FREE(subkeys);
994 /* copy values into the struct regval_ctr */
996 for ( i=0; i<nk->num_values; i++ ) {
997 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
998 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1001 /* copy subkeys into the struct regsubkey_ctr */
1003 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1004 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1007 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1009 /* write each one of the subkeys out */
1011 path = talloc_asprintf(subkeys,
1017 TALLOC_FREE(subkeys);
1021 nk->subkey_index = 0;
1022 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1023 write_registry_tree( infile, subkey, key, outfile, path );
1026 d_printf("[%s]\n", path );
1027 TALLOC_FREE(subkeys);
1032 /********************************************************************
1033 ********************************************************************/
1035 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1037 REGF_FILE *registry;
1040 if (argc != 1 || c->display_usage) {
1041 d_printf("Usage: net rpc registry dump <file> \n");
1045 d_printf("Opening %s....", argv[0]);
1046 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1047 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
1052 /* get the root of the registry file */
1054 if ((nk = regfio_rootkey( registry )) == NULL) {
1055 d_fprintf(stderr, "Could not get rootkey\n");
1056 regfio_close( registry );
1059 d_printf("[%s]\n", nk->keyname);
1063 dump_registry_tree( registry, nk, nk->keyname );
1066 talloc_report_full( registry->mem_ctx, stderr );
1068 d_printf("Closing registry...");
1069 regfio_close( registry );
1075 /********************************************************************
1076 ********************************************************************/
1078 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1080 REGF_FILE *infile = NULL, *outfile = NULL;
1084 if (argc != 2 || c->display_usage) {
1085 d_printf("Usage: net rpc registry copy <srcfile> <newfile>\n");
1089 d_printf("Opening %s....", argv[0]);
1090 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1091 d_fprintf(stderr, "Failed to open %s for reading\n", argv[0]);
1096 d_printf("Opening %s....", argv[1]);
1097 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1098 d_fprintf(stderr, "Failed to open %s for writing\n", argv[1]);
1103 /* get the root of the registry file */
1105 if ((nk = regfio_rootkey( infile )) == NULL) {
1106 d_fprintf(stderr, "Could not get rootkey\n");
1109 d_printf("RootKey: [%s]\n", nk->keyname);
1111 write_registry_tree( infile, nk, NULL, outfile, "" );
1117 d_printf("Closing %s...", argv[1]);
1119 regfio_close( outfile );
1123 d_printf("Closing %s...", argv[0]);
1125 regfio_close( infile );
1132 /********************************************************************
1133 ********************************************************************/
1135 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1136 const DOM_SID *domain_sid,
1137 const char *domain_name,
1138 struct cli_state *cli,
1139 struct rpc_pipe_client *pipe_hnd,
1140 TALLOC_CTX *mem_ctx,
1144 struct policy_handle pol_hive, pol_key;
1146 enum ndr_err_code ndr_err;
1147 struct KeySecurityData *sd = NULL;
1150 struct security_descriptor sec_desc;
1151 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1152 SEC_FLAG_SYSTEM_SECURITY;
1155 if (argc <1 || argc > 2 || c->display_usage) {
1156 d_printf("Usage: net rpc registry getsd <path> <secinfo>\n");
1157 d_printf("Example: net rpc registry getsd 'HKLM\\Software\\Samba'\n");
1158 return NT_STATUS_INVALID_PARAMETER;
1161 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1163 &pol_hive, &pol_key);
1164 if (!NT_STATUS_IS_OK(status)) {
1165 d_fprintf(stderr, "registry_openkey failed: %s\n",
1170 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1172 status = NT_STATUS_NO_MEMORY;
1179 sscanf(argv[1], "%x", &sec_info);
1181 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1184 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 d_fprintf(stderr, "getting sd failed: %s\n",
1191 blob.data = sd->data;
1192 blob.length = sd->size;
1194 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
1195 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1196 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1197 status = ndr_map_error2ntstatus(ndr_err);
1200 status = NT_STATUS_OK;
1202 display_sec_desc(&sec_desc);
1205 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1206 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1212 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1214 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1215 rpc_registry_getsd_internal, argc, argv);
1218 /********************************************************************
1219 ********************************************************************/
1221 * @defgroup net_rpc_registry_import Import
1222 * @ingroup net_rpc_registry
1227 struct rpc_pipe_client *pipe_hnd;
1228 TALLOC_CTX *mem_ctx;
1231 static WERROR import_create_key(struct import_ctx* ctx,
1232 struct policy_handle* parent, const char* name,
1233 void** pkey, bool* existing)
1235 WERROR werr=WERR_OK;
1237 void* mem_ctx = talloc_new(ctx->mem_ctx);
1239 struct policy_handle* key = NULL;
1240 struct policy_handle hive;
1241 struct winreg_String keyclass, keyname;
1242 enum winreg_CreateAction action = REG_ACTION_NONE;
1244 ZERO_STRUCT(keyname);
1245 keyname.name = name;
1247 if (parent == NULL) {
1248 uint32 hive_idx = 0;
1249 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1254 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx,
1255 hive_idx, SEC_FLAG_MAXIMUM_ALLOWED,
1257 werr = ntstatus_to_werror(status);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 d_fprintf(stderr, "rpccli_winreg_Connect returned %s\n",
1268 key = talloc_zero(mem_ctx, struct policy_handle);
1274 ZERO_STRUCT(keyclass);
1277 status = rpccli_winreg_CreateKey(ctx->pipe_hnd, mem_ctx,
1279 keyclass, 0, REG_KEY_READ, NULL,
1280 key, &action, &werr);
1281 if (!NT_STATUS_IS_OK(status)) {
1282 d_fprintf(stderr, "rpccli_winreg_CreateKey returned %s\n",
1288 case REG_CREATED_NEW_KEY:
1289 d_printf("createkey created %s\n", name);
1290 if (existing != NULL)
1294 case REG_OPENED_EXISTING_KEY:
1295 d_printf("createkey opened existing %s\n", name);
1296 if (existing != NULL)
1300 case REG_ACTION_NONE:
1301 d_printf("createkey did nothing -- huh?\n");
1309 if ( parent == &hive ) {
1310 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx,
1315 *pkey = talloc_steal(ctx->mem_ctx, key);
1318 talloc_free(mem_ctx);
1322 static WERROR import_delete_key(struct import_ctx* ctx,
1323 struct policy_handle* parent, const char* name)
1327 void* mem_ctx = talloc_new(ctx->mem_ctx);
1328 struct winreg_String keyname;
1329 struct policy_handle hive;
1331 keyname.name = name;
1333 if (parent == NULL) {
1335 if (!reg_hive_key(mem_ctx, name, &hive_idx, &keyname.name)) {
1340 status = rpccli_winreg_Connect(ctx->pipe_hnd, mem_ctx, hive_idx,
1341 SEC_FLAG_MAXIMUM_ALLOWED, &hive);
1342 werr = ntstatus_to_werror(status);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 d_fprintf(stderr, "rpccli_winreg_Connect returned %s\n",
1352 status = rpccli_winreg_DeleteKey(ctx->pipe_hnd, mem_ctx, parent,
1354 if (!NT_STATUS_IS_OK(status)) {
1355 d_fprintf(stderr, "rpccli_winreg_DeleteKey returned %s\n",
1361 if ( parent == &hive ) {
1362 rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, parent, NULL);
1365 talloc_free(mem_ctx);
1369 static WERROR import_close_key(struct import_ctx* ctx,
1370 struct policy_handle* key)
1374 void* mem_ctx = talloc_new(ctx->mem_ctx);
1376 status = rpccli_winreg_CloseKey(ctx->pipe_hnd, mem_ctx, key, &werr);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 d_fprintf(stderr, "rpccli_winreg_CloseKey returned %s\n",
1383 werr = (talloc_free(key) == 0) ? WERR_OK : WERR_GENERAL_FAILURE;
1385 talloc_free(mem_ctx);
1389 static WERROR import_create_val(struct import_ctx* ctx,
1390 struct policy_handle* parent, const char* name,
1391 uint32_t type, const uint8_t* val, uint32_t len)
1395 void* mem_ctx = talloc_new(ctx->mem_ctx);
1396 struct winreg_String valuename;
1398 if (parent == NULL) {
1399 return WERR_INVALID_PARAM;
1402 ZERO_STRUCT(valuename);
1403 valuename.name = name;
1405 status = rpccli_winreg_SetValue(ctx->pipe_hnd, mem_ctx, parent,
1407 discard_const(val), len, &werr);
1408 if (!NT_STATUS_IS_OK(status)) {
1409 d_fprintf(stderr, "registry_setvalue failed: %s\n",
1415 talloc_free(mem_ctx);
1419 static WERROR import_delete_val(struct import_ctx* ctx,
1420 struct policy_handle* parent, const char* name)
1424 void* mem_ctx = talloc_new(ctx->mem_ctx);
1425 struct winreg_String valuename;
1427 if (parent == NULL) {
1428 return WERR_INVALID_PARAM;
1431 ZERO_STRUCT(valuename);
1432 valuename.name = name;
1434 status = rpccli_winreg_DeleteValue(ctx->pipe_hnd, mem_ctx,
1435 parent, valuename, &werr);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 d_fprintf(stderr, "registry_deletevalue failed: %s\n",
1443 talloc_free(mem_ctx);
1449 static NTSTATUS rpc_registry_import_internal(struct net_context *c,
1450 const DOM_SID *domain_sid,
1451 const char *domain_name,
1452 struct cli_state *cli,
1453 struct rpc_pipe_client *pipe_hnd,
1454 TALLOC_CTX *mem_ctx,
1458 struct import_ctx import_ctx;
1460 struct reg_import_callback import_callback = {
1462 .closekey = (reg_import_callback_closekey_t)&import_close_key,
1463 .createkey = (reg_import_callback_createkey_t)&import_create_key,
1464 .deletekey = (reg_import_callback_deletekey_t)&import_delete_key,
1465 .deleteval = (reg_import_callback_deleteval_t)&import_delete_val,
1466 .setval.blob = (reg_import_callback_setval_blob_t)&import_create_val,
1467 .setval_type = BLOB,
1472 if (argc < 1 || argc > 2 || c->display_usage) {
1475 "net rpc registry import <file> [options]\n");
1476 d_printf("%s net rpc registry export "
1477 "samba.reg enc=CP1252,flags=0\n", "Example:");
1478 return NT_STATUS_INVALID_PARAMETER;
1480 ZERO_STRUCT(import_ctx);
1481 import_ctx.pipe_hnd = pipe_hnd;
1482 import_ctx.mem_ctx = mem_ctx;
1483 ret = reg_parse_file(argv[0],
1484 reg_import_adapter(import_ctx.mem_ctx,
1487 (argc > 1) ? argv[1] : NULL
1490 return ret==0 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1494 static int rpc_registry_import(struct net_context *c, int argc,
1497 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1498 rpc_registry_import_internal, argc, argv );
1502 /********************************************************************
1503 ********************************************************************/
1505 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1507 struct functable func[] = {
1510 rpc_registry_enumerate,
1512 "Enumerate registry keys and values",
1513 "net rpc registry enumerate\n"
1514 " Enumerate registry keys and values"
1518 rpc_registry_createkey,
1520 "Create a new registry key",
1521 "net rpc registry createkey\n"
1522 " Create a new registry key"
1526 rpc_registry_deletekey,
1528 "Delete a registry key",
1529 "net rpc registry deletekey\n"
1530 " Delete a registry key"
1534 rpc_registry_getvalue,
1536 "Print a registry value",
1537 "net rpc registry getvalue\n"
1538 " Print a registry value"
1542 rpc_registry_getvalueraw,
1544 "Print a registry value",
1545 "net rpc registry getvalueraw\n"
1546 " Print a registry value (raw version)"
1550 rpc_registry_setvalue,
1552 "Set a new registry value",
1553 "net rpc registry setvalue\n"
1554 " Set a new registry value"
1558 rpc_registry_deletevalue,
1560 "Delete a registry value",
1561 "net rpc registry deletevalue\n"
1562 " Delete a registry value"
1568 "Save a registry file",
1569 "net rpc registry save\n"
1570 " Save a registry file"
1576 "Dump a registry file",
1577 "net rpc registry dump\n"
1578 " Dump a registry file"
1584 "Copy a registry file",
1585 "net rpc registry copy\n"
1586 " Copy a registry file"
1592 "Get security descriptor",
1593 "net rpc registry getsd\n"
1594 " Get security descriptior"
1598 rpc_registry_import,
1601 "net rpc registry import\n"
1604 {NULL, NULL, 0, NULL, NULL}
1607 return net_run_function(c, argc, argv, "net rpc registry", func);