2 * Unix SMB/CIFS implementation.
4 * WINREG client routines
6 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../librpc/gen_ndr/ndr_winreg_c.h"
24 #include "../librpc/gen_ndr/ndr_security.h"
25 #include "rpc_client/cli_winreg.h"
26 #include "../libcli/registry/util_reg.h"
28 NTSTATUS
dcerpc_winreg_query_dword(TALLOC_CTX
*mem_ctx
,
29 struct dcerpc_binding_handle
*h
,
30 struct policy_handle
*key_handle
,
35 struct winreg_String wvalue
;
36 enum winreg_Type type
= REG_NONE
;
37 uint32_t value_len
= 0;
38 uint32_t data_size
= 0;
44 status
= dcerpc_winreg_QueryValue(h
,
53 if (!NT_STATUS_IS_OK(status
)) {
56 if (!W_ERROR_IS_OK(*pwerr
)) {
60 if (type
!= REG_DWORD
) {
61 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
65 return NT_STATUS_INVALID_PARAMETER
;
68 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
69 if (blob
.data
== NULL
) {
70 return NT_STATUS_NO_MEMORY
;
74 status
= dcerpc_winreg_QueryValue(h
,
83 if (!NT_STATUS_IS_OK(status
)) {
86 if (!W_ERROR_IS_OK(*pwerr
)) {
91 *data
= IVAL(blob
.data
, 0);
97 NTSTATUS
dcerpc_winreg_query_binary(TALLOC_CTX
*mem_ctx
,
98 struct dcerpc_binding_handle
*h
,
99 struct policy_handle
*key_handle
,
104 struct winreg_String wvalue
;
105 enum winreg_Type type
= REG_NONE
;
106 uint32_t value_len
= 0;
107 uint32_t data_size
= 0;
114 status
= dcerpc_winreg_QueryValue(h
,
123 if (!NT_STATUS_IS_OK(status
)) {
126 if (!W_ERROR_IS_OK(*pwerr
)) {
130 if (type
!= REG_BINARY
) {
131 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
134 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
135 if (blob
.data
== NULL
) {
136 return NT_STATUS_NO_MEMORY
;
140 status
= dcerpc_winreg_QueryValue(h
,
149 if (!NT_STATUS_IS_OK(status
)) {
152 if (!W_ERROR_IS_OK(*pwerr
)) {
157 data
->data
= blob
.data
;
158 data
->length
= blob
.length
;
164 NTSTATUS
dcerpc_winreg_query_multi_sz(TALLOC_CTX
*mem_ctx
,
165 struct dcerpc_binding_handle
*h
,
166 struct policy_handle
*key_handle
,
171 struct winreg_String wvalue
;
172 enum winreg_Type type
= REG_NONE
;
173 uint32_t value_len
= 0;
174 uint32_t data_size
= 0;
180 status
= dcerpc_winreg_QueryValue(h
,
189 if (!NT_STATUS_IS_OK(status
)) {
192 if (!W_ERROR_IS_OK(*pwerr
)) {
196 if (type
!= REG_MULTI_SZ
) {
197 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
200 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
201 if (blob
.data
== NULL
) {
202 return NT_STATUS_NO_MEMORY
;
206 status
= dcerpc_winreg_QueryValue(h
,
215 if (!NT_STATUS_IS_OK(status
)) {
218 if (!W_ERROR_IS_OK(*pwerr
)) {
225 ok
= pull_reg_multi_sz(mem_ctx
, &blob
, data
);
227 status
= NT_STATUS_NO_MEMORY
;
234 NTSTATUS
dcerpc_winreg_query_sz(TALLOC_CTX
*mem_ctx
,
235 struct dcerpc_binding_handle
*h
,
236 struct policy_handle
*key_handle
,
241 struct winreg_String wvalue
;
242 enum winreg_Type type
= REG_NONE
;
243 uint32_t value_len
= 0;
244 uint32_t data_size
= 0;
250 status
= dcerpc_winreg_QueryValue(h
,
259 if (!NT_STATUS_IS_OK(status
)) {
262 if (!W_ERROR_IS_OK(*pwerr
)) {
266 if (type
!= REG_SZ
) {
267 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
270 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
271 if (blob
.data
== NULL
) {
272 return NT_STATUS_NO_MEMORY
;
276 status
= dcerpc_winreg_QueryValue(h
,
285 if (!NT_STATUS_IS_OK(status
)) {
288 if (!W_ERROR_IS_OK(*pwerr
)) {
295 ok
= pull_reg_sz(mem_ctx
, &blob
, data
);
297 status
= NT_STATUS_NO_MEMORY
;
304 NTSTATUS
dcerpc_winreg_query_sd(TALLOC_CTX
*mem_ctx
,
305 struct dcerpc_binding_handle
*h
,
306 struct policy_handle
*key_handle
,
308 struct security_descriptor
**data
,
314 status
= dcerpc_winreg_query_binary(mem_ctx
,
320 if (!NT_STATUS_IS_OK(status
)) {
323 if (!W_ERROR_IS_OK(*pwerr
)) {
328 struct security_descriptor
*sd
;
329 enum ndr_err_code ndr_err
;
331 sd
= talloc_zero(mem_ctx
, struct security_descriptor
);
333 return NT_STATUS_NO_MEMORY
;
336 ndr_err
= ndr_pull_struct_blob(&blob
,
339 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
340 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
341 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
342 "security descriptor\n"));
343 return NT_STATUS_NO_MEMORY
;
352 NTSTATUS
dcerpc_winreg_set_dword(TALLOC_CTX
*mem_ctx
,
353 struct dcerpc_binding_handle
*h
,
354 struct policy_handle
*key_handle
,
359 struct winreg_String wvalue
;
365 blob
= data_blob_talloc_zero(mem_ctx
, 4);
366 SIVAL(blob
.data
, 0, data
);
368 status
= dcerpc_winreg_SetValue(h
,
380 NTSTATUS
dcerpc_winreg_set_sz(TALLOC_CTX
*mem_ctx
,
381 struct dcerpc_binding_handle
*h
,
382 struct policy_handle
*key_handle
,
387 struct winreg_String wvalue
= { 0, };
393 blob
= data_blob_string_const("");
395 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
396 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
397 "string %s for %s\n",
399 return NT_STATUS_NO_MEMORY
;
403 status
= dcerpc_winreg_SetValue(h
,
415 NTSTATUS
dcerpc_winreg_set_expand_sz(TALLOC_CTX
*mem_ctx
,
416 struct dcerpc_binding_handle
*h
,
417 struct policy_handle
*key_handle
,
422 struct winreg_String wvalue
= { 0, };
428 blob
= data_blob_string_const("");
430 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
431 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
432 "string %s for %s\n",
434 return NT_STATUS_NO_MEMORY
;
438 status
= dcerpc_winreg_SetValue(h
,
450 NTSTATUS
dcerpc_winreg_set_multi_sz(TALLOC_CTX
*mem_ctx
,
451 struct dcerpc_binding_handle
*h
,
452 struct policy_handle
*key_handle
,
457 struct winreg_String wvalue
= { 0, };
462 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
463 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
464 "string multi sz for %s\n",
466 return NT_STATUS_NO_MEMORY
;
469 status
= dcerpc_winreg_SetValue(h
,
481 NTSTATUS
dcerpc_winreg_set_binary(TALLOC_CTX
*mem_ctx
,
482 struct dcerpc_binding_handle
*h
,
483 struct policy_handle
*key_handle
,
488 struct winreg_String wvalue
= { 0, };
493 status
= dcerpc_winreg_SetValue(h
,
505 NTSTATUS
dcerpc_winreg_set_sd(TALLOC_CTX
*mem_ctx
,
506 struct dcerpc_binding_handle
*h
,
507 struct policy_handle
*key_handle
,
509 const struct security_descriptor
*data
,
512 enum ndr_err_code ndr_err
;
515 ndr_err
= ndr_push_struct_blob(&blob
,
518 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
519 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
520 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
522 return NT_STATUS_NO_MEMORY
;
525 return dcerpc_winreg_set_binary(mem_ctx
,
533 NTSTATUS
dcerpc_winreg_add_multi_sz(TALLOC_CTX
*mem_ctx
,
534 struct dcerpc_binding_handle
*h
,
535 struct policy_handle
*key_handle
,
540 const char **a
= NULL
;
545 status
= dcerpc_winreg_query_multi_sz(mem_ctx
,
552 /* count the elements */
553 for (p
= a
, i
= 0; p
&& *p
; p
++, i
++);
555 p
= talloc_realloc(mem_ctx
, a
, const char *, i
+ 2);
557 return NT_STATUS_NO_MEMORY
;
563 status
= dcerpc_winreg_set_multi_sz(mem_ctx
,
573 NTSTATUS
dcerpc_winreg_enum_keys(TALLOC_CTX
*mem_ctx
,
574 struct dcerpc_binding_handle
*h
,
575 struct policy_handle
*key_hnd
,
576 uint32_t *pnum_subkeys
,
577 const char ***psubkeys
,
580 const char **subkeys
;
581 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
582 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
584 NTTIME last_changed_time
;
585 uint32_t secdescsize
;
586 struct winreg_String classname
;
590 tmp_ctx
= talloc_stackframe();
591 if (tmp_ctx
== NULL
) {
592 return NT_STATUS_NO_MEMORY
;
595 ZERO_STRUCT(classname
);
597 status
= dcerpc_winreg_QueryInfoKey(h
,
610 if (!NT_STATUS_IS_OK(status
)) {
613 if (!W_ERROR_IS_OK(*pwerr
)) {
617 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
618 if (subkeys
== NULL
) {
619 status
= NT_STATUS_NO_MEMORY
;
623 if (num_subkeys
== 0) {
624 subkeys
[0] = talloc_strdup(subkeys
, "");
625 if (subkeys
[0] == NULL
) {
626 status
= NT_STATUS_NO_MEMORY
;
631 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
634 TALLOC_FREE(tmp_ctx
);
638 for (i
= 0; i
< num_subkeys
; i
++) {
642 struct winreg_StringBuf class_buf
;
643 struct winreg_StringBuf name_buf
;
647 class_buf
.size
= max_classlen
+ 2;
648 class_buf
.length
= 0;
651 name_buf
.size
= max_subkeylen
+ 2;
654 ZERO_STRUCT(modtime
);
656 status
= dcerpc_winreg_EnumKey(h
,
664 if (!NT_STATUS_IS_OK(status
)) {
665 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
670 if (W_ERROR_EQUAL(*pwerr
, WERR_NO_MORE_ITEMS
)) {
674 if (!W_ERROR_IS_OK(*pwerr
)) {
675 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
676 win_errstr(*pwerr
)));
680 if (name_buf
.name
== NULL
) {
681 *pwerr
= WERR_INVALID_PARAMETER
;
685 name
= talloc_strdup(subkeys
, name_buf
.name
);
687 status
= NT_STATUS_NO_MEMORY
;
694 *pnum_subkeys
= num_subkeys
;
696 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
700 TALLOC_FREE(tmp_ctx
);
705 NTSTATUS
dcerpc_winreg_enumvals(TALLOC_CTX
*mem_ctx
,
706 struct dcerpc_binding_handle
*h
,
707 struct policy_handle
*key_hnd
,
708 uint32_t *pnum_values
,
709 const char ***pnames
,
710 enum winreg_Type
**_type
,
714 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
715 uint32_t num_subkeys
= 0, max_subkeylen
= 0, max_classlen
= 0;
716 uint32_t num_values
= 0, max_valnamelen
= 0, max_valbufsize
= 0;
717 uint32_t secdescsize
= 0;
719 NTTIME last_changed_time
= 0;
720 struct winreg_String classname
= { .name
= NULL
};
722 const char **enum_names
= NULL
;
723 enum winreg_Type
*enum_types
= NULL
;
724 DATA_BLOB
*enum_data_blobs
= NULL
;
727 WERROR result
= WERR_OK
;
730 status
= dcerpc_winreg_QueryInfoKey(h
,
743 if (!NT_STATUS_IS_OK(status
)) {
744 DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
748 if (!W_ERROR_IS_OK(result
)) {
749 DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
750 win_errstr(result
)));
755 if (num_values
== 0) {
757 TALLOC_FREE(tmp_ctx
);
762 enum_names
= talloc_zero_array(tmp_ctx
, const char *, num_values
);
764 if (enum_names
== NULL
) {
765 *pwerr
= WERR_NOT_ENOUGH_MEMORY
;
769 enum_types
= talloc_zero_array(tmp_ctx
, enum winreg_Type
, num_values
);
771 if (enum_types
== NULL
) {
772 *pwerr
= WERR_NOT_ENOUGH_MEMORY
;
776 enum_data_blobs
= talloc_zero_array(tmp_ctx
, DATA_BLOB
, num_values
);
778 if (enum_data_blobs
== NULL
) {
779 *pwerr
= WERR_NOT_ENOUGH_MEMORY
;
783 for (i
= 0; i
< num_values
; i
++) {
785 struct winreg_ValNameBuf name_buf
;
786 enum winreg_Type type
= REG_NONE
;
794 name_buf
.size
= max_valnamelen
+ 2;
797 data_size
= max_valbufsize
;
800 data
= (uint8_t *) TALLOC(tmp_ctx
, data_size
);
804 status
= dcerpc_winreg_EnumValue(h
,
811 data_size
? &data_size
: NULL
,
814 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
816 status
= NT_STATUS_OK
;
820 if (!NT_STATUS_IS_OK(status
)) {
821 DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
825 if (!W_ERROR_IS_OK(result
)) {
826 DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
827 win_errstr(result
)));
832 if (name_buf
.name
== NULL
) {
833 result
= WERR_INVALID_PARAMETER
;
838 name
= talloc_strdup(enum_names
, name_buf
.name
);
840 result
= WERR_NOT_ENOUGH_MEMORY
;
844 /* place name, type and datablob in the enum return params */
846 enum_data_blobs
[i
] = data_blob_talloc(enum_data_blobs
, data
, length
);
847 enum_names
[i
] = name
;
848 enum_types
[i
] = type
;
851 /* move to the main mem context */
852 *pnum_values
= num_values
;
854 *pnames
= talloc_move(mem_ctx
, &enum_names
);
856 /* can this fail in any way? */
858 *_type
= talloc_move(mem_ctx
, &enum_types
);
862 *pdata
= talloc_move(mem_ctx
, &enum_data_blobs
);
869 TALLOC_FREE(tmp_ctx
);
875 NTSTATUS
dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX
*mem_ctx
,
876 struct dcerpc_binding_handle
*h
,
877 struct policy_handle
*hive_handle
,
878 uint32_t access_mask
,
882 const char **subkeys
= NULL
;
883 uint32_t num_subkeys
= 0;
884 struct policy_handle key_hnd
;
885 struct winreg_String wkey
= { 0, };
886 WERROR result
= WERR_OK
;
890 ZERO_STRUCT(key_hnd
);
893 DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key
));
895 status
= dcerpc_winreg_OpenKey(h
,
903 if (!NT_STATUS_IS_OK(status
)) {
904 DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
905 wkey
.name
, nt_errstr(status
)));
908 if (!W_ERROR_IS_OK(result
)) {
909 DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
910 wkey
.name
, win_errstr(result
)));
915 status
= dcerpc_winreg_enum_keys(mem_ctx
,
921 if (!NT_STATUS_IS_OK(status
)) {
924 if (!W_ERROR_IS_OK(result
)) {
928 for (i
= 0; i
< num_subkeys
; i
++) {
929 /* create key + subkey */
930 char *subkey
= talloc_asprintf(mem_ctx
, "%s\\%s", key
, subkeys
[i
]);
931 if (subkey
== NULL
) {
935 DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey
));
936 status
= dcerpc_winreg_delete_subkeys_recursive(mem_ctx
,
942 if (!W_ERROR_IS_OK(result
)) {
947 if (is_valid_policy_hnd(&key_hnd
)) {
949 dcerpc_winreg_CloseKey(h
, mem_ctx
, &key_hnd
, &ignore
);
954 status
= dcerpc_winreg_DeleteKey(h
,
959 if (!NT_STATUS_IS_OK(status
)) {
965 if (is_valid_policy_hnd(&key_hnd
)) {
968 dcerpc_winreg_CloseKey(h
, mem_ctx
, &key_hnd
, &ignore
);
975 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */