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"
27 NTSTATUS
dcerpc_winreg_query_dword(TALLOC_CTX
*mem_ctx
,
28 struct dcerpc_binding_handle
*h
,
29 struct policy_handle
*key_handle
,
34 struct winreg_String wvalue
;
35 enum winreg_Type type
;
36 uint32_t value_len
= 0;
37 uint32_t data_size
= 0;
38 WERROR result
= WERR_OK
;
44 status
= dcerpc_winreg_QueryValue(h
,
53 if (!NT_STATUS_IS_OK(status
)) {
56 if (!W_ERROR_IS_OK(result
)) {
61 if (type
!= REG_DWORD
) {
62 *pwerr
= WERR_INVALID_DATATYPE
;
67 *pwerr
= WERR_INVALID_DATA
;
71 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
72 if (blob
.data
== NULL
) {
78 status
= dcerpc_winreg_QueryValue(h
,
87 if (!NT_STATUS_IS_OK(status
)) {
90 if (!W_ERROR_IS_OK(result
)) {
96 *data
= IVAL(blob
.data
, 0);
102 NTSTATUS
dcerpc_winreg_query_binary(TALLOC_CTX
*mem_ctx
,
103 struct dcerpc_binding_handle
*h
,
104 struct policy_handle
*key_handle
,
109 struct winreg_String wvalue
;
110 enum winreg_Type type
;
111 WERROR result
= WERR_OK
;
112 uint32_t value_len
= 0;
113 uint32_t data_size
= 0;
119 status
= dcerpc_winreg_QueryValue(h
,
128 if (!NT_STATUS_IS_OK(status
)) {
131 if (!W_ERROR_IS_OK(result
)) {
136 if (type
!= REG_BINARY
) {
137 *pwerr
= WERR_INVALID_DATATYPE
;
141 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
142 if (blob
.data
== NULL
) {
148 status
= dcerpc_winreg_QueryValue(h
,
157 if (!NT_STATUS_IS_OK(status
)) {
160 if (!W_ERROR_IS_OK(result
)) {
166 data
->data
= blob
.data
;
167 data
->length
= blob
.length
;
173 NTSTATUS
dcerpc_winreg_query_multi_sz(TALLOC_CTX
*mem_ctx
,
174 struct dcerpc_binding_handle
*h
,
175 struct policy_handle
*key_handle
,
180 struct winreg_String wvalue
;
181 enum winreg_Type type
;
182 WERROR result
= WERR_OK
;
183 uint32_t value_len
= 0;
184 uint32_t data_size
= 0;
190 status
= dcerpc_winreg_QueryValue(h
,
199 if (!NT_STATUS_IS_OK(status
)) {
202 if (!W_ERROR_IS_OK(result
)) {
207 if (type
!= REG_MULTI_SZ
) {
208 *pwerr
= WERR_INVALID_DATATYPE
;
212 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
213 if (blob
.data
== NULL
) {
219 status
= dcerpc_winreg_QueryValue(h
,
228 if (!NT_STATUS_IS_OK(status
)) {
231 if (!W_ERROR_IS_OK(result
)) {
239 ok
= pull_reg_multi_sz(mem_ctx
, &blob
, data
);
248 NTSTATUS
dcerpc_winreg_query_sz(TALLOC_CTX
*mem_ctx
,
249 struct dcerpc_binding_handle
*h
,
250 struct policy_handle
*key_handle
,
255 struct winreg_String wvalue
;
256 enum winreg_Type type
;
257 WERROR result
= WERR_OK
;
258 uint32_t value_len
= 0;
259 uint32_t data_size
= 0;
265 status
= dcerpc_winreg_QueryValue(h
,
274 if (!NT_STATUS_IS_OK(status
)) {
277 if (!W_ERROR_IS_OK(result
)) {
282 if (type
!= REG_SZ
) {
283 *pwerr
= WERR_INVALID_DATATYPE
;
287 blob
= data_blob_talloc(mem_ctx
, NULL
, data_size
);
288 if (blob
.data
== NULL
) {
294 status
= dcerpc_winreg_QueryValue(h
,
303 if (!NT_STATUS_IS_OK(status
)) {
306 if (!W_ERROR_IS_OK(result
)) {
314 ok
= pull_reg_sz(mem_ctx
, &blob
, data
);
323 NTSTATUS
dcerpc_winreg_query_sd(TALLOC_CTX
*mem_ctx
,
324 struct dcerpc_binding_handle
*h
,
325 struct policy_handle
*key_handle
,
327 struct security_descriptor
**data
,
330 WERROR result
= WERR_OK
;
334 status
= dcerpc_winreg_query_binary(mem_ctx
,
340 if (!NT_STATUS_IS_OK(status
)) {
343 if (!W_ERROR_IS_OK(result
)) {
349 struct security_descriptor
*sd
;
350 enum ndr_err_code ndr_err
;
352 sd
= talloc_zero(mem_ctx
, struct security_descriptor
);
358 ndr_err
= ndr_pull_struct_blob(&blob
,
361 (ndr_pull_flags_fn_t
) ndr_pull_security_descriptor
);
362 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
363 DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
364 "security descriptor\n"));
375 NTSTATUS
dcerpc_winreg_set_dword(TALLOC_CTX
*mem_ctx
,
376 struct dcerpc_binding_handle
*h
,
377 struct policy_handle
*key_handle
,
382 struct winreg_String wvalue
= { 0, };
384 WERROR result
= WERR_OK
;
388 blob
= data_blob_talloc(mem_ctx
, NULL
, 4);
389 SIVAL(blob
.data
, 0, data
);
391 status
= dcerpc_winreg_SetValue(h
,
399 if (!NT_STATUS_IS_OK(status
)) {
402 if (!W_ERROR_IS_OK(result
)) {
409 NTSTATUS
dcerpc_winreg_set_sz(TALLOC_CTX
*mem_ctx
,
410 struct dcerpc_binding_handle
*h
,
411 struct policy_handle
*key_handle
,
416 struct winreg_String wvalue
= { 0, };
418 WERROR result
= WERR_OK
;
423 blob
= data_blob_string_const("");
425 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
426 DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
427 "string %s for %s\n",
434 status
= dcerpc_winreg_SetValue(h
,
442 if (!NT_STATUS_IS_OK(status
)) {
445 if (!W_ERROR_IS_OK(result
)) {
452 NTSTATUS
dcerpc_winreg_set_expand_sz(TALLOC_CTX
*mem_ctx
,
453 struct dcerpc_binding_handle
*h
,
454 struct policy_handle
*key_handle
,
459 struct winreg_String wvalue
= { 0, };
461 WERROR result
= WERR_OK
;
466 blob
= data_blob_string_const("");
468 if (!push_reg_sz(mem_ctx
, &blob
, data
)) {
469 DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
470 "string %s for %s\n",
477 status
= dcerpc_winreg_SetValue(h
,
485 if (!NT_STATUS_IS_OK(status
)) {
488 if (!W_ERROR_IS_OK(result
)) {
495 NTSTATUS
dcerpc_winreg_set_multi_sz(TALLOC_CTX
*mem_ctx
,
496 struct dcerpc_binding_handle
*h
,
497 struct policy_handle
*key_handle
,
502 struct winreg_String wvalue
;
504 WERROR result
= WERR_OK
;
508 if (!push_reg_multi_sz(mem_ctx
, &blob
, data
)) {
509 DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
510 "string multi sz for %s\n",
516 status
= dcerpc_winreg_SetValue(h
,
524 if (!NT_STATUS_IS_OK(status
)) {
527 if (!W_ERROR_IS_OK(result
)) {
534 NTSTATUS
dcerpc_winreg_set_binary(TALLOC_CTX
*mem_ctx
,
535 struct dcerpc_binding_handle
*h
,
536 struct policy_handle
*key_handle
,
541 struct winreg_String wvalue
= { 0, };
542 WERROR result
= WERR_OK
;
547 status
= dcerpc_winreg_SetValue(h
,
555 if (!NT_STATUS_IS_OK(status
)) {
558 if (!W_ERROR_IS_OK(result
)) {
565 NTSTATUS
dcerpc_winreg_set_sd(TALLOC_CTX
*mem_ctx
,
566 struct dcerpc_binding_handle
*h
,
567 struct policy_handle
*key_handle
,
569 const struct security_descriptor
*data
,
572 enum ndr_err_code ndr_err
;
575 ndr_err
= ndr_push_struct_blob(&blob
,
578 (ndr_push_flags_fn_t
) ndr_push_security_descriptor
);
579 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
580 DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
586 return dcerpc_winreg_set_binary(mem_ctx
,
594 NTSTATUS
dcerpc_winreg_add_multi_sz(TALLOC_CTX
*mem_ctx
,
595 struct dcerpc_binding_handle
*h
,
596 struct policy_handle
*key_handle
,
601 const char **a
= NULL
;
604 WERROR result
= WERR_OK
;
607 status
= dcerpc_winreg_query_multi_sz(mem_ctx
,
614 /* count the elements */
615 for (p
= a
, i
= 0; p
&& *p
; p
++, i
++);
617 p
= TALLOC_REALLOC_ARRAY(mem_ctx
, a
, const char *, i
+ 2);
626 status
= dcerpc_winreg_set_multi_sz(mem_ctx
,
636 NTSTATUS
dcerpc_winreg_enum_keys(TALLOC_CTX
*mem_ctx
,
637 struct dcerpc_binding_handle
*h
,
638 struct policy_handle
*key_hnd
,
639 uint32_t *pnum_subkeys
,
640 const char ***psubkeys
,
643 const char **subkeys
;
644 uint32_t num_subkeys
, max_subkeylen
, max_classlen
;
645 uint32_t num_values
, max_valnamelen
, max_valbufsize
;
647 NTTIME last_changed_time
;
648 uint32_t secdescsize
;
649 struct winreg_String classname
;
650 WERROR result
= WERR_OK
;
654 tmp_ctx
= talloc_stackframe();
655 if (tmp_ctx
== NULL
) {
656 return NT_STATUS_NO_MEMORY
;
659 ZERO_STRUCT(classname
);
661 status
= dcerpc_winreg_QueryInfoKey(h
,
674 if (!NT_STATUS_IS_OK(status
)) {
677 if (!W_ERROR_IS_OK(result
)) {
682 subkeys
= talloc_zero_array(tmp_ctx
, const char *, num_subkeys
+ 2);
683 if (subkeys
== NULL
) {
688 if (num_subkeys
== 0) {
689 subkeys
[0] = talloc_strdup(subkeys
, "");
690 if (subkeys
[0] == NULL
) {
696 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
699 TALLOC_FREE(tmp_ctx
);
703 for (i
= 0; i
< num_subkeys
; i
++) {
707 struct winreg_StringBuf class_buf
;
708 struct winreg_StringBuf name_buf
;
712 class_buf
.size
= max_classlen
+ 2;
713 class_buf
.length
= 0;
716 name_buf
.size
= max_subkeylen
+ 2;
719 ZERO_STRUCT(modtime
);
721 status
= dcerpc_winreg_EnumKey(h
,
729 if (!NT_STATUS_IS_OK(status
)) {
730 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
735 if (W_ERROR_EQUAL(result
, WERR_NO_MORE_ITEMS
) ) {
739 if (!W_ERROR_IS_OK(result
)) {
740 DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
741 win_errstr(result
)));
746 if (name_buf
.name
== NULL
) {
747 *pwerr
= WERR_INVALID_PARAMETER
;
751 name
= talloc_strdup(subkeys
, name_buf
.name
);
760 *pnum_subkeys
= num_subkeys
;
762 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
766 TALLOC_FREE(tmp_ctx
);
771 /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */