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 "popt_common.h"
23 #include "utils/net.h"
24 #include "utils/net_registry_util.h"
25 #include "registry/regfio.h"
26 #include "../librpc/gen_ndr/cli_winreg.h"
27 #include "registry/reg_objects.h"
28 #include "../librpc/gen_ndr/ndr_security.h"
29 #include "registry/reg_format.h"
33 /*******************************************************************
34 connect to a registry hive root (open a registry policy)
35 *******************************************************************/
37 static NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
38 uint32_t reg_type, uint32_t access_mask,
39 struct policy_handle *reg_hnd, WERROR *werr)
41 ZERO_STRUCTP(reg_hnd);
45 case HKEY_CLASSES_ROOT:
46 return rpccli_winreg_OpenHKCR( cli, mem_ctx, NULL,
47 access_mask, reg_hnd, werr);
49 case HKEY_LOCAL_MACHINE:
50 return rpccli_winreg_OpenHKLM( cli, mem_ctx, NULL,
51 access_mask, reg_hnd, werr);
54 return rpccli_winreg_OpenHKU( cli, mem_ctx, NULL,
55 access_mask, reg_hnd, werr);
57 case HKEY_CURRENT_USER:
58 return rpccli_winreg_OpenHKCU( cli, mem_ctx, NULL,
59 access_mask, reg_hnd, werr);
61 case HKEY_PERFORMANCE_DATA:
62 return rpccli_winreg_OpenHKPD( cli, mem_ctx, NULL,
63 access_mask, reg_hnd, werr);
66 /* fall through to end of function */
70 return NT_STATUS_INVALID_PARAMETER;
73 static bool reg_hive_key(TALLOC_CTX *ctx, const char *fullname,
74 uint32 *reg_type, const char **key_name)
77 char *hivename = NULL;
78 char *tmp_keyname = NULL;
80 TALLOC_CTX *tmp_ctx = talloc_stackframe();
82 werr = split_hive_key(tmp_ctx, fullname, &hivename, &tmp_keyname);
83 if (!W_ERROR_IS_OK(werr)) {
87 *key_name = talloc_strdup(ctx, tmp_keyname);
88 if (*key_name == NULL) {
92 if (strequal(hivename, "HKLM") ||
93 strequal(hivename, "HKEY_LOCAL_MACHINE"))
95 (*reg_type) = HKEY_LOCAL_MACHINE;
96 } else if (strequal(hivename, "HKCR") ||
97 strequal(hivename, "HKEY_CLASSES_ROOT"))
99 (*reg_type) = HKEY_CLASSES_ROOT;
100 } else if (strequal(hivename, "HKU") ||
101 strequal(hivename, "HKEY_USERS"))
103 (*reg_type) = HKEY_USERS;
104 } else if (strequal(hivename, "HKCU") ||
105 strequal(hivename, "HKEY_CURRENT_USER"))
107 (*reg_type) = HKEY_CURRENT_USER;
108 } else if (strequal(hivename, "HKPD") ||
109 strequal(hivename, "HKEY_PERFORMANCE_DATA"))
111 (*reg_type) = HKEY_PERFORMANCE_DATA;
113 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
121 TALLOC_FREE(tmp_ctx);
125 static NTSTATUS registry_openkey(TALLOC_CTX *mem_ctx,
126 struct rpc_pipe_client *pipe_hnd,
127 const char *name, uint32 access_mask,
128 struct policy_handle *hive_hnd,
129 struct policy_handle *key_hnd)
133 struct winreg_String key;
137 if (!reg_hive_key(mem_ctx, name, &hive, &key.name)) {
138 return NT_STATUS_INVALID_PARAMETER;
141 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive, access_mask,
143 if (!(NT_STATUS_IS_OK(status))) {
147 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, hive_hnd, key, 0,
148 access_mask, key_hnd, NULL);
149 if (!(NT_STATUS_IS_OK(status))) {
150 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, hive_hnd, NULL);
157 static NTSTATUS registry_enumkeys(TALLOC_CTX *ctx,
158 struct rpc_pipe_client *pipe_hnd,
159 struct policy_handle *key_hnd,
160 uint32 *pnum_keys, char ***pnames,
161 char ***pclasses, NTTIME ***pmodtimes)
165 uint32 num_subkeys, max_subkeylen, max_classlen;
166 uint32 num_values, max_valnamelen, max_valbufsize;
168 NTTIME last_changed_time;
170 struct winreg_String classname;
171 char **names, **classes;
174 if (!(mem_ctx = talloc_new(ctx))) {
175 return NT_STATUS_NO_MEMORY;
178 ZERO_STRUCT(classname);
179 status = rpccli_winreg_QueryInfoKey(
180 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
181 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
182 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
184 if (!NT_STATUS_IS_OK(status)) {
188 if (num_subkeys == 0) {
190 TALLOC_FREE(mem_ctx);
194 if ((!(names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
195 (!(classes = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_subkeys))) ||
196 (!(modtimes = TALLOC_ZERO_ARRAY(mem_ctx, NTTIME *,
198 status = NT_STATUS_NO_MEMORY;
202 for (i=0; i<num_subkeys; i++) {
204 struct winreg_StringBuf class_buf;
205 struct winreg_StringBuf name_buf;
211 class_buf.size = max_classlen+2;
215 name_buf.size = max_subkeylen+2;
217 ZERO_STRUCT(modtime);
219 status = rpccli_winreg_EnumKey(pipe_hnd, mem_ctx, key_hnd,
220 i, &name_buf, &class_buf,
223 if (W_ERROR_EQUAL(werr,
224 WERR_NO_MORE_ITEMS) ) {
225 status = NT_STATUS_OK;
228 if (!NT_STATUS_IS_OK(status)) {
234 if (class_buf.name &&
235 (!(classes[i] = talloc_strdup(classes, class_buf.name)))) {
236 status = NT_STATUS_NO_MEMORY;
240 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
241 status = NT_STATUS_NO_MEMORY;
245 if ((!(modtimes[i] = (NTTIME *)talloc_memdup(
246 modtimes, &modtime, sizeof(modtime))))) {
247 status = NT_STATUS_NO_MEMORY;
252 *pnum_keys = num_subkeys;
255 *pnames = talloc_move(ctx, &names);
258 *pclasses = talloc_move(ctx, &classes);
261 *pmodtimes = talloc_move(ctx, &modtimes);
264 status = NT_STATUS_OK;
267 TALLOC_FREE(mem_ctx);
271 static NTSTATUS registry_enumvalues(TALLOC_CTX *ctx,
272 struct rpc_pipe_client *pipe_hnd,
273 struct policy_handle *key_hnd,
274 uint32 *pnum_values, char ***pvalnames,
275 struct registry_value ***pvalues)
279 uint32 num_subkeys, max_subkeylen, max_classlen;
280 uint32 num_values, max_valnamelen, max_valbufsize;
282 NTTIME last_changed_time;
284 struct winreg_String classname;
285 struct registry_value **values;
288 if (!(mem_ctx = talloc_new(ctx))) {
289 return NT_STATUS_NO_MEMORY;
292 ZERO_STRUCT(classname);
293 status = rpccli_winreg_QueryInfoKey(
294 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
295 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
296 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
298 if (!NT_STATUS_IS_OK(status)) {
302 if (num_values == 0) {
304 TALLOC_FREE(mem_ctx);
308 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
309 (!(values = TALLOC_ARRAY(mem_ctx, struct registry_value *,
311 status = NT_STATUS_NO_MEMORY;
315 for (i=0; i<num_values; i++) {
316 enum winreg_Type type = REG_NONE;
322 struct winreg_ValNameBuf name_buf;
327 name_buf.size = max_valnamelen + 2;
329 data_size = max_valbufsize;
330 data = (uint8 *)TALLOC(mem_ctx, data_size);
333 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
336 &value_length, &err);
338 if ( W_ERROR_EQUAL(err,
339 WERR_NO_MORE_ITEMS) ) {
340 status = NT_STATUS_OK;
344 if (!(NT_STATUS_IS_OK(status))) {
348 if (name_buf.name == NULL) {
349 status = NT_STATUS_INVALID_PARAMETER;
353 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
354 status = NT_STATUS_NO_MEMORY;
358 values[i] = talloc_zero(values, struct registry_value);
359 if (values[i] == NULL) {
360 status = NT_STATUS_NO_MEMORY;
364 values[i]->type = type;
365 values[i]->data = data_blob_talloc(values[i], data, data_size);
368 *pnum_values = num_values;
371 *pvalnames = talloc_move(ctx, &names);
374 *pvalues = talloc_move(ctx, &values);
377 status = NT_STATUS_OK;
380 TALLOC_FREE(mem_ctx);
384 static NTSTATUS registry_enumvalues2(TALLOC_CTX *ctx,
385 struct rpc_pipe_client *pipe_hnd,
386 struct policy_handle *key_hnd,
387 uint32 *pnum_values, char ***pvalnames,
388 struct regval_blob ***pvalues)
392 uint32 num_subkeys, max_subkeylen, max_classlen;
393 uint32 num_values, max_valnamelen, max_valbufsize;
395 NTTIME last_changed_time;
397 struct winreg_String classname;
398 struct regval_blob **values;
401 if (!(mem_ctx = talloc_new(ctx))) {
402 return NT_STATUS_NO_MEMORY;
405 ZERO_STRUCT(classname);
406 status = rpccli_winreg_QueryInfoKey(
407 pipe_hnd, mem_ctx, key_hnd, &classname, &num_subkeys,
408 &max_subkeylen, &max_classlen, &num_values, &max_valnamelen,
409 &max_valbufsize, &secdescsize, &last_changed_time, NULL );
411 if (!NT_STATUS_IS_OK(status)) {
415 if (num_values == 0) {
417 TALLOC_FREE(mem_ctx);
421 if ((!(names = TALLOC_ARRAY(mem_ctx, char *, num_values))) ||
422 (!(values = TALLOC_ARRAY(mem_ctx, struct regval_blob *,
424 status = NT_STATUS_NO_MEMORY;
428 for (i=0; i<num_values; i++) {
429 enum winreg_Type type = REG_NONE;
435 struct winreg_ValNameBuf name_buf;
440 name_buf.size = max_valnamelen + 2;
442 data_size = max_valbufsize;
443 data = (uint8 *)TALLOC(mem_ctx, data_size);
446 status = rpccli_winreg_EnumValue(pipe_hnd, mem_ctx, key_hnd,
449 &value_length, &err);
451 if ( W_ERROR_EQUAL(err, WERR_NO_MORE_ITEMS) ) {
452 status = NT_STATUS_OK;
456 if (!(NT_STATUS_IS_OK(status))) {
460 if (name_buf.name == NULL) {
461 status = NT_STATUS_INVALID_PARAMETER;
465 if (!(names[i] = talloc_strdup(names, name_buf.name))) {
466 status = NT_STATUS_NO_MEMORY;
470 assert(value_length<=data_size); //???
472 values[i] = regval_compose(values,
477 status = NT_STATUS_NO_MEMORY;
482 *pnum_values = num_values;
485 *pvalnames = talloc_move(ctx, &names);
488 *pvalues = talloc_move(ctx, &values);
491 status = NT_STATUS_OK;
494 TALLOC_FREE(mem_ctx);
498 static NTSTATUS registry_getsd(TALLOC_CTX *mem_ctx,
499 struct rpc_pipe_client *pipe_hnd,
500 struct policy_handle *key_hnd,
502 struct KeySecurityData *sd)
504 return rpccli_winreg_GetKeySecurity(pipe_hnd, mem_ctx, key_hnd,
509 static NTSTATUS registry_setvalue(TALLOC_CTX *mem_ctx,
510 struct rpc_pipe_client *pipe_hnd,
511 struct policy_handle *key_hnd,
513 const struct registry_value *value)
515 struct winreg_String name_string;
518 ZERO_STRUCT(name_string);
520 name_string.name = name;
521 result = rpccli_winreg_SetValue(pipe_hnd, mem_ctx, key_hnd,
522 name_string, value->type,
523 value->data.data, value->data.length, NULL);
527 static NTSTATUS rpc_registry_setvalue_internal(struct net_context *c,
528 const struct dom_sid *domain_sid,
529 const char *domain_name,
530 struct cli_state *cli,
531 struct rpc_pipe_client *pipe_hnd,
536 struct policy_handle hive_hnd, key_hnd;
538 struct registry_value value;
540 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
541 SEC_FLAG_MAXIMUM_ALLOWED,
542 &hive_hnd, &key_hnd);
543 if (!NT_STATUS_IS_OK(status)) {
544 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
549 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
550 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
551 return NT_STATUS_NOT_IMPLEMENTED;
554 if (strequal(argv[2], "dword")) {
555 uint32_t v = strtoul(argv[3], NULL, 10);
556 value.type = REG_DWORD;
557 value.data = data_blob_talloc(mem_ctx, NULL, 4);
558 SIVAL(value.data.data, 0, v);
560 else if (strequal(argv[2], "sz")) {
562 if (!push_reg_sz(mem_ctx, &value.data, argv[3])) {
563 status = NT_STATUS_NO_MEMORY;
568 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
569 status = NT_STATUS_NOT_IMPLEMENTED;
573 status = registry_setvalue(mem_ctx, pipe_hnd, &key_hnd,
576 if (!NT_STATUS_IS_OK(status)) {
577 d_fprintf(stderr, _("registry_setvalue failed: %s\n"),
582 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
583 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
588 static int rpc_registry_setvalue(struct net_context *c, int argc,
591 if (argc < 4 || c->display_usage) {
592 d_fprintf(stderr, "%s\n%s",
594 _("net rpc registry setvalue <key> <valuename> "
595 "<type> [<val>]+\n"));
599 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
600 rpc_registry_setvalue_internal, argc, argv );
603 static NTSTATUS rpc_registry_deletevalue_internal(struct net_context *c,
604 const struct dom_sid *domain_sid,
605 const char *domain_name,
606 struct cli_state *cli,
607 struct rpc_pipe_client *pipe_hnd,
612 struct policy_handle hive_hnd, key_hnd;
614 struct winreg_String valuename;
616 ZERO_STRUCT(valuename);
618 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
619 SEC_FLAG_MAXIMUM_ALLOWED,
620 &hive_hnd, &key_hnd);
621 if (!NT_STATUS_IS_OK(status)) {
622 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
627 valuename.name = argv[1];
629 status = rpccli_winreg_DeleteValue(pipe_hnd, mem_ctx, &key_hnd,
632 if (!NT_STATUS_IS_OK(status)) {
633 d_fprintf(stderr, _("registry_deletevalue failed: %s\n"),
637 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
638 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
643 static int rpc_registry_deletevalue(struct net_context *c, int argc,
646 if (argc != 2 || c->display_usage) {
647 d_fprintf(stderr, "%s\n%s",
649 _("net rpc registry deletevalue <key> <valuename>\n"));
653 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
654 rpc_registry_deletevalue_internal, argc, argv );
657 static NTSTATUS rpc_registry_getvalue_internal(struct net_context *c,
658 const struct dom_sid *domain_sid,
659 const char *domain_name,
660 struct cli_state *cli,
661 struct rpc_pipe_client *pipe_hnd,
667 struct policy_handle hive_hnd, key_hnd;
669 struct winreg_String valuename;
670 struct registry_value *value = NULL;
671 enum winreg_Type type = REG_NONE;
672 uint32_t data_size = 0;
673 uint32_t value_length = 0;
674 TALLOC_CTX *tmp_ctx = talloc_stackframe();
676 ZERO_STRUCT(valuename);
678 status = registry_openkey(tmp_ctx, pipe_hnd, argv[0],
679 SEC_FLAG_MAXIMUM_ALLOWED,
680 &hive_hnd, &key_hnd);
681 if (!NT_STATUS_IS_OK(status)) {
682 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
687 valuename.name = argv[1];
689 value = talloc_zero(tmp_ctx, struct registry_value);
691 return NT_STATUS_NO_MEMORY;
695 * call QueryValue once with data == NULL to get the
696 * needed memory size to be allocated, then allocate
697 * data buffer and call again.
699 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
707 if (!NT_STATUS_IS_OK(status)) {
708 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
713 value->data = data_blob_talloc(tmp_ctx, NULL, data_size);
715 status = rpccli_winreg_QueryValue(pipe_hnd, tmp_ctx, &key_hnd,
723 if (!NT_STATUS_IS_OK(status)) {
724 d_fprintf(stderr, _("registry_queryvalue failed: %s\n"),
731 print_registry_value(value, raw);
734 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &key_hnd, NULL);
735 rpccli_winreg_CloseKey(pipe_hnd, tmp_ctx, &hive_hnd, NULL);
737 TALLOC_FREE(tmp_ctx);
742 static NTSTATUS rpc_registry_getvalue_full(struct net_context *c,
743 const struct dom_sid *domain_sid,
744 const char *domain_name,
745 struct cli_state *cli,
746 struct rpc_pipe_client *pipe_hnd,
751 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
752 cli, pipe_hnd, mem_ctx, false,
756 static int rpc_registry_getvalue(struct net_context *c, int argc,
759 if (argc != 2 || c->display_usage) {
760 d_fprintf(stderr, "%s\n%s",
762 _("net rpc registry getvalue <key> <valuename>\n"));
766 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
767 rpc_registry_getvalue_full, argc, argv);
770 static NTSTATUS rpc_registry_getvalue_raw(struct net_context *c,
771 const struct dom_sid *domain_sid,
772 const char *domain_name,
773 struct cli_state *cli,
774 struct rpc_pipe_client *pipe_hnd,
779 return rpc_registry_getvalue_internal(c, domain_sid, domain_name,
780 cli, pipe_hnd, mem_ctx, true,
784 static int rpc_registry_getvalueraw(struct net_context *c, int argc,
787 if (argc != 2 || c->display_usage) {
788 d_fprintf(stderr, "%s\n%s",
790 _("net rpc registry getvalue <key> <valuename>\n"));
794 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
795 rpc_registry_getvalue_raw, argc, argv);
798 static NTSTATUS rpc_registry_createkey_internal(struct net_context *c,
799 const struct dom_sid *domain_sid,
800 const char *domain_name,
801 struct cli_state *cli,
802 struct rpc_pipe_client *pipe_hnd,
808 struct policy_handle hive_hnd, key_hnd;
809 struct winreg_String key, keyclass;
810 enum winreg_CreateAction action;
814 ZERO_STRUCT(keyclass);
816 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
817 return NT_STATUS_INVALID_PARAMETER;
820 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
821 SEC_FLAG_MAXIMUM_ALLOWED,
823 if (!(NT_STATUS_IS_OK(status))) {
827 action = REG_ACTION_NONE;
830 status = rpccli_winreg_CreateKey(pipe_hnd, mem_ctx, &hive_hnd, key,
831 keyclass, 0, REG_KEY_READ, NULL,
832 &key_hnd, &action, NULL);
833 if (!NT_STATUS_IS_OK(status)) {
834 d_fprintf(stderr, _("createkey returned %s\n"),
836 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
841 case REG_ACTION_NONE:
842 d_printf(_("createkey did nothing -- huh?\n"));
844 case REG_CREATED_NEW_KEY:
845 d_printf(_("createkey created %s\n"), argv[0]);
847 case REG_OPENED_EXISTING_KEY:
848 d_printf(_("createkey opened existing %s\n"), argv[0]);
852 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &key_hnd, NULL);
853 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
858 static int rpc_registry_createkey(struct net_context *c, int argc,
861 if (argc != 1 || c->display_usage) {
862 d_fprintf(stderr, "%s\n%s",
864 _("net rpc registry createkey <key>\n"));
868 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
869 rpc_registry_createkey_internal, argc, argv );
872 static NTSTATUS rpc_registry_deletekey_internal(struct net_context *c,
873 const struct dom_sid *domain_sid,
874 const char *domain_name,
875 struct cli_state *cli,
876 struct rpc_pipe_client *pipe_hnd,
882 struct policy_handle hive_hnd;
883 struct winreg_String key;
888 if (!reg_hive_key(mem_ctx, argv[0], &hive, &key.name)) {
889 return NT_STATUS_INVALID_PARAMETER;
892 status = rpccli_winreg_Connect(pipe_hnd, mem_ctx, hive,
893 SEC_FLAG_MAXIMUM_ALLOWED,
895 if (!(NT_STATUS_IS_OK(status))) {
899 status = rpccli_winreg_DeleteKey(pipe_hnd, mem_ctx, &hive_hnd, key, NULL);
900 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &hive_hnd, NULL);
902 if (!NT_STATUS_IS_OK(status)) {
903 d_fprintf(stderr, _("deletekey returned %s\n"),
910 static int rpc_registry_deletekey(struct net_context *c, int argc, const char **argv )
912 if (argc != 1 || c->display_usage) {
913 d_fprintf(stderr, "%s\n%s",
915 _("net rpc registry deletekey <key>\n"));
919 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
920 rpc_registry_deletekey_internal, argc, argv );
923 /********************************************************************
924 ********************************************************************/
926 static NTSTATUS rpc_registry_enumerate_internal(struct net_context *c,
927 const struct dom_sid *domain_sid,
928 const char *domain_name,
929 struct cli_state *cli,
930 struct rpc_pipe_client *pipe_hnd,
935 struct policy_handle pol_hive, pol_key;
937 uint32 num_subkeys = 0;
938 uint32 num_values = 0;
939 char **names = NULL, **classes = NULL;
940 NTTIME **modtimes = NULL;
942 struct registry_value **values = NULL;
944 if (argc != 1 || c->display_usage) {
947 _("net rpc registry enumerate <path>\n"));
948 d_printf("%s net rpc registry enumerate "
949 "'HKLM\\Software\\Samba'\n", _("Example:"));
950 return NT_STATUS_INVALID_PARAMETER;
953 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
954 &pol_hive, &pol_key);
955 if (!NT_STATUS_IS_OK(status)) {
956 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
961 status = registry_enumkeys(mem_ctx, pipe_hnd, &pol_key, &num_subkeys,
962 &names, &classes, &modtimes);
963 if (!NT_STATUS_IS_OK(status)) {
964 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
969 for (i=0; i<num_subkeys; i++) {
970 print_registry_key(names[i], modtimes[i]);
973 status = registry_enumvalues(mem_ctx, pipe_hnd, &pol_key, &num_values,
975 if (!NT_STATUS_IS_OK(status)) {
976 d_fprintf(stderr, _("enumerating values failed: %s\n"),
981 for (i=0; i<num_values; i++) {
982 print_registry_value_with_name(names[i], values[i]);
985 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
986 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
991 /********************************************************************
992 ********************************************************************/
994 static int rpc_registry_enumerate(struct net_context *c, int argc,
997 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
998 rpc_registry_enumerate_internal, argc, argv );
1001 /********************************************************************
1002 ********************************************************************/
1004 static NTSTATUS rpc_registry_save_internal(struct net_context *c,
1005 const struct dom_sid *domain_sid,
1006 const char *domain_name,
1007 struct cli_state *cli,
1008 struct rpc_pipe_client *pipe_hnd,
1009 TALLOC_CTX *mem_ctx,
1013 WERROR result = WERR_GENERAL_FAILURE;
1014 struct policy_handle pol_hive, pol_key;
1015 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1016 struct winreg_String filename;
1018 if (argc != 2 || c->display_usage) {
1021 _("net rpc registry backup <path> <file> \n"));
1022 return NT_STATUS_INVALID_PARAMETER;
1025 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_ALL,
1026 &pol_hive, &pol_key);
1027 if (!NT_STATUS_IS_OK(status)) {
1028 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1033 filename.name = argv[1];
1034 status = rpccli_winreg_SaveKey( pipe_hnd, mem_ctx, &pol_key, &filename, NULL, NULL);
1035 if ( !W_ERROR_IS_OK(result) ) {
1036 d_fprintf(stderr, _("Unable to save [%s] to %s:%s\n"), argv[0],
1037 cli->desthost, argv[1]);
1042 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1043 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1048 /********************************************************************
1049 ********************************************************************/
1051 static int rpc_registry_save(struct net_context *c, int argc, const char **argv )
1053 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1054 rpc_registry_save_internal, argc, argv );
1058 /********************************************************************
1059 ********************************************************************/
1061 static void dump_values( REGF_NK_REC *nk )
1064 const char *data_str = NULL;
1065 uint32 data_size, data;
1071 for ( i=0; i<nk->num_values; i++ ) {
1072 d_printf( "\"%s\" = ", nk->values[i].valuename ? nk->values[i].valuename : "(default)" );
1073 d_printf( "(%s) ", str_regtype( nk->values[i].type ) );
1075 data_size = nk->values[i].data_size & ~VK_DATA_IN_OFFSET;
1076 switch ( nk->values[i].type ) {
1078 blob = data_blob_const(nk->values[i].data, data_size);
1079 pull_reg_sz(talloc_tos(), &blob, &data_str);
1083 d_printf( "%s", data_str );
1087 for ( j=0; j<data_size; j++ ) {
1088 d_printf( "%c", nk->values[i].data[j] );
1092 data = IVAL( nk->values[i].data, 0 );
1093 d_printf("0x%x", data );
1096 for ( j=0; j<data_size; j++ ) {
1097 d_printf( "%x", nk->values[i].data[j] );
1101 d_printf(_("unknown"));
1110 /********************************************************************
1111 ********************************************************************/
1113 static bool dump_registry_tree( REGF_FILE *file, REGF_NK_REC *nk, const char *parent )
1117 /* depth first dump of the registry tree */
1119 while ( (key = regfio_fetch_subkey( file, nk )) ) {
1121 if (asprintf(®path, "%s\\%s", parent, key->keyname) < 0) {
1124 d_printf("[%s]\n", regpath );
1127 dump_registry_tree( file, key, regpath );
1134 /********************************************************************
1135 ********************************************************************/
1137 static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk,
1138 REGF_NK_REC *parent, REGF_FILE *outfile,
1139 const char *parentpath )
1141 REGF_NK_REC *key, *subkey;
1142 struct regval_ctr *values = NULL;
1143 struct regsubkey_ctr *subkeys = NULL;
1148 werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys);
1149 if (!W_ERROR_IS_OK(werr)) {
1150 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
1151 "%s\n", win_errstr(werr)));
1155 werr = regval_ctr_init(subkeys, &values);
1156 if (!W_ERROR_IS_OK(werr)) {
1157 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
1158 TALLOC_FREE(subkeys);
1162 /* copy values into the struct regval_ctr */
1164 for ( i=0; i<nk->num_values; i++ ) {
1165 regval_ctr_addvalue( values, nk->values[i].valuename, nk->values[i].type,
1166 nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) );
1169 /* copy subkeys into the struct regsubkey_ctr */
1171 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1172 regsubkey_ctr_addkey( subkeys, subkey->keyname );
1175 key = regfio_write_key( outfile, nk->keyname, values, subkeys, nk->sec_desc->sec_desc, parent );
1177 /* write each one of the subkeys out */
1179 path = talloc_asprintf(subkeys,
1185 TALLOC_FREE(subkeys);
1189 nk->subkey_index = 0;
1190 while ( (subkey = regfio_fetch_subkey( infile, nk )) ) {
1191 write_registry_tree( infile, subkey, key, outfile, path );
1194 d_printf("[%s]\n", path );
1195 TALLOC_FREE(subkeys);
1200 /********************************************************************
1201 ********************************************************************/
1203 static int rpc_registry_dump(struct net_context *c, int argc, const char **argv)
1205 REGF_FILE *registry;
1208 if (argc != 1 || c->display_usage) {
1211 _("net rpc registry dump <file> \n"));
1215 d_printf(_("Opening %s...."), argv[0]);
1216 if ( !(registry = regfio_open( argv[0], O_RDONLY, 0)) ) {
1217 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1220 d_printf(_("ok\n"));
1222 /* get the root of the registry file */
1224 if ((nk = regfio_rootkey( registry )) == NULL) {
1225 d_fprintf(stderr, _("Could not get rootkey\n"));
1226 regfio_close( registry );
1229 d_printf("[%s]\n", nk->keyname);
1233 dump_registry_tree( registry, nk, nk->keyname );
1236 talloc_report_full( registry->mem_ctx, stderr );
1238 d_printf(_("Closing registry..."));
1239 regfio_close( registry );
1240 d_printf(_("ok\n"));
1245 /********************************************************************
1246 ********************************************************************/
1248 static int rpc_registry_copy(struct net_context *c, int argc, const char **argv )
1250 REGF_FILE *infile = NULL, *outfile = NULL;
1254 if (argc != 2 || c->display_usage) {
1257 _("net rpc registry copy <srcfile> <newfile>\n"));
1261 d_printf(_("Opening %s...."), argv[0]);
1262 if ( !(infile = regfio_open( argv[0], O_RDONLY, 0 )) ) {
1263 d_fprintf(stderr, _("Failed to open %s for reading\n"),argv[0]);
1266 d_printf(_("ok\n"));
1268 d_printf(_("Opening %s...."), argv[1]);
1269 if ( !(outfile = regfio_open( argv[1], (O_RDWR|O_CREAT|O_TRUNC), (S_IREAD|S_IWRITE) )) ) {
1270 d_fprintf(stderr, _("Failed to open %s for writing\n"),argv[1]);
1273 d_printf(_("ok\n"));
1275 /* get the root of the registry file */
1277 if ((nk = regfio_rootkey( infile )) == NULL) {
1278 d_fprintf(stderr, _("Could not get rootkey\n"));
1281 d_printf(_("RootKey: [%s]\n"), nk->keyname);
1283 write_registry_tree( infile, nk, NULL, outfile, "" );
1289 d_printf(_("Closing %s..."), argv[1]);
1291 regfio_close( outfile );
1293 d_printf(_("ok\n"));
1295 d_printf(_("Closing %s..."), argv[0]);
1297 regfio_close( infile );
1299 d_printf(_("ok\n"));
1304 /********************************************************************
1305 ********************************************************************/
1307 static NTSTATUS rpc_registry_getsd_internal(struct net_context *c,
1308 const struct dom_sid *domain_sid,
1309 const char *domain_name,
1310 struct cli_state *cli,
1311 struct rpc_pipe_client *pipe_hnd,
1312 TALLOC_CTX *mem_ctx,
1316 struct policy_handle pol_hive, pol_key;
1318 enum ndr_err_code ndr_err;
1319 struct KeySecurityData *sd = NULL;
1322 struct security_descriptor sec_desc;
1323 uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED |
1324 SEC_FLAG_SYSTEM_SECURITY;
1326 if (argc <1 || argc > 2 || c->display_usage) {
1329 _("net rpc registry getsd <path> <secinfo>\n"));
1330 d_printf("%s net rpc registry getsd "
1331 "'HKLM\\Software\\Samba'\n", _("Example:"));
1332 return NT_STATUS_INVALID_PARAMETER;
1335 status = registry_openkey(mem_ctx, pipe_hnd, argv[0],
1337 &pol_hive, &pol_key);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1344 sd = TALLOC_ZERO_P(mem_ctx, struct KeySecurityData);
1346 status = NT_STATUS_NO_MEMORY;
1353 sscanf(argv[1], "%x", &sec_info);
1355 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
1358 status = registry_getsd(mem_ctx, pipe_hnd, &pol_key, sec_info, sd);
1359 if (!NT_STATUS_IS_OK(status)) {
1360 d_fprintf(stderr, _("getting sd failed: %s\n"),
1365 blob.data = sd->data;
1366 blob.length = sd->size;
1368 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &sec_desc,
1369 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
1370 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1371 status = ndr_map_error2ntstatus(ndr_err);
1374 status = NT_STATUS_OK;
1376 display_sec_desc(&sec_desc);
1379 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1380 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1386 static int rpc_registry_getsd(struct net_context *c, int argc, const char **argv)
1388 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1389 rpc_registry_getsd_internal, argc, argv);
1392 /********************************************************************
1393 ********************************************************************/
1395 * @defgroup net_rpc_registry net rpc registry
1399 * @defgroup net_rpc_registry_export Export
1400 * @ingroup net_rpc_registry
1404 static NTSTATUS registry_export(struct rpc_pipe_client* pipe_hnd,
1406 struct policy_handle* key_hnd,
1407 struct reg_format* f,
1408 const char* parentfullname,
1412 uint32 num_subkeys = 0;
1413 uint32 num_values = 0;
1414 char **names = NULL, **classes = NULL;
1415 NTTIME **modtimes = NULL;
1416 struct regval_blob **values = NULL;
1419 TALLOC_CTX* mem_ctx = talloc_new(ctx);
1422 const char* fullname = name
1423 ? talloc_asprintf(mem_ctx, "%s\\%s", parentfullname, name)
1425 reg_format_key(f, &fullname, 1, false);
1427 status = registry_enumvalues2(mem_ctx, pipe_hnd, key_hnd, &num_values,
1429 if (!NT_STATUS_IS_OK(status)) {
1430 d_fprintf(stderr, _("enumerating values failed: %s\n"),
1435 for (i=0; i<num_values; i++) {
1436 reg_format_regval_blob(f, names[i], values[i]);
1440 status = registry_enumkeys(mem_ctx, pipe_hnd, key_hnd, &num_subkeys,
1441 &names, &classes, &modtimes);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 d_fprintf(stderr, _("enumerating keys failed: %s\n"),
1448 for (i=0; i<num_subkeys; i++) {
1449 struct policy_handle subkey_hnd;
1450 struct winreg_String key;
1452 /* key.name = talloc_strdup(mem_ctx, names[i]); ??? */
1453 key.name = names[i];
1455 status = rpccli_winreg_OpenKey(pipe_hnd, mem_ctx, key_hnd, key,
1458 if (NT_STATUS_IS_OK(status)) {
1459 status = registry_export(pipe_hnd, mem_ctx, &subkey_hnd,
1460 f, fullname, names[i]);
1461 if (!(NT_STATUS_IS_OK(status)))
1463 _("export key failed: %s %s\n"),
1464 names[i], nt_errstr(status));
1466 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx,
1470 _("rpccli_winreg_OpenKey failed: %s %s\n"),
1471 names[i], nt_errstr(status));
1475 talloc_free(mem_ctx);
1479 static NTSTATUS rpc_registry_export_internal(struct net_context *c,
1480 const struct dom_sid *domain_sid,
1481 const char *domain_name,
1482 struct cli_state *cli,
1483 struct rpc_pipe_client *pipe_hnd,
1484 TALLOC_CTX *mem_ctx,
1488 struct policy_handle pol_hive, pol_key;
1490 struct reg_format* f;
1492 if (argc < 2 || argc > 3 || c->display_usage) {
1495 _("net rpc registry export <path> <file> [opt]\n"));
1496 d_printf("%s net rpc registry export "
1497 "'HKLM\\Software\\Samba' samba.reg\n", _("Example:"));
1498 return NT_STATUS_INVALID_PARAMETER;
1501 status = registry_openkey(mem_ctx, pipe_hnd, argv[0], REG_KEY_READ,
1502 &pol_hive, &pol_key);
1503 if (!NT_STATUS_IS_OK(status)) {
1504 d_fprintf(stderr, _("registry_openkey failed: %s\n"),
1509 f = reg_format_file(mem_ctx, argv[1], (argc > 2) ? argv[2] : NULL);
1511 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
1512 return map_nt_error_from_unix(errno);
1515 status = registry_export(pipe_hnd, mem_ctx, &pol_key,
1517 if (!NT_STATUS_IS_OK(status))
1520 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_key, NULL);
1521 rpccli_winreg_CloseKey(pipe_hnd, mem_ctx, &pol_hive, NULL);
1525 /********************************************************************
1526 ********************************************************************/
1528 static int rpc_registry_export(struct net_context *c, int argc,
1531 return run_rpc_command(c, NULL, &ndr_table_winreg.syntax_id, 0,
1532 rpc_registry_export_internal, argc, argv );
1538 int net_rpc_registry(struct net_context *c, int argc, const char **argv)
1540 struct functable func[] = {
1543 rpc_registry_enumerate,
1545 N_("Enumerate registry keys and values"),
1546 N_("net rpc registry enumerate\n"
1547 " Enumerate registry keys and values")
1551 rpc_registry_createkey,
1553 N_("Create a new registry key"),
1554 N_("net rpc registry createkey\n"
1555 " Create a new registry key")
1559 rpc_registry_deletekey,
1561 N_("Delete a registry key"),
1562 N_("net rpc registry deletekey\n"
1563 " Delete a registry key")
1567 rpc_registry_getvalue,
1569 N_("Print a registry value"),
1570 N_("net rpc registry getvalue\n"
1571 " Print a registry value")
1575 rpc_registry_getvalueraw,
1577 N_("Print a registry value"),
1578 N_("net rpc registry getvalueraw\n"
1579 " Print a registry value (raw version)")
1583 rpc_registry_setvalue,
1585 N_("Set a new registry value"),
1586 N_("net rpc registry setvalue\n"
1587 " Set a new registry value")
1591 rpc_registry_deletevalue,
1593 N_("Delete a registry value"),
1594 N_("net rpc registry deletevalue\n"
1595 " Delete a registry value")
1601 N_("Save a registry file"),
1602 N_("net rpc registry save\n"
1603 " Save a registry file")
1609 N_("Dump a registry file"),
1610 N_("net rpc registry dump\n"
1611 " Dump a registry file")
1617 N_("Copy a registry file"),
1618 N_("net rpc registry copy\n"
1619 " Copy a registry file")
1625 N_("Get security descriptor"),
1626 N_("net rpc registry getsd\n"
1627 " Get security descriptior")
1631 rpc_registry_export,
1633 N_("net registry export\n"
1634 " Export .reg file")
1636 {NULL, NULL, 0, NULL, NULL}
1638 return net_run_function(c, argc, argv, "net rpc registry", func);