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"
26 #include "registry/reg_util_marshalling.h"
28 /*******************************************************************
29 connect to a registry hive root (open a registry policy)
30 *******************************************************************/
32 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
33 uint32_t reg_type, uint32_t access_mask,
34 struct policy_handle *reg_hnd)
36 ZERO_STRUCTP(reg_hnd);
40 case HKEY_CLASSES_ROOT:
41 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
42 access_mask, reg_hnd, NULL);
44 case HKEY_LOCAL_MACHINE:
45 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
46 access_mask, reg_hnd, NULL);
49 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
50 access_mask, reg_hnd, NULL);
52 case HKEY_CURRENT_USER:
53 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
54 access_mask, reg_hnd, NULL);
56 case HKEY_PERFORMANCE_DATA:
57 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
58 access_mask, reg_hnd, NULL);
61 /* fall through to end of function */
65 return NT_STATUS_INVALID_PARAMETER;
68 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
69 uint32 *reg_type, const char **key_name)
72 char *hivename = NULL;
73 char *tmp_keyname = NULL;
75 TALLOC_CTX *tmp_ctx = talloc_stackframe();
77 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
78 if (!W_ERROR_IS_OK(werr)) {
82 *key_name = talloc_strdup(ctx, tmp_keyname);
83 if (*key_name == NULL) {
87 if (strequal(hivename, "HKLM") ||
88 strequal(hivename, "HKEY_LOCAL_MACHINE"))
90 (*reg_type) = HKEY_LOCAL_MACHINE;
91 } else if (strequal(hivename, "HKCR") ||
92 strequal(hivename, "HKEY_CLASSES_ROOT"))
94 (*reg_type) = HKEY_CLASSES_ROOT;
95 } else if (strequal(hivename, "HKU") ||
96 strequal(hivename, "HKEY_USERS"))
98 (*reg_type) = HKEY_USERS;
99 } else if (strequal(hivename, "HKCU") ||
100 strequal(hivename, "HKEY_CURRENT_USER"))
102 (*reg_type) = HKEY_CURRENT_USER;
103 } else if (strequal(hivename, "HKPD") ||
104 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
106 (*reg_type) = HKEY_PERFORMANCE_DATA;
108 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
116 TALLOC_FREE(tmp_ctx);
120 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
121 struct rpc_pipe_client *pipe_hnd,
122 const char *name, uint32 access_mask,
123 struct policy_handle *hive_hnd,
124 struct policy_handle *key_hnd)
128 struct winreg_String key;
132 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
133 return NT_STATUS_INVALID_PARAMETER;
136 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
138 if (!(NT_STATUS_IS_OK(status))) {
142 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
143 access_mask, key_hnd, NULL);
144 if (!(NT_STATUS_IS_OK(status))) {
145 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
152 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
153 struct rpc_pipe_client *pipe_hnd,
154 struct policy_handle *key_hnd,
155 uint32 *pnum_keys, char ***pnames,
156 char ***pclasses, NTTIME ***pmodtimes)
160 uint32 num_subkeys, max_subkeylen, max_classlen;
161 uint32 num_values, max_valnamelen, max_valbufsize;
163 NTTIME last_changed_time;
165 struct winreg_String classname;
166 char **names, **classes;
169 if (!(mem_ctx = talloc_new(ctx))) {
170 return NT_STATUS_NO_MEMORY;
173 ZERO_STRUCT(classname);
174 status = rpccli_winreg_QueryInfoKey(
175 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
176 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
177 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
179 if (!NT_STATUS_IS_OK(status)) {
183 if (num_subkeys == 0) {
185 TALLOC_FREE(mem_ctx);
189 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
190 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
191 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
193 status = NT_STATUS_NO_MEMORY;
197 for (i=0; i<num_subkeys; i++) {
199 struct winreg_StringBuf class_buf;
200 struct winreg_StringBuf name_buf;
206 class_buf.size = max_classlen+2;
210 name_buf.size = max_subkeylen+2;
212 ZERO_STRUCT(modtime);
214 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
215 i, &name_buf, &class_buf,
218 if (W_ERROR_EQUAL(werr,
219 WERR_NO_MORE_ITEMS) ) {
220 status = NT_STATUS_OK;
223 if (!NT_STATUS_IS_OK(status)) {
229 if (class_buf.name &&
230 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
231 status = NT_STATUS_NO_MEMORY;
235 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
236 status = NT_STATUS_NO_MEMORY;
240 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
241 modtimes, &modtime, sizeof(modtime))))) {
242 status = NT_STATUS_NO_MEMORY;
247 *pnum_keys = num_subkeys;
250 *pnames = talloc_move(ctx, &names);
253 *pclasses = talloc_move(ctx, &classes);
256 *pmodtimes = talloc_move(ctx, &modtimes);
259 status = NT_STATUS_OK;
262 TALLOC_FREE(mem_ctx);
266 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
267 struct rpc_pipe_client *pipe_hnd,
268 struct policy_handle *key_hnd,
269 uint32 *pnum_values, char ***pvalnames,
270 struct registry_value ***pvalues)
274 uint32 num_subkeys, max_subkeylen, max_classlen;
275 uint32 num_values, max_valnamelen, max_valbufsize;
277 NTTIME last_changed_time;
279 struct winreg_String classname;
280 struct registry_value **values;
283 if (!(mem_ctx = talloc_new(ctx))) {
284 return NT_STATUS_NO_MEMORY;
287 ZERO_STRUCT(classname);
288 status = rpccli_winreg_QueryInfoKey(
289 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
290 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
291 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
293 if (!NT_STATUS_IS_OK(status)) {
297 if (num_values == 0) {
299 TALLOC_FREE(mem_ctx);
303 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
304 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
306 status = NT_STATUS_NO_MEMORY;
310 for (i=0; i<num_values; i++) {
311 enum winreg_Type type = REG_NONE;
317 struct winreg_ValNameBuf name_buf;
322 name_buf.size = max_valnamelen + 2;
324 data_size = max_valbufsize;
325 data = (uint8 *)TALLOC(mem_ctx, data_size);
328 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
331 &value_length, &err);
333 if ( W_ERROR_EQUAL(err,
334 WERR_NO_MORE_ITEMS) ) {
335 status = NT_STATUS_OK;
339 if (!(NT_STATUS_IS_OK(status))) {
343 if (name_buf.name == NULL) {
344 status = NT_STATUS_INVALID_PARAMETER;
348 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
349 status = NT_STATUS_NO_MEMORY;
353 err = registry_pull_value(values, &values[i], type, data,
354 data_size, value_length);
355 if (!W_ERROR_IS_OK(err)) {
356 status = werror_to_ntstatus(err);
361 *pnum_values = num_values;
364 *pvalnames = talloc_move(ctx, &names);
367 *pvalues = talloc_move(ctx, &values);
370 status = NT_STATUS_OK;
373 TALLOC_FREE(mem_ctx);
377 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
378 struct rpc_pipe_client *pipe_hnd,
379 struct policy_handle *key_hnd,
381 struct KeySecurityData *sd)
383 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
388 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
389 struct rpc_pipe_client *pipe_hnd,
390 struct policy_handle *key_hnd,
392 const struct registry_value *value)
394 struct winreg_String name_string;
399 err = registry_push_value(mem_ctx, value, &blob);
400 if (!W_ERROR_IS_OK(err)) {
401 return werror_to_ntstatus(err);
404 ZERO_STRUCT(name_string);
406 name_string.name = name;
407 result = rpccli_winreg_SetValue(pipe_hnd, blob.data, key_hnd,
408 name_string, value->type,
409 blob.data, blob.length, NULL);
410 TALLOC_FREE(blob.data);
414 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
415 const struct dom_sid *domain_sid,
416 const char *domain_name,
417 struct cli_state *cli,
418 struct rpc_pipe_client *pipe_hnd,
423 struct policy_handle hive_hnd, key_hnd;
425 struct registry_value value;
427 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
428 SEC_FLAG_MAXIMUM_ALLOWED,
429 &hive_hnd, &key_hnd);
430 if (!NT_STATUS_IS_OK(status)) {
431 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
436 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
437 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
438 return NT_STATUS_NOT_IMPLEMENTED;
441 if (strequal(argv[2], "dword")) {
442 value.type = REG_DWORD;
443 value.v.dword = strtoul(argv[3], NULL, 10);
445 else if (strequal(argv[2], "sz")) {
447 value.v.sz.len = strlen(argv[3])+1;
448 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
451 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
452 status = NT_STATUS_NOT_IMPLEMENTED;
456 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
459 if (!NT_STATUS_IS_OK(status)) {
460 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
465 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
466 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
471 static int rpc_registry_setvalue(struct net_context *c, int argc,
474 if (argc < 4 || c->display_usage) {
475 d_fprintf(stderr, "%s\n%s",
477 _("net rpc registry setvalue <key> <valuename> "
478 "<type> [<val>]+\n"));
482 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
483 rpc_registry_setvalue_internal, argc, argv );
486 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
487 const struct dom_sid *domain_sid,
488 const char *domain_name,
489 struct cli_state *cli,
490 struct rpc_pipe_client *pipe_hnd,
495 struct policy_handle hive_hnd, key_hnd;
497 struct winreg_String valuename;
499 ZERO_STRUCT(valuename);
501 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
502 SEC_FLAG_MAXIMUM_ALLOWED,
503 &hive_hnd, &key_hnd);
504 if (!NT_STATUS_IS_OK(status)) {
505 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
510 valuename.name = argv[1];
512 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
515 if (!NT_STATUS_IS_OK(status)) {
516 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
521 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
526 static int rpc_registry_deletevalue(struct net_context *c, int argc,
529 if (argc != 2 || c->display_usage) {
530 d_fprintf(stderr, "%s\n%s",
532 _("net rpc registry deletevalue <key> <valuename>\n"));
536 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
537 rpc_registry_deletevalue_internal, argc, argv );
540 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
541 const struct dom_sid *domain_sid,
542 const char *domain_name,
543 struct cli_state *cli,
544 struct rpc_pipe_client *pipe_hnd,
550 struct policy_handle hive_hnd, key_hnd;
553 struct winreg_String valuename;
554 struct registry_value *value = NULL;
555 enum winreg_Type type = REG_NONE;
556 uint8_t *data = NULL;
557 uint32_t data_size = 0;
558 uint32_t value_length = 0;
559 TALLOC_CTX *tmp_ctx = talloc_stackframe();
561 ZERO_STRUCT(valuename);
563 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
564 SEC_FLAG_MAXIMUM_ALLOWED,
565 &hive_hnd, &key_hnd);
566 if (!NT_STATUS_IS_OK(status)) {
567 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
572 valuename.name = argv[1];
575 * call QueryValue once with data == NULL to get the
576 * needed memory size to be allocated, then allocate
577 * data buffer and call again.
579 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
587 if (!NT_STATUS_IS_OK(status)) {
588 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
593 data = (uint8 *)TALLOC(tmp_ctx, data_size);
596 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
604 if (!NT_STATUS_IS_OK(status)) {
605 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
610 werr = registry_pull_value(tmp_ctx, &value, type, data,
611 data_size, value_length);
612 if (!W_ERROR_IS_OK(werr)) {
613 status = werror_to_ntstatus(werr);
617 print_registry_value(value, raw);
620 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
621 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
623 TALLOC_FREE(tmp_ctx);
628 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
629 const struct dom_sid *domain_sid,
630 const char *domain_name,
631 struct cli_state *cli,
632 struct rpc_pipe_client *pipe_hnd,
637 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
638 cli, pipe_hnd, mem_ctx, false,
642 static int rpc_registry_getvalue(struct net_context *c, int argc,
645 if (argc != 2 || c->display_usage) {
646 d_fprintf(stderr, "%s\n%s",
648 _("net rpc registry getvalue <key> <valuename>\n"));
652 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
653 rpc_registry_getvalue_full, argc, argv);
656 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
657 const struct dom_sid *domain_sid,
658 const char *domain_name,
659 struct cli_state *cli,
660 struct rpc_pipe_client *pipe_hnd,
665 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
666 cli, pipe_hnd, mem_ctx, true,
670 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
673 if (argc != 2 || c->display_usage) {
674 d_fprintf(stderr, "%s\n%s",
676 _("net rpc registry getvalue <key> <valuename>\n"));
680 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
681 rpc_registry_getvalue_raw, argc, argv);
684 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
685 const struct dom_sid *domain_sid,
686 const char *domain_name,
687 struct cli_state *cli,
688 struct rpc_pipe_client *pipe_hnd,
694 struct policy_handle hive_hnd, key_hnd;
695 struct winreg_String key, keyclass;
696 enum winreg_CreateAction action;
700 ZERO_STRUCT(keyclass);
702 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
703 return NT_STATUS_INVALID_PARAMETER;
706 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
707 SEC_FLAG_MAXIMUM_ALLOWED,
709 if (!(NT_STATUS_IS_OK(status))) {
713 action = REG_ACTION_NONE;
716 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
717 keyclass, 0, REG_KEY_READ, NULL,
718 &key_hnd, &action, NULL);
719 if (!NT_STATUS_IS_OK(status)) {
720 d_fprintf(stderr, _("createkey returned %s\n"),
722 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
727 case REG_ACTION_NONE:
728 d_printf(_("createkey did nothing -- huh?\n"));
730 case REG_CREATED_NEW_KEY:
731 d_printf(_("createkey created %s\n"), argv[0]);
733 case REG_OPENED_EXISTING_KEY:
734 d_printf(_("createkey opened existing %s\n"), argv[0]);
738 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
739 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
744 static int rpc_registry_createkey(struct net_context *c, int argc,
747 if (argc != 1 || c->display_usage) {
748 d_fprintf(stderr, "%s\n%s",
750 _("net rpc registry createkey <key>\n"));
754 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
755 rpc_registry_createkey_internal, argc, argv );
758 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
759 const struct dom_sid *domain_sid,
760 const char *domain_name,
761 struct cli_state *cli,
762 struct rpc_pipe_client *pipe_hnd,
768 struct policy_handle hive_hnd;
769 struct winreg_String key;
774 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
775 return NT_STATUS_INVALID_PARAMETER;
778 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
779 SEC_FLAG_MAXIMUM_ALLOWED,
781 if (!(NT_STATUS_IS_OK(status))) {
785 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
786 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
788 if (!NT_STATUS_IS_OK(status)) {
789 d_fprintf(stderr, _("deletekey returned %s\n"),
796 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
798 if (argc != 1 || c->display_usage) {
799 d_fprintf(stderr, "%s\n%s",
801 _("net rpc registry deletekey <key>\n"));
805 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
806 rpc_registry_deletekey_internal, argc, argv );
809 /********************************************************************
810 ********************************************************************/
812 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
813 const struct dom_sid *domain_sid,
814 const char *domain_name,
815 struct cli_state *cli,
816 struct rpc_pipe_client *pipe_hnd,
821 struct policy_handle pol_hive, pol_key;
823 uint32 num_subkeys = 0;
824 uint32 num_values = 0;
825 char **names = NULL, **classes = NULL;
826 NTTIME **modtimes = NULL;
828 struct registry_value **values = NULL;
830 if (argc != 1 || c->display_usage) {
833 _("net rpc registry enumerate <path>\n"));
834 d_printf("%s net rpc registry enumerate "
835 "'HKLM\\Software\\Samba'\n", _("Example:"));
836 return NT_STATUS_INVALID_PARAMETER;
839 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
840 &pol_hive, &pol_key);
841 if (!NT_STATUS_IS_OK(status)) {
842 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
847 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
848 &names, &classes, &modtimes);
849 if (!NT_STATUS_IS_OK(status)) {
850 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
855 for (i=0; i<num_subkeys; i++) {
856 print_registry_key(names[i], modtimes[i]);
859 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
861 if (!NT_STATUS_IS_OK(status)) {
862 d_fprintf(stderr, _("enumerating values failed: %s\n"),
867 for (i=0; i<num_values; i++) {
868 print_registry_value_with_name(names[i], values[i]);
871 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
872 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
877 /********************************************************************
878 ********************************************************************/
880 static int rpc_registry_enumerate(struct net_context *c, int argc,
883 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
884 rpc_registry_enumerate_internal, argc, argv );
887 /********************************************************************
888 ********************************************************************/
890 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
891 const struct dom_sid *domain_sid,
892 const char *domain_name,
893 struct cli_state *cli,
894 struct rpc_pipe_client *pipe_hnd,
899 WERROR result = WERR_GENERAL_FAILURE;
900 struct policy_handle pol_hive, pol_key;
901 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
902 struct winreg_String filename;
904 if (argc != 2 || c->display_usage) {
907 _("net rpc registry backup <path> <file> \n"));
908 return NT_STATUS_INVALID_PARAMETER;
911 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
912 &pol_hive, &pol_key);
913 if (!NT_STATUS_IS_OK(status)) {
914 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
919 filename.name = argv[1];
920 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
921 if ( !W_ERROR_IS_OK(result) ) {
922 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
923 cli->desthost, argv[1]);
928 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
929 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
934 /********************************************************************
935 ********************************************************************/
937 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
939 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
940 rpc_registry_save_internal, argc, argv );
944 /********************************************************************
945 ********************************************************************/
947 static void dump_values( REGF_NK_REC *nk )
950 const char *data_str = NULL;
951 uint32 data_size, data;
957 for ( i=0; i<nk->num_values; i++ ) {
958 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
959 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
961 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
962 switch ( nk->values[i].type ) {
964 blob = data_blob_const(nk->values[i].data, data_size);
965 pull_reg_sz(talloc_tos(), &blob, &data_str);
969 d_printf( "%s", data_str );
973 for ( j=0; j<data_size; j++ ) {
974 d_printf( "%c", nk->values[i].data[j] );
978 data = IVAL( nk->values[i].data, 0 );
979 d_printf("0x%x", data );
982 for ( j=0; j<data_size; j++ ) {
983 d_printf( "%x", nk->values[i].data[j] );
987 d_printf(_("unknown"));
996 /********************************************************************
997 ********************************************************************/
999 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1003 /* depth first dump of the registry tree */
1005 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1007 if (asprintf(®path, "%s\\%s", parent, key->keyname) < 0) {
1010 d_printf("[%s]\n", regpath );
1013 dump_registry_tree( file, key, regpath );
1020 /********************************************************************
1021 ********************************************************************/
1023 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1024 REGF_NK_REC *parent, REGF_FILE *outfile,
1025 const char *parentpath )
1027 REGF_NK_REC *key, *subkey;
1028 struct regval_ctr *values = NULL;
1029 struct regsubkey_ctr *subkeys = NULL;
1034 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1035 if (!W_ERROR_IS_OK(werr)) {
1036 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1037 "%s\n", win_errstr(werr)));
1041 werr = regval_ctr_init(subkeys, &values);
1042 if (!W_ERROR_IS_OK(werr)) {
1043 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1044 TALLOC_FREE(subkeys);
1048 /* copy values into the struct regval_ctr */
1050 for ( i=0; i<nk->num_values; i++ ) {
1051 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1052 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1055 /* copy subkeys into the struct regsubkey_ctr */
1057 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1058 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1061 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1063 /* write each one of the subkeys out */
1065 path = talloc_asprintf(subkeys,
1071 TALLOC_FREE(subkeys);
1075 nk->subkey_index = 0;
1076 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1077 write_registry_tree( infile, subkey, key, outfile, path );
1080 d_printf("[%s]\n", path );
1081 TALLOC_FREE(subkeys);
1086 /********************************************************************
1087 ********************************************************************/
1089 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1091 REGF_FILE *registry;
1094 if (argc != 1 || c->display_usage) {
1097 _("net rpc registry dump <file> \n"));
1101 d_printf(_("Opening %s...."), argv[0]);
1102 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1103 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1106 d_printf(_("ok\n"));
1108 /* get the root of the registry file */
1110 if ((nk = regfio_rootkey( registry )) == NULL) {
1111 d_fprintf(stderr, _("Could not get rootkey\n"));
1112 regfio_close( registry );
1115 d_printf("[%s]\n", nk->keyname);
1119 dump_registry_tree( registry, nk, nk->keyname );
1122 talloc_report_full( registry->mem_ctx, stderr );
1124 d_printf(_("Closing registry..."));
1125 regfio_close( registry );
1126 d_printf(_("ok\n"));
1131 /********************************************************************
1132 ********************************************************************/
1134 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1136 REGF_FILE *infile = NULL, *outfile = NULL;
1140 if (argc != 2 || c->display_usage) {
1143 _("net rpc registry copy <srcfile> <newfile>\n"));
1147 d_printf(_("Opening %s...."), argv[0]);
1148 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1149 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1152 d_printf(_("ok\n"));
1154 d_printf(_("Opening %s...."), argv[1]);
1155 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1156 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1159 d_printf(_("ok\n"));
1161 /* get the root of the registry file */
1163 if ((nk = regfio_rootkey( infile )) == NULL) {
1164 d_fprintf(stderr, _("Could not get rootkey\n"));
1167 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1169 write_registry_tree( infile, nk, NULL, outfile, "" );
1175 d_printf(_("Closing %s..."), argv[1]);
1177 regfio_close( outfile );
1179 d_printf(_("ok\n"));
1181 d_printf(_("Closing %s..."), argv[0]);
1183 regfio_close( infile );
1185 d_printf(_("ok\n"));
1190 /********************************************************************
1191 ********************************************************************/
1193 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1194 const struct dom_sid *domain_sid,
1195 const char *domain_name,
1196 struct cli_state *cli,
1197 struct rpc_pipe_client *pipe_hnd,
1198 TALLOC_CTX *mem_ctx,
1202 struct policy_handle pol_hive, pol_key;
1204 enum ndr_err_code ndr_err;
1205 struct KeySecurityData *sd = NULL;
1208 struct security_descriptor sec_desc;
1209 uint32_t access_mask = REG_KEY_READ |
1210 SEC_FLAG_MAXIMUM_ALLOWED |
1211 SEC_FLAG_SYSTEM_SECURITY;
1213 if (argc <1 || argc > 2 || c->display_usage) {
1216 _("net rpc registry getsd <path> <secinfo>\n"));
1217 d_printf("%s net rpc registry getsd "
1218 "'HKLM\\Software\\Samba'\n", _("Example:"));
1219 return NT_STATUS_INVALID_PARAMETER;
1222 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1224 &pol_hive, &pol_key);
1225 if (!NT_STATUS_IS_OK(status)) {
1226 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1231 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1233 status = NT_STATUS_NO_MEMORY;
1240 sscanf(argv[1], "%x", &sec_info);
1242 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1245 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 d_fprintf(stderr, _("getting sd failed: %s\n"),
1252 blob.data = sd->data;
1253 blob.length = sd->size;
1255 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1256 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1257 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1258 status = ndr_map_error2ntstatus(ndr_err);
1261 status = NT_STATUS_OK;
1263 display_sec_desc(&sec_desc);
1266 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1267 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1273 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1275 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1276 rpc_registry_getsd_internal, argc, argv);
1279 /********************************************************************
1280 ********************************************************************/
1282 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1284 struct functable func[] = {
1287 rpc_registry_enumerate,
1289 N_("Enumerate registry keys and values"),
1290 N_("net rpc registry enumerate\n"
1291 " Enumerate registry keys and values")
1295 rpc_registry_createkey,
1297 N_("Create a new registry key"),
1298 N_("net rpc registry createkey\n"
1299 " Create a new registry key")
1303 rpc_registry_deletekey,
1305 N_("Delete a registry key"),
1306 N_("net rpc registry deletekey\n"
1307 " Delete a registry key")
1311 rpc_registry_getvalue,
1313 N_("Print a registry value"),
1314 N_("net rpc registry getvalue\n"
1315 " Print a registry value")
1319 rpc_registry_getvalueraw,
1321 N_("Print a registry value"),
1322 N_("net rpc registry getvalueraw\n"
1323 " Print a registry value (raw version)")
1327 rpc_registry_setvalue,
1329 N_("Set a new registry value"),
1330 N_("net rpc registry setvalue\n"
1331 " Set a new registry value")
1335 rpc_registry_deletevalue,
1337 N_("Delete a registry value"),
1338 N_("net rpc registry deletevalue\n"
1339 " Delete a registry value")
1345 N_("Save a registry file"),
1346 N_("net rpc registry save\n"
1347 " Save a registry file")
1353 N_("Dump a registry file"),
1354 N_("net rpc registry dump\n"
1355 " Dump a registry file")
1361 N_("Copy a registry file"),
1362 N_("net rpc registry copy\n"
1363 " Copy a registry file")
1369 N_("Get security descriptor"),
1370 N_("net rpc registry getsd\n"
1371 " Get security descriptior")
1373 {NULL, NULL, 0, NULL, NULL}
1376 return net_run_function(c, argc, argv, "net rpc registry", func);