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
;
37 uint32_t value_len
= 0;
38 uint32_t data_size
= 0;
39 WERROR result
= WERR_OK
;
45 status
= dcerpc_winreg_QueryValue(h
,
54 if (!NT_STATUS_IS_OK(status
)) {
57 if (!W_ERROR_IS_OK(result
)) {
62 if (type
!= REG_DWORD
) {
63 *pwerr
= WERR_INVALID_DATATYPE
;
68 *pwerr
= WERR_INVALID_DATA
;
72 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
73 if (blob
.data
== NULL
) {
79 status
= dcerpc_winreg_QueryValue(h
,
88 if (!NT_STATUS_IS_OK(status
)) {
91 if (!W_ERROR_IS_OK(result
)) {
97 *data
= IVAL(blob
.data
, 0);
103 NTSTATUS
dcerpc_winreg_query_binary(TALLOC_CTX
*mem_ctx
,
104 struct dcerpc_binding_handle
*h
,
105 struct policy_handle
*key_handle
,
110 struct winreg_String wvalue
;
111 enum winreg_Type type
;
112 WERROR result
= WERR_OK
;
113 uint32_t value_len
= 0;
114 uint32_t data_size
= 0;
120 status
= dcerpc_winreg_QueryValue(h
,
129 if (!NT_STATUS_IS_OK(status
)) {
132 if (!W_ERROR_IS_OK(result
)) {
137 if (type
!= REG_BINARY
) {
138 *pwerr
= WERR_INVALID_DATATYPE
;
142 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
143 if (blob
.data
== NULL
) {
149 status
= dcerpc_winreg_QueryValue(h
,
158 if (!NT_STATUS_IS_OK(status
)) {
161 if (!W_ERROR_IS_OK(result
)) {
167 data
->data
= blob
.data
;
168 data
->length
= blob
.length
;
174 NTSTATUS
dcerpc_winreg_query_multi_sz(TALLOC_CTX
*mem_ctx
,
175 struct dcerpc_binding_handle
*h
,
176 struct policy_handle
*key_handle
,
181 struct winreg_String wvalue
;
182 enum winreg_Type type
;
183 WERROR result
= WERR_OK
;
184 uint32_t value_len
= 0;
185 uint32_t data_size
= 0;
191 status
= dcerpc_winreg_QueryValue(h
,
200 if (!NT_STATUS_IS_OK(status
)) {
203 if (!W_ERROR_IS_OK(result
)) {
208 if (type
!= REG_MULTI_SZ
) {
209 *pwerr
= WERR_INVALID_DATATYPE
;
213 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
214 if (blob
.data
== NULL
) {
220 status
= dcerpc_winreg_QueryValue(h
,
229 if (!NT_STATUS_IS_OK(status
)) {
232 if (!W_ERROR_IS_OK(result
)) {
240 ok
= pull_reg_multi_sz(mem_ctx
, &blob
, data
);
249 NTSTATUS
dcerpc_winreg_query_sz(TALLOC_CTX
*mem_ctx
,
250 struct dcerpc_binding_handle
*h
,
251 struct policy_handle
*key_handle
,
256 struct winreg_String wvalue
;
257 enum winreg_Type type
;
258 WERROR result
= WERR_OK
;
259 uint32_t value_len
= 0;
260 uint32_t data_size
= 0;
266 status
= dcerpc_winreg_QueryValue(h
,
275 if (!NT_STATUS_IS_OK(status
)) {
278 if (!W_ERROR_IS_OK(result
)) {
283 if (type
!= REG_SZ
) {
284 *pwerr
= WERR_INVALID_DATATYPE
;
288 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
289 if (blob
.data
== NULL
) {
295 status
= dcerpc_winreg_QueryValue(h
,
304 if (!NT_STATUS_IS_OK(status
)) {
307 if (!W_ERROR_IS_OK(result
)) {
315 ok
= pull_reg_sz(mem_ctx
, &blob
, data
);
324 NTSTATUS
dcerpc_winreg_query_sd(TALLOC_CTX
*mem_ctx
,
325 struct dcerpc_binding_handle
*h
,
326 struct policy_handle
*key_handle
,
328 struct security_descriptor
**data
,
331 WERROR result
= WERR_OK
;
335 status
= dcerpc_winreg_query_binary(mem_ctx
,
341 if (!NT_STATUS_IS_OK(status
)) {
344 if (!W_ERROR_IS_OK(result
)) {
350 struct security_descriptor
*sd
;
351 enum ndr_err_code ndr_err
;
353 sd
= talloc_zero(mem_ctx
, struct security_descriptor
);
359 ndr_err
= ndr_pull_struct_blob(&blob
,
362 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
363 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
364 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
365 "security descriptor\n"));
376 NTSTATUS
dcerpc_winreg_set_dword(TALLOC_CTX
*mem_ctx
,
377 struct dcerpc_binding_handle
*h
,
378 struct policy_handle
*key_handle
,
383 struct winreg_String wvalue
= { 0, };
385 WERROR result
= WERR_OK
;
389 blob
= data_blob_talloc(mem_ctx
, NULL
, 4);
390 SIVAL(blob
.data
, 0, data
);
392 status
= dcerpc_winreg_SetValue(h
,
400 if (!NT_STATUS_IS_OK(status
)) {
403 if (!W_ERROR_IS_OK(result
)) {
410 NTSTATUS
dcerpc_winreg_set_sz(TALLOC_CTX
*mem_ctx
,
411 struct dcerpc_binding_handle
*h
,
412 struct policy_handle
*key_handle
,
417 struct winreg_String wvalue
= { 0, };
419 WERROR result
= WERR_OK
;
424 blob
= data_blob_string_const("");
426 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
427 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
428 "string %s for %s\n",
435 status
= dcerpc_winreg_SetValue(h
,
443 if (!NT_STATUS_IS_OK(status
)) {
446 if (!W_ERROR_IS_OK(result
)) {
453 NTSTATUS
dcerpc_winreg_set_expand_sz(TALLOC_CTX
*mem_ctx
,
454 struct dcerpc_binding_handle
*h
,
455 struct policy_handle
*key_handle
,
460 struct winreg_String wvalue
= { 0, };
462 WERROR result
= WERR_OK
;
467 blob
= data_blob_string_const("");
469 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
470 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
471 "string %s for %s\n",
478 status
= dcerpc_winreg_SetValue(h
,
486 if (!NT_STATUS_IS_OK(status
)) {
489 if (!W_ERROR_IS_OK(result
)) {
496 NTSTATUS
dcerpc_winreg_set_multi_sz(TALLOC_CTX
*mem_ctx
,
497 struct dcerpc_binding_handle
*h
,
498 struct policy_handle
*key_handle
,
503 struct winreg_String wvalue
= { 0, };
505 WERROR result
= WERR_OK
;
509 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
510 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
511 "string multi sz for %s\n",
517 status
= dcerpc_winreg_SetValue(h
,
525 if (!NT_STATUS_IS_OK(status
)) {
528 if (!W_ERROR_IS_OK(result
)) {
535 NTSTATUS
dcerpc_winreg_set_binary(TALLOC_CTX
*mem_ctx
,
536 struct dcerpc_binding_handle
*h
,
537 struct policy_handle
*key_handle
,
542 struct winreg_String wvalue
= { 0, };
543 WERROR result
= WERR_OK
;
548 status
= dcerpc_winreg_SetValue(h
,
556 if (!NT_STATUS_IS_OK(status
)) {
559 if (!W_ERROR_IS_OK(result
)) {
566 NTSTATUS
dcerpc_winreg_set_sd(TALLOC_CTX
*mem_ctx
,
567 struct dcerpc_binding_handle
*h
,
568 struct policy_handle
*key_handle
,
570 const struct security_descriptor
*data
,
573 enum ndr_err_code ndr_err
;
576 ndr_err
= ndr_push_struct_blob(&blob
,
579 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
580 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
581 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
587 return dcerpc_winreg_set_binary(mem_ctx
,
595 NTSTATUS
dcerpc_winreg_add_multi_sz(TALLOC_CTX
*mem_ctx
,
596 struct dcerpc_binding_handle
*h
,
597 struct policy_handle
*key_handle
,
602 const char **a
= NULL
;
605 WERROR result
= WERR_OK
;
608 status
= dcerpc_winreg_query_multi_sz(mem_ctx
,
615 /* count the elements */
616 for (p
= a
, i
= 0; p
&& *p
; p
++, i
++);
618 p
= TALLOC_REALLOC_ARRAY(mem_ctx
, a
, const char *, i
+ 2);
627 status
= dcerpc_winreg_set_multi_sz(mem_ctx
,
637 NTSTATUS
dcerpc_winreg_enum_keys(TALLOC_CTX
*mem_ctx
,
638 struct dcerpc_binding_handle
*h
,
639 struct policy_handle
*key_hnd
,
640 uint32_t *pnum_subkeys
,
641 const char ***psubkeys
,
644 const char **subkeys
;
645 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
646 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
648 NTTIME last_changed_time
;
649 uint32_t secdescsize
;
650 struct winreg_String classname
;
651 WERROR result
= WERR_OK
;
655 tmp_ctx
= talloc_stackframe();
656 if (tmp_ctx
== NULL
) {
657 return NT_STATUS_NO_MEMORY
;
660 ZERO_STRUCT(classname
);
662 status
= dcerpc_winreg_QueryInfoKey(h
,
675 if (!NT_STATUS_IS_OK(status
)) {
678 if (!W_ERROR_IS_OK(result
)) {
683 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
684 if (subkeys
== NULL
) {
689 if (num_subkeys
== 0) {
690 subkeys
[0] = talloc_strdup(subkeys
, "");
691 if (subkeys
[0] == NULL
) {
697 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
700 TALLOC_FREE(tmp_ctx
);
704 for (i
= 0; i
< num_subkeys
; i
++) {
708 struct winreg_StringBuf class_buf
;
709 struct winreg_StringBuf name_buf
;
713 class_buf
.size
= max_classlen
+ 2;
714 class_buf
.length
= 0;
717 name_buf
.size
= max_subkeylen
+ 2;
720 ZERO_STRUCT(modtime
);
722 status
= dcerpc_winreg_EnumKey(h
,
730 if (!NT_STATUS_IS_OK(status
)) {
731 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
736 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
740 if (!W_ERROR_IS_OK(result
)) {
741 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
742 win_errstr(result
)));
747 if (name_buf
.name
== NULL
) {
748 *pwerr
= WERR_INVALID_PARAMETER
;
752 name
= talloc_strdup(subkeys
, name_buf
.name
);
761 *pnum_subkeys
= num_subkeys
;
763 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
767 TALLOC_FREE(tmp_ctx
);
772 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */