2 Samba Unix/Linux SMB client library
3 Distributed SMB/CIFS Server Management Utility
5 Copyright (C) Gerald (Jerry) Carter 2005-2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "utils/net.h"
22 #include "utils/net_registry_util.h"
24 #include "reg_objects.h"
26 static bool reg_hive_key(TALLOC_CTX
*ctx
, const char *fullname
,
27 uint32
*reg_type
, const char **key_name
)
30 char *hivename
= NULL
;
31 char *tmp_keyname
= NULL
;
33 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
35 werr
= split_hive_key(tmp_ctx
, fullname
, &hivename
, &tmp_keyname
);
36 if (!W_ERROR_IS_OK(werr
)) {
40 *key_name
= talloc_strdup(ctx
, tmp_keyname
);
41 if (*key_name
== NULL
) {
45 if (strequal(hivename
, "HKLM") ||
46 strequal(hivename
, "HKEY_LOCAL_MACHINE"))
48 (*reg_type
) = HKEY_LOCAL_MACHINE
;
49 } else if (strequal(hivename
, "HKCR") ||
50 strequal(hivename
, "HKEY_CLASSES_ROOT"))
52 (*reg_type
) = HKEY_CLASSES_ROOT
;
53 } else if (strequal(hivename
, "HKU") ||
54 strequal(hivename
, "HKEY_USERS"))
56 (*reg_type
) = HKEY_USERS
;
57 } else if (strequal(hivename
, "HKCU") ||
58 strequal(hivename
, "HKEY_CURRENT_USER"))
60 (*reg_type
) = HKEY_CURRENT_USER
;
61 } else if (strequal(hivename
, "HKPD") ||
62 strequal(hivename
, "HKEY_PERFORMANCE_DATA"))
64 (*reg_type
) = HKEY_PERFORMANCE_DATA
;
66 DEBUG(10,("reg_hive_key: unrecognised hive key %s\n",
78 static NTSTATUS
registry_openkey(TALLOC_CTX
*mem_ctx
,
79 struct rpc_pipe_client
*pipe_hnd
,
80 const char *name
, uint32 access_mask
,
81 struct policy_handle
*hive_hnd
,
82 struct policy_handle
*key_hnd
)
86 struct winreg_String key
;
90 if (!reg_hive_key(mem_ctx
, name
, &hive
, &key
.name
)) {
91 return NT_STATUS_INVALID_PARAMETER
;
94 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
, access_mask
,
96 if (!(NT_STATUS_IS_OK(status
))) {
100 status
= rpccli_winreg_OpenKey(pipe_hnd
, mem_ctx
, hive_hnd
, key
, 0,
101 access_mask
, key_hnd
, NULL
);
102 if (!(NT_STATUS_IS_OK(status
))) {
103 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, hive_hnd
, NULL
);
110 static NTSTATUS
registry_enumkeys(TALLOC_CTX
*ctx
,
111 struct rpc_pipe_client
*pipe_hnd
,
112 struct policy_handle
*key_hnd
,
113 uint32
*pnum_keys
, char ***pnames
,
114 char ***pclasses
, NTTIME
***pmodtimes
)
118 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
119 uint32 num_values
, max_valnamelen
, max_valbufsize
;
121 NTTIME last_changed_time
;
123 struct winreg_String classname
;
124 char **names
, **classes
;
127 if (!(mem_ctx
= talloc_new(ctx
))) {
128 return NT_STATUS_NO_MEMORY
;
131 ZERO_STRUCT(classname
);
132 status
= rpccli_winreg_QueryInfoKey(
133 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
134 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
135 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
137 if (!NT_STATUS_IS_OK(status
)) {
141 if (num_subkeys
== 0) {
143 TALLOC_FREE(mem_ctx
);
147 if ((!(names
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
148 (!(classes
= TALLOC_ZERO_ARRAY(mem_ctx
, char *, num_subkeys
))) ||
149 (!(modtimes
= TALLOC_ZERO_ARRAY(mem_ctx
, NTTIME
*,
151 status
= NT_STATUS_NO_MEMORY
;
155 for (i
=0; i
<num_subkeys
; i
++) {
157 struct winreg_StringBuf class_buf
;
158 struct winreg_StringBuf name_buf
;
164 class_buf
.size
= max_classlen
+2;
168 name_buf
.size
= max_subkeylen
+2;
170 ZERO_STRUCT(modtime
);
172 status
= rpccli_winreg_EnumKey(pipe_hnd
, mem_ctx
, key_hnd
,
173 i
, &name_buf
, &class_buf
,
176 if (W_ERROR_EQUAL(werr
,
177 WERR_NO_MORE_ITEMS
) ) {
178 status
= NT_STATUS_OK
;
181 if (!NT_STATUS_IS_OK(status
)) {
187 if (class_buf
.name
&&
188 (!(classes
[i
] = talloc_strdup(classes
, class_buf
.name
)))) {
189 status
= NT_STATUS_NO_MEMORY
;
193 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
194 status
= NT_STATUS_NO_MEMORY
;
198 if ((!(modtimes
[i
] = (NTTIME
*)talloc_memdup(
199 modtimes
, &modtime
, sizeof(modtime
))))) {
200 status
= NT_STATUS_NO_MEMORY
;
205 *pnum_keys
= num_subkeys
;
208 *pnames
= talloc_move(ctx
, &names
);
211 *pclasses
= talloc_move(ctx
, &classes
);
214 *pmodtimes
= talloc_move(ctx
, &modtimes
);
217 status
= NT_STATUS_OK
;
220 TALLOC_FREE(mem_ctx
);
224 static NTSTATUS
registry_enumvalues(TALLOC_CTX
*ctx
,
225 struct rpc_pipe_client
*pipe_hnd
,
226 struct policy_handle
*key_hnd
,
227 uint32
*pnum_values
, char ***pvalnames
,
228 struct registry_value
***pvalues
)
232 uint32 num_subkeys
, max_subkeylen
, max_classlen
;
233 uint32 num_values
, max_valnamelen
, max_valbufsize
;
235 NTTIME last_changed_time
;
237 struct winreg_String classname
;
238 struct registry_value
**values
;
241 if (!(mem_ctx
= talloc_new(ctx
))) {
242 return NT_STATUS_NO_MEMORY
;
245 ZERO_STRUCT(classname
);
246 status
= rpccli_winreg_QueryInfoKey(
247 pipe_hnd
, mem_ctx
, key_hnd
, &classname
, &num_subkeys
,
248 &max_subkeylen
, &max_classlen
, &num_values
, &max_valnamelen
,
249 &max_valbufsize
, &secdescsize
, &last_changed_time
, NULL
);
251 if (!NT_STATUS_IS_OK(status
)) {
255 if (num_values
== 0) {
257 TALLOC_FREE(mem_ctx
);
261 if ((!(names
= TALLOC_ARRAY(mem_ctx
, char *, num_values
))) ||
262 (!(values
= TALLOC_ARRAY(mem_ctx
, struct registry_value
*,
264 status
= NT_STATUS_NO_MEMORY
;
268 for (i
=0; i
<num_values
; i
++) {
269 enum winreg_Type type
= REG_NONE
;
275 struct winreg_ValNameBuf name_buf
;
280 name_buf
.size
= max_valnamelen
+ 2;
282 data_size
= max_valbufsize
;
283 data
= (uint8
*)TALLOC(mem_ctx
, data_size
);
286 status
= rpccli_winreg_EnumValue(pipe_hnd
, mem_ctx
, key_hnd
,
289 &value_length
, &err
);
291 if ( W_ERROR_EQUAL(err
,
292 WERR_NO_MORE_ITEMS
) ) {
293 status
= NT_STATUS_OK
;
297 if (!(NT_STATUS_IS_OK(status
))) {
301 if (name_buf
.name
== NULL
) {
302 status
= NT_STATUS_INVALID_PARAMETER
;
306 if (!(names
[i
] = talloc_strdup(names
, name_buf
.name
))) {
307 status
= NT_STATUS_NO_MEMORY
;
311 err
= registry_pull_value(values
, &values
[i
], type
, data
,
312 data_size
, value_length
);
313 if (!W_ERROR_IS_OK(err
)) {
314 status
= werror_to_ntstatus(err
);
319 *pnum_values
= num_values
;
322 *pvalnames
= talloc_move(ctx
, &names
);
325 *pvalues
= talloc_move(ctx
, &values
);
328 status
= NT_STATUS_OK
;
331 TALLOC_FREE(mem_ctx
);
335 static NTSTATUS
registry_getsd(TALLOC_CTX
*mem_ctx
,
336 struct rpc_pipe_client
*pipe_hnd
,
337 struct policy_handle
*key_hnd
,
339 struct KeySecurityData
*sd
)
341 return rpccli_winreg_GetKeySecurity(pipe_hnd
, mem_ctx
, key_hnd
,
346 static NTSTATUS
registry_setvalue(TALLOC_CTX
*mem_ctx
,
347 struct rpc_pipe_client
*pipe_hnd
,
348 struct policy_handle
*key_hnd
,
350 const struct registry_value
*value
)
352 struct winreg_String name_string
;
357 err
= registry_push_value(mem_ctx
, value
, &blob
);
358 if (!W_ERROR_IS_OK(err
)) {
359 return werror_to_ntstatus(err
);
362 ZERO_STRUCT(name_string
);
364 name_string
.name
= name
;
365 result
= rpccli_winreg_SetValue(pipe_hnd
, blob
.data
, key_hnd
,
366 name_string
, value
->type
,
367 blob
.data
, blob
.length
, NULL
);
368 TALLOC_FREE(blob
.data
);
372 static NTSTATUS
rpc_registry_setvalue_internal(struct net_context
*c
,
373 const DOM_SID
*domain_sid
,
374 const char *domain_name
,
375 struct cli_state
*cli
,
376 struct rpc_pipe_client
*pipe_hnd
,
381 struct policy_handle hive_hnd
, key_hnd
;
383 struct registry_value value
;
385 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
386 SEC_FLAG_MAXIMUM_ALLOWED
,
387 &hive_hnd
, &key_hnd
);
388 if (!NT_STATUS_IS_OK(status
)) {
389 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
394 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
395 d_fprintf(stderr
, _("Too many args for type %s\n"), argv
[2]);
396 return NT_STATUS_NOT_IMPLEMENTED
;
399 if (strequal(argv
[2], "dword")) {
400 value
.type
= REG_DWORD
;
401 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
403 else if (strequal(argv
[2], "sz")) {
405 value
.v
.sz
.len
= strlen(argv
[3])+1;
406 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
409 d_fprintf(stderr
, _("type \"%s\" not implemented\n"), argv
[2]);
410 status
= NT_STATUS_NOT_IMPLEMENTED
;
414 status
= registry_setvalue(mem_ctx
, pipe_hnd
, &key_hnd
,
417 if (!NT_STATUS_IS_OK(status
)) {
418 d_fprintf(stderr
, _("registry_setvalue failed: %s\n"),
423 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
424 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
429 static int rpc_registry_setvalue(struct net_context
*c
, int argc
,
432 if (argc
< 4 || c
->display_usage
) {
433 d_fprintf(stderr
, _("usage: net rpc registry setvalue <key> "
434 "<valuename> <type> [<val>]+\n"));
438 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
439 rpc_registry_setvalue_internal
, argc
, argv
);
442 static NTSTATUS
rpc_registry_deletevalue_internal(struct net_context
*c
,
443 const DOM_SID
*domain_sid
,
444 const char *domain_name
,
445 struct cli_state
*cli
,
446 struct rpc_pipe_client
*pipe_hnd
,
451 struct policy_handle hive_hnd
, key_hnd
;
453 struct winreg_String valuename
;
455 ZERO_STRUCT(valuename
);
457 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
458 SEC_FLAG_MAXIMUM_ALLOWED
,
459 &hive_hnd
, &key_hnd
);
460 if (!NT_STATUS_IS_OK(status
)) {
461 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
466 valuename
.name
= argv
[1];
468 status
= rpccli_winreg_DeleteValue(pipe_hnd
, mem_ctx
, &key_hnd
,
471 if (!NT_STATUS_IS_OK(status
)) {
472 d_fprintf(stderr
, _("registry_deletevalue failed: %s\n"),
476 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
477 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
482 static int rpc_registry_deletevalue(struct net_context
*c
, int argc
,
485 if (argc
!= 2 || c
->display_usage
) {
486 d_fprintf(stderr
, _("usage: net rpc registry deletevalue <key> "
491 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
492 rpc_registry_deletevalue_internal
, argc
, argv
);
495 static NTSTATUS
rpc_registry_getvalue_internal(struct net_context
*c
,
496 const DOM_SID
*domain_sid
,
497 const char *domain_name
,
498 struct cli_state
*cli
,
499 struct rpc_pipe_client
*pipe_hnd
,
505 struct policy_handle hive_hnd
, key_hnd
;
508 struct winreg_String valuename
;
509 struct registry_value
*value
= NULL
;
510 enum winreg_Type type
= REG_NONE
;
511 uint8_t *data
= NULL
;
512 uint32_t data_size
= 0;
513 uint32_t value_length
= 0;
514 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
516 ZERO_STRUCT(valuename
);
518 status
= registry_openkey(tmp_ctx
, pipe_hnd
, argv
[0],
519 SEC_FLAG_MAXIMUM_ALLOWED
,
520 &hive_hnd
, &key_hnd
);
521 if (!NT_STATUS_IS_OK(status
)) {
522 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
527 valuename
.name
= argv
[1];
530 * call QueryValue once with data == NULL to get the
531 * needed memory size to be allocated, then allocate
532 * data buffer and call again.
534 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
542 if (!NT_STATUS_IS_OK(status
)) {
543 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
548 data
= (uint8
*)TALLOC(tmp_ctx
, data_size
);
551 status
= rpccli_winreg_QueryValue(pipe_hnd
, tmp_ctx
, &key_hnd
,
559 if (!NT_STATUS_IS_OK(status
)) {
560 d_fprintf(stderr
, _("registry_queryvalue failed: %s\n"),
565 werr
= registry_pull_value(tmp_ctx
, &value
, type
, data
,
566 data_size
, value_length
);
567 if (!W_ERROR_IS_OK(werr
)) {
568 status
= werror_to_ntstatus(werr
);
572 print_registry_value(value
, raw
);
575 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &key_hnd
, NULL
);
576 rpccli_winreg_CloseKey(pipe_hnd
, tmp_ctx
, &hive_hnd
, NULL
);
578 TALLOC_FREE(tmp_ctx
);
583 static NTSTATUS
rpc_registry_getvalue_full(struct net_context
*c
,
584 const DOM_SID
*domain_sid
,
585 const char *domain_name
,
586 struct cli_state
*cli
,
587 struct rpc_pipe_client
*pipe_hnd
,
592 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
593 cli
, pipe_hnd
, mem_ctx
, false,
597 static int rpc_registry_getvalue(struct net_context
*c
, int argc
,
600 if (argc
!= 2 || c
->display_usage
) {
601 d_fprintf(stderr
, _("usage: net rpc registry getvalue <key> "
606 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
607 rpc_registry_getvalue_full
, argc
, argv
);
610 static NTSTATUS
rpc_registry_getvalue_raw(struct net_context
*c
,
611 const DOM_SID
*domain_sid
,
612 const char *domain_name
,
613 struct cli_state
*cli
,
614 struct rpc_pipe_client
*pipe_hnd
,
619 return rpc_registry_getvalue_internal(c
, domain_sid
, domain_name
,
620 cli
, pipe_hnd
, mem_ctx
, true,
624 static int rpc_registry_getvalueraw(struct net_context
*c
, int argc
,
627 if (argc
!= 2 || c
->display_usage
) {
628 d_fprintf(stderr
, _("usage: net rpc registry getvalue <key> "
633 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
634 rpc_registry_getvalue_raw
, argc
, argv
);
637 static NTSTATUS
rpc_registry_createkey_internal(struct net_context
*c
,
638 const DOM_SID
*domain_sid
,
639 const char *domain_name
,
640 struct cli_state
*cli
,
641 struct rpc_pipe_client
*pipe_hnd
,
647 struct policy_handle hive_hnd
, key_hnd
;
648 struct winreg_String key
, keyclass
;
649 enum winreg_CreateAction action
;
653 ZERO_STRUCT(keyclass
);
655 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
656 return NT_STATUS_INVALID_PARAMETER
;
659 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
660 SEC_FLAG_MAXIMUM_ALLOWED
,
662 if (!(NT_STATUS_IS_OK(status
))) {
666 action
= REG_ACTION_NONE
;
669 status
= rpccli_winreg_CreateKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
,
670 keyclass
, 0, REG_KEY_READ
, NULL
,
671 &key_hnd
, &action
, NULL
);
672 if (!NT_STATUS_IS_OK(status
)) {
673 d_fprintf(stderr
, _("createkey returned %s\n"),
675 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
680 case REG_ACTION_NONE
:
681 d_printf(_("createkey did nothing -- huh?\n"));
683 case REG_CREATED_NEW_KEY
:
684 d_printf(_("createkey created %s\n"), argv
[0]);
686 case REG_OPENED_EXISTING_KEY
:
687 d_printf(_("createkey opened existing %s\n"), argv
[0]);
691 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &key_hnd
, NULL
);
692 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
697 static int rpc_registry_createkey(struct net_context
*c
, int argc
,
700 if (argc
!= 1 || c
->display_usage
) {
702 _("usage: net rpc registry createkey <key>\n"));
706 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
707 rpc_registry_createkey_internal
, argc
, argv
);
710 static NTSTATUS
rpc_registry_deletekey_internal(struct net_context
*c
,
711 const DOM_SID
*domain_sid
,
712 const char *domain_name
,
713 struct cli_state
*cli
,
714 struct rpc_pipe_client
*pipe_hnd
,
720 struct policy_handle hive_hnd
;
721 struct winreg_String key
;
726 if (!reg_hive_key(mem_ctx
, argv
[0], &hive
, &key
.name
)) {
727 return NT_STATUS_INVALID_PARAMETER
;
730 status
= rpccli_winreg_Connect(pipe_hnd
, mem_ctx
, hive
,
731 SEC_FLAG_MAXIMUM_ALLOWED
,
733 if (!(NT_STATUS_IS_OK(status
))) {
737 status
= rpccli_winreg_DeleteKey(pipe_hnd
, mem_ctx
, &hive_hnd
, key
, NULL
);
738 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &hive_hnd
, NULL
);
740 if (!NT_STATUS_IS_OK(status
)) {
741 d_fprintf(stderr
, _("deletekey returned %s\n"),
748 static int rpc_registry_deletekey(struct net_context
*c
, int argc
, const char **argv
)
750 if (argc
!= 1 || c
->display_usage
) {
752 _("usage: net rpc registry deletekey <key>\n"));
756 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
757 rpc_registry_deletekey_internal
, argc
, argv
);
760 /********************************************************************
761 ********************************************************************/
763 static NTSTATUS
rpc_registry_enumerate_internal(struct net_context
*c
,
764 const DOM_SID
*domain_sid
,
765 const char *domain_name
,
766 struct cli_state
*cli
,
767 struct rpc_pipe_client
*pipe_hnd
,
772 struct policy_handle pol_hive
, pol_key
;
774 uint32 num_subkeys
= 0;
775 uint32 num_values
= 0;
776 char **names
= NULL
, **classes
= NULL
;
777 NTTIME
**modtimes
= NULL
;
779 struct registry_value
**values
= NULL
;
781 if (argc
!= 1 || c
->display_usage
) {
782 d_printf(_("Usage: net rpc registry enumerate <path>\n"));
783 d_printf(_("Example: net rpc registry enumerate "
784 "'HKLM\\Software\\Samba'\n"));
785 return NT_STATUS_INVALID_PARAMETER
;
788 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_READ
,
789 &pol_hive
, &pol_key
);
790 if (!NT_STATUS_IS_OK(status
)) {
791 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
796 status
= registry_enumkeys(mem_ctx
, pipe_hnd
, &pol_key
, &num_subkeys
,
797 &names
, &classes
, &modtimes
);
798 if (!NT_STATUS_IS_OK(status
)) {
799 d_fprintf(stderr
, _("enumerating keys failed: %s\n"),
804 for (i
=0; i
<num_subkeys
; i
++) {
805 print_registry_key(names
[i
], modtimes
[i
]);
808 status
= registry_enumvalues(mem_ctx
, pipe_hnd
, &pol_key
, &num_values
,
810 if (!NT_STATUS_IS_OK(status
)) {
811 d_fprintf(stderr
, _("enumerating values failed: %s\n"),
816 for (i
=0; i
<num_values
; i
++) {
817 print_registry_value_with_name(names
[i
], values
[i
]);
820 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
821 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
826 /********************************************************************
827 ********************************************************************/
829 static int rpc_registry_enumerate(struct net_context
*c
, int argc
,
832 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
833 rpc_registry_enumerate_internal
, argc
, argv
);
836 /********************************************************************
837 ********************************************************************/
839 static NTSTATUS
rpc_registry_save_internal(struct net_context
*c
,
840 const DOM_SID
*domain_sid
,
841 const char *domain_name
,
842 struct cli_state
*cli
,
843 struct rpc_pipe_client
*pipe_hnd
,
848 WERROR result
= WERR_GENERAL_FAILURE
;
849 struct policy_handle pol_hive
, pol_key
;
850 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
851 struct winreg_String filename
;
853 if (argc
!= 2 || c
->display_usage
) {
854 d_printf(_("Usage: net rpc registry backup <path> "
856 return NT_STATUS_INVALID_PARAMETER
;
859 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0], REG_KEY_ALL
,
860 &pol_hive
, &pol_key
);
861 if (!NT_STATUS_IS_OK(status
)) {
862 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
867 filename
.name
= argv
[1];
868 status
= rpccli_winreg_SaveKey( pipe_hnd
, mem_ctx
, &pol_key
, &filename
, NULL
, NULL
);
869 if ( !W_ERROR_IS_OK(result
) ) {
870 d_fprintf(stderr
, _("Unable to save [%s] to %s:%s\n"), argv
[0],
871 cli
->desthost
, argv
[1]);
876 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
877 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
882 /********************************************************************
883 ********************************************************************/
885 static int rpc_registry_save(struct net_context
*c
, int argc
, const char **argv
)
887 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
888 rpc_registry_save_internal
, argc
, argv
);
892 /********************************************************************
893 ********************************************************************/
895 static void dump_values( REGF_NK_REC
*nk
)
898 char *data_str
= NULL
;
899 uint32 data_size
, data
;
904 for ( i
=0; i
<nk
->num_values
; i
++ ) {
905 d_printf( "\"%s\" = ", nk
->values
[i
].valuename
? nk
->values
[i
].valuename
: "(default)" );
906 d_printf( "(%s) ", reg_type_lookup( nk
->values
[i
].type
) );
908 data_size
= nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
;
909 switch ( nk
->values
[i
].type
) {
911 rpcstr_pull_talloc(talloc_tos(),
919 d_printf( "%s", data_str
);
923 for ( j
=0; j
<data_size
; j
++ ) {
924 d_printf( "%c", nk
->values
[i
].data
[j
] );
928 data
= IVAL( nk
->values
[i
].data
, 0 );
929 d_printf("0x%x", data
);
932 for ( j
=0; j
<data_size
; j
++ ) {
933 d_printf( "%x", nk
->values
[i
].data
[j
] );
937 d_printf(_("unknown"));
946 /********************************************************************
947 ********************************************************************/
949 static bool dump_registry_tree( REGF_FILE
*file
, REGF_NK_REC
*nk
, const char *parent
)
953 /* depth first dump of the registry tree */
955 while ( (key
= regfio_fetch_subkey( file
, nk
)) ) {
957 if (asprintf(®path
, "%s\\%s", parent
, key
->keyname
) < 0) {
960 d_printf("[%s]\n", regpath
);
963 dump_registry_tree( file
, key
, regpath
);
970 /********************************************************************
971 ********************************************************************/
973 static bool write_registry_tree( REGF_FILE
*infile
, REGF_NK_REC
*nk
,
974 REGF_NK_REC
*parent
, REGF_FILE
*outfile
,
975 const char *parentpath
)
977 REGF_NK_REC
*key
, *subkey
;
978 struct regval_ctr
*values
= NULL
;
979 struct regsubkey_ctr
*subkeys
= NULL
;
984 werr
= regsubkey_ctr_init(infile
->mem_ctx
, &subkeys
);
985 if (!W_ERROR_IS_OK(werr
)) {
986 DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: "
987 "%s\n", win_errstr(werr
)));
991 if ( !(values
= TALLOC_ZERO_P( subkeys
, struct regval_ctr
)) ) {
992 DEBUG(0,("write_registry_tree: talloc() failed!\n"));
993 TALLOC_FREE(subkeys
);
997 /* copy values into the struct regval_ctr */
999 for ( i
=0; i
<nk
->num_values
; i
++ ) {
1000 regval_ctr_addvalue( values
, nk
->values
[i
].valuename
, nk
->values
[i
].type
,
1001 (const char *)nk
->values
[i
].data
, (nk
->values
[i
].data_size
& ~VK_DATA_IN_OFFSET
) );
1004 /* copy subkeys into the struct regsubkey_ctr */
1006 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1007 regsubkey_ctr_addkey( subkeys
, subkey
->keyname
);
1010 key
= regfio_write_key( outfile
, nk
->keyname
, values
, subkeys
, nk
->sec_desc
->sec_desc
, parent
);
1012 /* write each one of the subkeys out */
1014 path
= talloc_asprintf(subkeys
,
1020 TALLOC_FREE(subkeys
);
1024 nk
->subkey_index
= 0;
1025 while ( (subkey
= regfio_fetch_subkey( infile
, nk
)) ) {
1026 write_registry_tree( infile
, subkey
, key
, outfile
, path
);
1029 d_printf("[%s]\n", path
);
1030 TALLOC_FREE(subkeys
);
1035 /********************************************************************
1036 ********************************************************************/
1038 static int rpc_registry_dump(struct net_context
*c
, int argc
, const char **argv
)
1040 REGF_FILE
*registry
;
1043 if (argc
!= 1 || c
->display_usage
) {
1044 d_printf(_("Usage: net rpc registry dump <file> \n"));
1048 d_printf(_("Opening %s...."), argv
[0]);
1049 if ( !(registry
= regfio_open( argv
[0], O_RDONLY
, 0)) ) {
1050 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1053 d_printf(_("ok\n"));
1055 /* get the root of the registry file */
1057 if ((nk
= regfio_rootkey( registry
)) == NULL
) {
1058 d_fprintf(stderr
, _("Could not get rootkey\n"));
1059 regfio_close( registry
);
1062 d_printf("[%s]\n", nk
->keyname
);
1066 dump_registry_tree( registry
, nk
, nk
->keyname
);
1069 talloc_report_full( registry
->mem_ctx
, stderr
);
1071 d_printf(_("Closing registry..."));
1072 regfio_close( registry
);
1073 d_printf(_("ok\n"));
1078 /********************************************************************
1079 ********************************************************************/
1081 static int rpc_registry_copy(struct net_context
*c
, int argc
, const char **argv
)
1083 REGF_FILE
*infile
= NULL
, *outfile
= NULL
;
1087 if (argc
!= 2 || c
->display_usage
) {
1088 d_printf(_("Usage: net rpc registry copy <srcfile> "
1093 d_printf(_("Opening %s...."), argv
[0]);
1094 if ( !(infile
= regfio_open( argv
[0], O_RDONLY
, 0 )) ) {
1095 d_fprintf(stderr
, _("Failed to open %s for reading\n"),argv
[0]);
1098 d_printf(_("ok\n"));
1100 d_printf(_("Opening %s...."), argv
[1]);
1101 if ( !(outfile
= regfio_open( argv
[1], (O_RDWR
|O_CREAT
|O_TRUNC
), (S_IREAD
|S_IWRITE
) )) ) {
1102 d_fprintf(stderr
, _("Failed to open %s for writing\n"),argv
[1]);
1105 d_printf(_("ok\n"));
1107 /* get the root of the registry file */
1109 if ((nk
= regfio_rootkey( infile
)) == NULL
) {
1110 d_fprintf(stderr
, _("Could not get rootkey\n"));
1113 d_printf(_("RootKey: [%s]\n"), nk
->keyname
);
1115 write_registry_tree( infile
, nk
, NULL
, outfile
, "" );
1121 d_printf(_("Closing %s..."), argv
[1]);
1123 regfio_close( outfile
);
1125 d_printf(_("ok\n"));
1127 d_printf(_("Closing %s..."), argv
[0]);
1129 regfio_close( infile
);
1131 d_printf(_("ok\n"));
1136 /********************************************************************
1137 ********************************************************************/
1139 static NTSTATUS
rpc_registry_getsd_internal(struct net_context
*c
,
1140 const DOM_SID
*domain_sid
,
1141 const char *domain_name
,
1142 struct cli_state
*cli
,
1143 struct rpc_pipe_client
*pipe_hnd
,
1144 TALLOC_CTX
*mem_ctx
,
1148 struct policy_handle pol_hive
, pol_key
;
1150 enum ndr_err_code ndr_err
;
1151 struct KeySecurityData
*sd
= NULL
;
1154 struct security_descriptor sec_desc
;
1155 uint32_t access_mask
= REG_KEY_READ
|
1156 SEC_FLAG_MAXIMUM_ALLOWED
|
1157 SEC_FLAG_SYSTEM_SECURITY
;
1159 if (argc
<1 || argc
> 2 || c
->display_usage
) {
1160 d_printf(_("Usage: net rpc registry getsd <path> "
1162 d_printf(_("Example: net rpc registry getsd "
1163 "'HKLM\\Software\\Samba'\n"));
1164 return NT_STATUS_INVALID_PARAMETER
;
1167 status
= registry_openkey(mem_ctx
, pipe_hnd
, argv
[0],
1169 &pol_hive
, &pol_key
);
1170 if (!NT_STATUS_IS_OK(status
)) {
1171 d_fprintf(stderr
, _("registry_openkey failed: %s\n"),
1176 sd
= TALLOC_ZERO_P(mem_ctx
, struct KeySecurityData
);
1178 status
= NT_STATUS_NO_MEMORY
;
1185 sscanf(argv
[1], "%x", &sec_info
);
1187 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
1190 status
= registry_getsd(mem_ctx
, pipe_hnd
, &pol_key
, sec_info
, sd
);
1191 if (!NT_STATUS_IS_OK(status
)) {
1192 d_fprintf(stderr
, _("getting sd failed: %s\n"),
1197 blob
.data
= sd
->data
;
1198 blob
.length
= sd
->size
;
1200 ndr_err
= ndr_pull_struct_blob(&blob
, mem_ctx
, NULL
, &sec_desc
,
1201 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
);
1202 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1203 status
= ndr_map_error2ntstatus(ndr_err
);
1206 status
= NT_STATUS_OK
;
1208 display_sec_desc(&sec_desc
);
1211 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_key
, NULL
);
1212 rpccli_winreg_CloseKey(pipe_hnd
, mem_ctx
, &pol_hive
, NULL
);
1218 static int rpc_registry_getsd(struct net_context
*c
, int argc
, const char **argv
)
1220 return run_rpc_command(c
, NULL
, &ndr_table_winreg
.syntax_id
, 0,
1221 rpc_registry_getsd_internal
, argc
, argv
);
1224 /********************************************************************
1225 ********************************************************************/
1227 int net_rpc_registry(struct net_context
*c
, int argc
, const char **argv
)
1229 struct functable func
[] = {
1232 rpc_registry_enumerate
,
1234 N_("Enumerate registry keys and values"),
1235 N_("net rpc registry enumerate\n"
1236 " Enumerate registry keys and values")
1240 rpc_registry_createkey
,
1242 N_("Create a new registry key"),
1243 N_("net rpc registry createkey\n"
1244 " Create a new registry key")
1248 rpc_registry_deletekey
,
1250 N_("Delete a registry key"),
1251 N_("net rpc registry deletekey\n"
1252 " Delete a registry key")
1256 rpc_registry_getvalue
,
1258 N_("Print a registry value"),
1259 N_("net rpc registry getvalue\n"
1260 " Print a registry value")
1264 rpc_registry_getvalueraw
,
1266 N_("Print a registry value"),
1267 N_("net rpc registry getvalueraw\n"
1268 " Print a registry value (raw version)")
1272 rpc_registry_setvalue
,
1274 N_("Set a new registry value"),
1275 N_("net rpc registry setvalue\n"
1276 " Set a new registry value")
1280 rpc_registry_deletevalue
,
1282 N_("Delete a registry value"),
1283 N_("net rpc registry deletevalue\n"
1284 " Delete a registry value")
1290 N_("Save a registry file"),
1291 N_("net rpc registry save\n"
1292 " Save a registry file")
1298 N_("Dump a registry file"),
1299 N_("net rpc registry dump\n"
1300 " Dump a registry file")
1306 N_("Copy a registry file"),
1307 N_("net rpc registry copy\n"
1308 " Copy a registry file")
1314 N_("Get security descriptor"),
1315 N_("net rpc registry getsd\n"
1316 " Get security descriptior")
1318 {NULL
, NULL
, 0, NULL
, NULL
}
1321 return net_run_function(c
, argc
, argv
, "net rpc registry", func
);