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(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: */