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;
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_zero(mem_ctx
, 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
= REG_NONE
;
112 WERROR result
= WERR_OK
;
113 uint32_t value_len
= 0;
114 uint32_t data_size
= 0;
121 status
= dcerpc_winreg_QueryValue(h
,
130 if (!NT_STATUS_IS_OK(status
)) {
133 if (!W_ERROR_IS_OK(result
)) {
138 if (type
!= REG_BINARY
) {
139 *pwerr
= WERR_INVALID_DATATYPE
;
143 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
144 if (blob
.data
== NULL
) {
150 status
= dcerpc_winreg_QueryValue(h
,
159 if (!NT_STATUS_IS_OK(status
)) {
162 if (!W_ERROR_IS_OK(result
)) {
168 data
->data
= blob
.data
;
169 data
->length
= blob
.length
;
175 NTSTATUS
dcerpc_winreg_query_multi_sz(TALLOC_CTX
*mem_ctx
,
176 struct dcerpc_binding_handle
*h
,
177 struct policy_handle
*key_handle
,
182 struct winreg_String wvalue
;
183 enum winreg_Type type
= REG_NONE
;
184 WERROR result
= WERR_OK
;
185 uint32_t value_len
= 0;
186 uint32_t data_size
= 0;
192 status
= dcerpc_winreg_QueryValue(h
,
201 if (!NT_STATUS_IS_OK(status
)) {
204 if (!W_ERROR_IS_OK(result
)) {
209 if (type
!= REG_MULTI_SZ
) {
210 *pwerr
= WERR_INVALID_DATATYPE
;
214 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
215 if (blob
.data
== NULL
) {
221 status
= dcerpc_winreg_QueryValue(h
,
230 if (!NT_STATUS_IS_OK(status
)) {
233 if (!W_ERROR_IS_OK(result
)) {
241 ok
= pull_reg_multi_sz(mem_ctx
, &blob
, data
);
250 NTSTATUS
dcerpc_winreg_query_sz(TALLOC_CTX
*mem_ctx
,
251 struct dcerpc_binding_handle
*h
,
252 struct policy_handle
*key_handle
,
257 struct winreg_String wvalue
;
258 enum winreg_Type type
= REG_NONE
;
259 WERROR result
= WERR_OK
;
260 uint32_t value_len
= 0;
261 uint32_t data_size
= 0;
267 status
= dcerpc_winreg_QueryValue(h
,
276 if (!NT_STATUS_IS_OK(status
)) {
279 if (!W_ERROR_IS_OK(result
)) {
284 if (type
!= REG_SZ
) {
285 *pwerr
= WERR_INVALID_DATATYPE
;
289 blob
= data_blob_talloc_zero(mem_ctx
, data_size
);
290 if (blob
.data
== NULL
) {
296 status
= dcerpc_winreg_QueryValue(h
,
305 if (!NT_STATUS_IS_OK(status
)) {
308 if (!W_ERROR_IS_OK(result
)) {
316 ok
= pull_reg_sz(mem_ctx
, &blob
, data
);
325 NTSTATUS
dcerpc_winreg_query_sd(TALLOC_CTX
*mem_ctx
,
326 struct dcerpc_binding_handle
*h
,
327 struct policy_handle
*key_handle
,
329 struct security_descriptor
**data
,
332 WERROR result
= WERR_OK
;
336 status
= dcerpc_winreg_query_binary(mem_ctx
,
342 if (!NT_STATUS_IS_OK(status
)) {
345 if (!W_ERROR_IS_OK(result
)) {
351 struct security_descriptor
*sd
;
352 enum ndr_err_code ndr_err
;
354 sd
= talloc_zero(mem_ctx
, struct security_descriptor
);
360 ndr_err
= ndr_pull_struct_blob(&blob
,
363 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
364 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
365 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
366 "security descriptor\n"));
377 NTSTATUS
dcerpc_winreg_set_dword(TALLOC_CTX
*mem_ctx
,
378 struct dcerpc_binding_handle
*h
,
379 struct policy_handle
*key_handle
,
384 struct winreg_String wvalue
;
386 WERROR result
= WERR_OK
;
391 blob
= data_blob_talloc_zero(mem_ctx
, 4);
392 SIVAL(blob
.data
, 0, data
);
394 status
= dcerpc_winreg_SetValue(h
,
402 if (!NT_STATUS_IS_OK(status
)) {
405 if (!W_ERROR_IS_OK(result
)) {
412 NTSTATUS
dcerpc_winreg_set_sz(TALLOC_CTX
*mem_ctx
,
413 struct dcerpc_binding_handle
*h
,
414 struct policy_handle
*key_handle
,
419 struct winreg_String wvalue
= { 0, };
421 WERROR result
= WERR_OK
;
426 blob
= data_blob_string_const("");
428 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
429 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
430 "string %s for %s\n",
437 status
= dcerpc_winreg_SetValue(h
,
445 if (!NT_STATUS_IS_OK(status
)) {
448 if (!W_ERROR_IS_OK(result
)) {
455 NTSTATUS
dcerpc_winreg_set_expand_sz(TALLOC_CTX
*mem_ctx
,
456 struct dcerpc_binding_handle
*h
,
457 struct policy_handle
*key_handle
,
462 struct winreg_String wvalue
= { 0, };
464 WERROR result
= WERR_OK
;
469 blob
= data_blob_string_const("");
471 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
472 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
473 "string %s for %s\n",
480 status
= dcerpc_winreg_SetValue(h
,
488 if (!NT_STATUS_IS_OK(status
)) {
491 if (!W_ERROR_IS_OK(result
)) {
498 NTSTATUS
dcerpc_winreg_set_multi_sz(TALLOC_CTX
*mem_ctx
,
499 struct dcerpc_binding_handle
*h
,
500 struct policy_handle
*key_handle
,
505 struct winreg_String wvalue
= { 0, };
507 WERROR result
= WERR_OK
;
511 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
512 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
513 "string multi sz for %s\n",
519 status
= dcerpc_winreg_SetValue(h
,
527 if (!NT_STATUS_IS_OK(status
)) {
530 if (!W_ERROR_IS_OK(result
)) {
537 NTSTATUS
dcerpc_winreg_set_binary(TALLOC_CTX
*mem_ctx
,
538 struct dcerpc_binding_handle
*h
,
539 struct policy_handle
*key_handle
,
544 struct winreg_String wvalue
= { 0, };
545 WERROR result
= WERR_OK
;
550 status
= dcerpc_winreg_SetValue(h
,
558 if (!NT_STATUS_IS_OK(status
)) {
561 if (!W_ERROR_IS_OK(result
)) {
568 NTSTATUS
dcerpc_winreg_set_sd(TALLOC_CTX
*mem_ctx
,
569 struct dcerpc_binding_handle
*h
,
570 struct policy_handle
*key_handle
,
572 const struct security_descriptor
*data
,
575 enum ndr_err_code ndr_err
;
578 ndr_err
= ndr_push_struct_blob(&blob
,
581 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
582 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
583 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
589 return dcerpc_winreg_set_binary(mem_ctx
,
597 NTSTATUS
dcerpc_winreg_add_multi_sz(TALLOC_CTX
*mem_ctx
,
598 struct dcerpc_binding_handle
*h
,
599 struct policy_handle
*key_handle
,
604 const char **a
= NULL
;
607 WERROR result
= WERR_OK
;
610 status
= dcerpc_winreg_query_multi_sz(mem_ctx
,
617 /* count the elements */
618 for (p
= a
, i
= 0; p
&& *p
; p
++, i
++);
620 p
= TALLOC_REALLOC_ARRAY(mem_ctx
, a
, const char *, i
+ 2);
629 status
= dcerpc_winreg_set_multi_sz(mem_ctx
,
639 NTSTATUS
dcerpc_winreg_enum_keys(TALLOC_CTX
*mem_ctx
,
640 struct dcerpc_binding_handle
*h
,
641 struct policy_handle
*key_hnd
,
642 uint32_t *pnum_subkeys
,
643 const char ***psubkeys
,
646 const char **subkeys
;
647 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
648 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
650 NTTIME last_changed_time
;
651 uint32_t secdescsize
;
652 struct winreg_String classname
;
653 WERROR result
= WERR_OK
;
657 tmp_ctx
= talloc_stackframe();
658 if (tmp_ctx
== NULL
) {
659 return NT_STATUS_NO_MEMORY
;
662 ZERO_STRUCT(classname
);
664 status
= dcerpc_winreg_QueryInfoKey(h
,
677 if (!NT_STATUS_IS_OK(status
)) {
680 if (!W_ERROR_IS_OK(result
)) {
685 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
686 if (subkeys
== NULL
) {
691 if (num_subkeys
== 0) {
692 subkeys
[0] = talloc_strdup(subkeys
, "");
693 if (subkeys
[0] == NULL
) {
699 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
702 TALLOC_FREE(tmp_ctx
);
706 for (i
= 0; i
< num_subkeys
; i
++) {
710 struct winreg_StringBuf class_buf
;
711 struct winreg_StringBuf name_buf
;
715 class_buf
.size
= max_classlen
+ 2;
716 class_buf
.length
= 0;
719 name_buf
.size
= max_subkeylen
+ 2;
722 ZERO_STRUCT(modtime
);
724 status
= dcerpc_winreg_EnumKey(h
,
732 if (!NT_STATUS_IS_OK(status
)) {
733 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
738 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
742 if (!W_ERROR_IS_OK(result
)) {
743 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
744 win_errstr(result
)));
749 if (name_buf
.name
== NULL
) {
750 *pwerr
= WERR_INVALID_PARAMETER
;
754 name
= talloc_strdup(subkeys
, name_buf
.name
);
763 *pnum_subkeys
= num_subkeys
;
765 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
769 TALLOC_FREE(tmp_ctx
);
774 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */