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/>. */
22 #include "utils/net.h"
23 #include "utils/net_registry_util.h"
25 #include "../librpc/gen_ndr/cli_winreg.h"
27 /*******************************************************************
28 connect to a registry hive root (open a registry policy)
29 *******************************************************************/
31 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
32 uint32_t reg_type, uint32_t access_mask,
33 struct policy_handle *reg_hnd)
35 ZERO_STRUCTP(reg_hnd);
39 case HKEY_CLASSES_ROOT:
40 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
41 access_mask, reg_hnd, NULL);
43 case HKEY_LOCAL_MACHINE:
44 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
45 access_mask, reg_hnd, NULL);
48 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
49 access_mask, reg_hnd, NULL);
51 case HKEY_CURRENT_USER:
52 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
53 access_mask, reg_hnd, NULL);
55 case HKEY_PERFORMANCE_DATA:
56 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
57 access_mask, reg_hnd, NULL);
60 /* fall through to end of function */
64 return NT_STATUS_INVALID_PARAMETER;
67 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
68 uint32 *reg_type, const char **key_name)
71 char *hivename = NULL;
72 char *tmp_keyname = NULL;
74 TALLOC_CTX *tmp_ctx = talloc_stackframe();
76 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
77 if (!W_ERROR_IS_OK(werr)) {
81 *key_name = talloc_strdup(ctx, tmp_keyname);
82 if (*key_name == NULL) {
86 if (strequal(hivename, "HKLM") ||
87 strequal(hivename, "HKEY_LOCAL_MACHINE"))
89 (*reg_type) = HKEY_LOCAL_MACHINE;
90 } else if (strequal(hivename, "HKCR") ||
91 strequal(hivename, "HKEY_CLASSES_ROOT"))
93 (*reg_type) = HKEY_CLASSES_ROOT;
94 } else if (strequal(hivename, "HKU") ||
95 strequal(hivename, "HKEY_USERS"))
97 (*reg_type) = HKEY_USERS;
98 } else if (strequal(hivename, "HKCU") ||
99 strequal(hivename, "HKEY_CURRENT_USER"))
101 (*reg_type) = HKEY_CURRENT_USER;
102 } else if (strequal(hivename, "HKPD") ||
103 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
105 (*reg_type) = HKEY_PERFORMANCE_DATA;
107 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
115 TALLOC_FREE(tmp_ctx);
119 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
120 struct rpc_pipe_client *pipe_hnd,
121 const char *name, uint32 access_mask,
122 struct policy_handle *hive_hnd,
123 struct policy_handle *key_hnd)
127 struct winreg_String key;
131 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
132 return NT_STATUS_INVALID_PARAMETER;
135 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
137 if (!(NT_STATUS_IS_OK(status))) {
141 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
142 access_mask, key_hnd, NULL);
143 if (!(NT_STATUS_IS_OK(status))) {
144 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
151 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
152 struct rpc_pipe_client *pipe_hnd,
153 struct policy_handle *key_hnd,
154 uint32 *pnum_keys, char ***pnames,
155 char ***pclasses, NTTIME ***pmodtimes)
159 uint32 num_subkeys, max_subkeylen, max_classlen;
160 uint32 num_values, max_valnamelen, max_valbufsize;
162 NTTIME last_changed_time;
164 struct winreg_String classname;
165 char **names, **classes;
168 if (!(mem_ctx = talloc_new(ctx))) {
169 return NT_STATUS_NO_MEMORY;
172 ZERO_STRUCT(classname);
173 status = rpccli_winreg_QueryInfoKey(
174 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
175 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
176 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
178 if (!NT_STATUS_IS_OK(status)) {
182 if (num_subkeys == 0) {
184 TALLOC_FREE(mem_ctx);
188 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
189 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
190 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
192 status = NT_STATUS_NO_MEMORY;
196 for (i=0; i<num_subkeys; i++) {
198 struct winreg_StringBuf class_buf;
199 struct winreg_StringBuf name_buf;
205 class_buf.size = max_classlen+2;
209 name_buf.size = max_subkeylen+2;
211 ZERO_STRUCT(modtime);
213 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
214 i, &name_buf, &class_buf,
217 if (W_ERROR_EQUAL(werr,
218 WERR_NO_MORE_ITEMS) ) {
219 status = NT_STATUS_OK;
222 if (!NT_STATUS_IS_OK(status)) {
228 if (class_buf.name &&
229 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
230 status = NT_STATUS_NO_MEMORY;
234 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
235 status = NT_STATUS_NO_MEMORY;
239 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
240 modtimes, &modtime, sizeof(modtime))))) {
241 status = NT_STATUS_NO_MEMORY;
246 *pnum_keys = num_subkeys;
249 *pnames = talloc_move(ctx, &names);
252 *pclasses = talloc_move(ctx, &classes);
255 *pmodtimes = talloc_move(ctx, &modtimes);
258 status = NT_STATUS_OK;
261 TALLOC_FREE(mem_ctx);
265 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
266 struct rpc_pipe_client *pipe_hnd,
267 struct policy_handle *key_hnd,
268 uint32 *pnum_values, char ***pvalnames,
269 struct registry_value ***pvalues)
273 uint32 num_subkeys, max_subkeylen, max_classlen;
274 uint32 num_values, max_valnamelen, max_valbufsize;
276 NTTIME last_changed_time;
278 struct winreg_String classname;
279 struct registry_value **values;
282 if (!(mem_ctx = talloc_new(ctx))) {
283 return NT_STATUS_NO_MEMORY;
286 ZERO_STRUCT(classname);
287 status = rpccli_winreg_QueryInfoKey(
288 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
289 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
290 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
292 if (!NT_STATUS_IS_OK(status)) {
296 if (num_values == 0) {
298 TALLOC_FREE(mem_ctx);
302 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
303 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
305 status = NT_STATUS_NO_MEMORY;
309 for (i=0; i<num_values; i++) {
310 enum winreg_Type type = REG_NONE;
316 struct winreg_ValNameBuf name_buf;
321 name_buf.size = max_valnamelen + 2;
323 data_size = max_valbufsize;
324 data = (uint8 *)TALLOC(mem_ctx, data_size);
327 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
330 &value_length, &err);
332 if ( W_ERROR_EQUAL(err,
333 WERR_NO_MORE_ITEMS) ) {
334 status = NT_STATUS_OK;
338 if (!(NT_STATUS_IS_OK(status))) {
342 if (name_buf.name == NULL) {
343 status = NT_STATUS_INVALID_PARAMETER;
347 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
348 status = NT_STATUS_NO_MEMORY;
352 err = registry_pull_value(values, &values[i], type, data,
353 data_size, value_length);
354 if (!W_ERROR_IS_OK(err)) {
355 status = werror_to_ntstatus(err);
360 *pnum_values = num_values;
363 *pvalnames = talloc_move(ctx, &names);
366 *pvalues = talloc_move(ctx, &values);
369 status = NT_STATUS_OK;
372 TALLOC_FREE(mem_ctx);
376 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
377 struct rpc_pipe_client *pipe_hnd,
378 struct policy_handle *key_hnd,
380 struct KeySecurityData *sd)
382 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
387 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
388 struct rpc_pipe_client *pipe_hnd,
389 struct policy_handle *key_hnd,
391 const struct registry_value *value)
393 struct winreg_String name_string;
398 err = registry_push_value(mem_ctx, value, &blob);
399 if (!W_ERROR_IS_OK(err)) {
400 return werror_to_ntstatus(err);
403 ZERO_STRUCT(name_string);
405 name_string.name = name;
406 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
407 name_string, value->type,
408 blob.data, blob.length, NULL);
409 TALLOC_FREE(blob.data);
413 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
414 const DOM_SID *domain_sid,
415 const char *domain_name,
416 struct cli_state *cli,
417 struct rpc_pipe_client *pipe_hnd,
422 struct policy_handle hive_hnd, key_hnd;
424 struct registry_value value;
426 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 &hive_hnd, &key_hnd);
429 if (!NT_STATUS_IS_OK(status)) {
430 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
435 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
436 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
437 return NT_STATUS_NOT_IMPLEMENTED;
440 if (strequal(argv[2], "dword")) {
441 value.type = REG_DWORD;
442 value.v.dword = strtoul(argv[3], NULL, 10);
444 else if (strequal(argv[2], "sz")) {
446 value.v.sz.len = strlen(argv[3])+1;
447 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
450 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
451 status = NT_STATUS_NOT_IMPLEMENTED;
455 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
458 if (!NT_STATUS_IS_OK(status)) {
459 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
464 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
470 static int rpc_registry_setvalue(struct net_context *c, int argc,
473 if (argc < 4 || c->display_usage) {
474 d_fprintf(stderr, "%s\n%s",
476 _("net rpc registry setvalue <key> <valuename> "
477 "<type> [<val>]+\n"));
481 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
482 rpc_registry_setvalue_internal, argc, argv );
485 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
486 const DOM_SID *domain_sid,
487 const char *domain_name,
488 struct cli_state *cli,
489 struct rpc_pipe_client *pipe_hnd,
494 struct policy_handle hive_hnd, key_hnd;
496 struct winreg_String valuename;
498 ZERO_STRUCT(valuename);
500 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
501 SEC_FLAG_MAXIMUM_ALLOWED,
502 &hive_hnd, &key_hnd);
503 if (!NT_STATUS_IS_OK(status)) {
504 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
509 valuename.name = argv[1];
511 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
514 if (!NT_STATUS_IS_OK(status)) {
515 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
519 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
525 static int rpc_registry_deletevalue(struct net_context *c, int argc,
528 if (argc != 2 || c->display_usage) {
529 d_fprintf(stderr, "%s\n%s",
531 _("net rpc registry deletevalue <key> <valuename>\n"));
535 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
536 rpc_registry_deletevalue_internal, argc, argv );
539 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
540 const DOM_SID *domain_sid,
541 const char *domain_name,
542 struct cli_state *cli,
543 struct rpc_pipe_client *pipe_hnd,
549 struct policy_handle hive_hnd, key_hnd;
552 struct winreg_String valuename;
553 struct registry_value *value = NULL;
554 enum winreg_Type type = REG_NONE;
555 uint8_t *data = NULL;
556 uint32_t data_size = 0;
557 uint32_t value_length = 0;
558 TALLOC_CTX *tmp_ctx = talloc_stackframe();
560 ZERO_STRUCT(valuename);
562 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
563 SEC_FLAG_MAXIMUM_ALLOWED,
564 &hive_hnd, &key_hnd);
565 if (!NT_STATUS_IS_OK(status)) {
566 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
571 valuename.name = argv[1];
574 * call QueryValue once with data == NULL to get the
575 * needed memory size to be allocated, then allocate
576 * data buffer and call again.
578 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
586 if (!NT_STATUS_IS_OK(status)) {
587 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
592 data = (uint8 *)TALLOC(tmp_ctx, data_size);
595 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
603 if (!NT_STATUS_IS_OK(status)) {
604 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
609 werr = registry_pull_value(tmp_ctx, &value, type, data,
610 data_size, value_length);
611 if (!W_ERROR_IS_OK(werr)) {
612 status = werror_to_ntstatus(werr);
616 print_registry_value(value, raw);
619 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
620 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
622 TALLOC_FREE(tmp_ctx);
627 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
628 const DOM_SID *domain_sid,
629 const char *domain_name,
630 struct cli_state *cli,
631 struct rpc_pipe_client *pipe_hnd,
636 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
637 cli, pipe_hnd, mem_ctx, false,
641 static int rpc_registry_getvalue(struct net_context *c, int argc,
644 if (argc != 2 || c->display_usage) {
645 d_fprintf(stderr, "%s\n%s",
647 _("net rpc registry getvalue <key> <valuename>\n"));
651 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
652 rpc_registry_getvalue_full, argc, argv);
655 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
656 const DOM_SID *domain_sid,
657 const char *domain_name,
658 struct cli_state *cli,
659 struct rpc_pipe_client *pipe_hnd,
664 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
665 cli, pipe_hnd, mem_ctx, true,
669 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
672 if (argc != 2 || c->display_usage) {
673 d_fprintf(stderr, "%s\n%s",
675 _("net rpc registry getvalue <key> <valuename>\n"));
679 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
680 rpc_registry_getvalue_raw, argc, argv);
683 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
684 const DOM_SID *domain_sid,
685 const char *domain_name,
686 struct cli_state *cli,
687 struct rpc_pipe_client *pipe_hnd,
693 struct policy_handle hive_hnd, key_hnd;
694 struct winreg_String key, keyclass;
695 enum winreg_CreateAction action;
699 ZERO_STRUCT(keyclass);
701 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
702 return NT_STATUS_INVALID_PARAMETER;
705 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
706 SEC_FLAG_MAXIMUM_ALLOWED,
708 if (!(NT_STATUS_IS_OK(status))) {
712 action = REG_ACTION_NONE;
715 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
716 keyclass, 0, REG_KEY_READ, NULL,
717 &key_hnd, &action, NULL);
718 if (!NT_STATUS_IS_OK(status)) {
719 d_fprintf(stderr, _("createkey returned %s\n"),
721 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
726 case REG_ACTION_NONE:
727 d_printf(_("createkey did nothing -- huh?\n"));
729 case REG_CREATED_NEW_KEY:
730 d_printf(_("createkey created %s\n"), argv[0]);
732 case REG_OPENED_EXISTING_KEY:
733 d_printf(_("createkey opened existing %s\n"), argv[0]);
737 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
738 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
743 static int rpc_registry_createkey(struct net_context *c, int argc,
746 if (argc != 1 || c->display_usage) {
747 d_fprintf(stderr, "%s\n%s",
749 _("net rpc registry createkey <key>\n"));
753 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
754 rpc_registry_createkey_internal, argc, argv );
757 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
758 const DOM_SID *domain_sid,
759 const char *domain_name,
760 struct cli_state *cli,
761 struct rpc_pipe_client *pipe_hnd,
767 struct policy_handle hive_hnd;
768 struct winreg_String key;
773 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
774 return NT_STATUS_INVALID_PARAMETER;
777 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
778 SEC_FLAG_MAXIMUM_ALLOWED,
780 if (!(NT_STATUS_IS_OK(status))) {
784 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
785 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
787 if (!NT_STATUS_IS_OK(status)) {
788 d_fprintf(stderr, _("deletekey returned %s\n"),
795 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
797 if (argc != 1 || c->display_usage) {
798 d_fprintf(stderr, "%s\n%s",
800 _("net rpc registry deletekey <key>\n"));
804 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
805 rpc_registry_deletekey_internal, argc, argv );
808 /********************************************************************
809 ********************************************************************/
811 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
812 const DOM_SID *domain_sid,
813 const char *domain_name,
814 struct cli_state *cli,
815 struct rpc_pipe_client *pipe_hnd,
820 struct policy_handle pol_hive, pol_key;
822 uint32 num_subkeys = 0;
823 uint32 num_values = 0;
824 char **names = NULL, **classes = NULL;
825 NTTIME **modtimes = NULL;
827 struct registry_value **values = NULL;
829 if (argc != 1 || c->display_usage) {
832 _("net rpc registry enumerate <path>\n"));
833 d_printf("%s net rpc registry enumerate "
834 "'HKLM\\Software\\Samba'\n", _("Example:"));
835 return NT_STATUS_INVALID_PARAMETER;
838 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
839 &pol_hive, &pol_key);
840 if (!NT_STATUS_IS_OK(status)) {
841 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
846 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
847 &names, &classes, &modtimes);
848 if (!NT_STATUS_IS_OK(status)) {
849 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
854 for (i=0; i<num_subkeys; i++) {
855 print_registry_key(names[i], modtimes[i]);
858 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
860 if (!NT_STATUS_IS_OK(status)) {
861 d_fprintf(stderr, _("enumerating values failed: %s\n"),
866 for (i=0; i<num_values; i++) {
867 print_registry_value_with_name(names[i], values[i]);
870 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
871 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
876 /********************************************************************
877 ********************************************************************/
879 static int rpc_registry_enumerate(struct net_context *c, int argc,
882 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
883 rpc_registry_enumerate_internal, argc, argv );
886 /********************************************************************
887 ********************************************************************/
889 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
890 const DOM_SID *domain_sid,
891 const char *domain_name,
892 struct cli_state *cli,
893 struct rpc_pipe_client *pipe_hnd,
898 WERROR result = WERR_GENERAL_FAILURE;
899 struct policy_handle pol_hive, pol_key;
900 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
901 struct winreg_String filename;
903 if (argc != 2 || c->display_usage) {
906 _("net rpc registry backup <path> <file> \n"));
907 return NT_STATUS_INVALID_PARAMETER;
910 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
911 &pol_hive, &pol_key);
912 if (!NT_STATUS_IS_OK(status)) {
913 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
918 filename.name = argv[1];
919 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
920 if ( !W_ERROR_IS_OK(result) ) {
921 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
922 cli->desthost, argv[1]);
927 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
928 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
933 /********************************************************************
934 ********************************************************************/
936 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
938 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
939 rpc_registry_save_internal, argc, argv );
943 /********************************************************************
944 ********************************************************************/
946 static void dump_values( REGF_NK_REC *nk )
949 const char *data_str = NULL;
950 uint32 data_size, data;
956 for ( i=0; i<nk->num_values; i++ ) {
957 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
958 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
960 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
961 switch ( nk->values[i].type ) {
963 blob = data_blob_const(nk->values[i].data, data_size);
964 pull_reg_sz(talloc_tos(), NULL, &blob, &data_str);
968 d_printf( "%s", data_str );
972 for ( j=0; j<data_size; j++ ) {
973 d_printf( "%c", nk->values[i].data[j] );
977 data = IVAL( nk->values[i].data, 0 );
978 d_printf("0x%x", data );
981 for ( j=0; j<data_size; j++ ) {
982 d_printf( "%x", nk->values[i].data[j] );
986 d_printf(_("unknown"));
995 /********************************************************************
996 ********************************************************************/
998 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1002 /* depth first dump of the registry tree */
1004 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1006 if (asprintf(®path, "%s\\%s", parent, key->keyname) < 0) {
1009 d_printf("[%s]\n", regpath );
1012 dump_registry_tree( file, key, regpath );
1019 /********************************************************************
1020 ********************************************************************/
1022 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1023 REGF_NK_REC *parent, REGF_FILE *outfile,
1024 const char *parentpath )
1026 REGF_NK_REC *key, *subkey;
1027 struct regval_ctr *values = NULL;
1028 struct regsubkey_ctr *subkeys = NULL;
1033 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1034 if (!W_ERROR_IS_OK(werr)) {
1035 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1036 "%s\n", win_errstr(werr)));
1040 if ( !(values = TALLOC_ZERO_P( subkeys, struct regval_ctr )) ) {
1041 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1042 TALLOC_FREE(subkeys);
1046 /* copy values into the struct regval_ctr */
1048 for ( i=0; i<nk->num_values; i++ ) {
1049 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1050 (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1053 /* copy subkeys into the struct regsubkey_ctr */
1055 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1056 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1059 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1061 /* write each one of the subkeys out */
1063 path = talloc_asprintf(subkeys,
1069 TALLOC_FREE(subkeys);
1073 nk->subkey_index = 0;
1074 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1075 write_registry_tree( infile, subkey, key, outfile, path );
1078 d_printf("[%s]\n", path );
1079 TALLOC_FREE(subkeys);
1084 /********************************************************************
1085 ********************************************************************/
1087 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1089 REGF_FILE *registry;
1092 if (argc != 1 || c->display_usage) {
1095 _("net rpc registry dump <file> \n"));
1099 d_printf(_("Opening %s...."), argv[0]);
1100 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1101 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1104 d_printf(_("ok\n"));
1106 /* get the root of the registry file */
1108 if ((nk = regfio_rootkey( registry )) == NULL) {
1109 d_fprintf(stderr, _("Could not get rootkey\n"));
1110 regfio_close( registry );
1113 d_printf("[%s]\n", nk->keyname);
1117 dump_registry_tree( registry, nk, nk->keyname );
1120 talloc_report_full( registry->mem_ctx, stderr );
1122 d_printf(_("Closing registry..."));
1123 regfio_close( registry );
1124 d_printf(_("ok\n"));
1129 /********************************************************************
1130 ********************************************************************/
1132 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1134 REGF_FILE *infile = NULL, *outfile = NULL;
1138 if (argc != 2 || c->display_usage) {
1141 _("net rpc registry copy <srcfile> <newfile>\n"));
1145 d_printf(_("Opening %s...."), argv[0]);
1146 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1147 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1150 d_printf(_("ok\n"));
1152 d_printf(_("Opening %s...."), argv[1]);
1153 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1154 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1157 d_printf(_("ok\n"));
1159 /* get the root of the registry file */
1161 if ((nk = regfio_rootkey( infile )) == NULL) {
1162 d_fprintf(stderr, _("Could not get rootkey\n"));
1165 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1167 write_registry_tree( infile, nk, NULL, outfile, "" );
1173 d_printf(_("Closing %s..."), argv[1]);
1175 regfio_close( outfile );
1177 d_printf(_("ok\n"));
1179 d_printf(_("Closing %s..."), argv[0]);
1181 regfio_close( infile );
1183 d_printf(_("ok\n"));
1188 /********************************************************************
1189 ********************************************************************/
1191 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1192 const DOM_SID *domain_sid,
1193 const char *domain_name,
1194 struct cli_state *cli,
1195 struct rpc_pipe_client *pipe_hnd,
1196 TALLOC_CTX *mem_ctx,
1200 struct policy_handle pol_hive, pol_key;
1202 enum ndr_err_code ndr_err;
1203 struct KeySecurityData *sd = NULL;
1206 struct security_descriptor sec_desc;
1207 uint32_t access_mask = REG_KEY_READ |
1208 SEC_FLAG_MAXIMUM_ALLOWED |
1209 SEC_FLAG_SYSTEM_SECURITY;
1211 if (argc <1 || argc > 2 || c->display_usage) {
1214 _("net rpc registry getsd <path> <secinfo>\n"));
1215 d_printf("%s net rpc registry getsd "
1216 "'HKLM\\Software\\Samba'\n", _("Example:"));
1217 return NT_STATUS_INVALID_PARAMETER;
1220 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1222 &pol_hive, &pol_key);
1223 if (!NT_STATUS_IS_OK(status)) {
1224 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1229 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1231 status = NT_STATUS_NO_MEMORY;
1238 sscanf(argv[1], "%x", &sec_info);
1240 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1243 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 d_fprintf(stderr, _("getting sd failed: %s\n"),
1250 blob.data = sd->data;
1251 blob.length = sd->size;
1253 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &sec_desc,
1254 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1255 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1256 status = ndr_map_error2ntstatus(ndr_err);
1259 status = NT_STATUS_OK;
1261 display_sec_desc(&sec_desc);
1264 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1265 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1271 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1273 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1274 rpc_registry_getsd_internal, argc, argv);
1277 /********************************************************************
1278 ********************************************************************/
1280 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1282 struct functable func[] = {
1285 rpc_registry_enumerate,
1287 N_("Enumerate registry keys and values"),
1288 N_("net rpc registry enumerate\n"
1289 " Enumerate registry keys and values")
1293 rpc_registry_createkey,
1295 N_("Create a new registry key"),
1296 N_("net rpc registry createkey\n"
1297 " Create a new registry key")
1301 rpc_registry_deletekey,
1303 N_("Delete a registry key"),
1304 N_("net rpc registry deletekey\n"
1305 " Delete a registry key")
1309 rpc_registry_getvalue,
1311 N_("Print a registry value"),
1312 N_("net rpc registry getvalue\n"
1313 " Print a registry value")
1317 rpc_registry_getvalueraw,
1319 N_("Print a registry value"),
1320 N_("net rpc registry getvalueraw\n"
1321 " Print a registry value (raw version)")
1325 rpc_registry_setvalue,
1327 N_("Set a new registry value"),
1328 N_("net rpc registry setvalue\n"
1329 " Set a new registry value")
1333 rpc_registry_deletevalue,
1335 N_("Delete a registry value"),
1336 N_("net rpc registry deletevalue\n"
1337 " Delete a registry value")
1343 N_("Save a registry file"),
1344 N_("net rpc registry save\n"
1345 " Save a registry file")
1351 N_("Dump a registry file"),
1352 N_("net rpc registry dump\n"
1353 " Dump a registry file")
1359 N_("Copy a registry file"),
1360 N_("net rpc registry copy\n"
1361 " Copy a registry file")
1367 N_("Get security descriptor"),
1368 N_("net rpc registry getsd\n"
1369 " Get security descriptior")
1371 {NULL, NULL, 0, NULL, NULL}
1374 return net_run_function(c, argc, argv, "net rpc registry", func);