2 Unix SMB/CIFS implementation.
5 Copyright (C) Guenther Deschner 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "rpcclient.h"
23 #include "../librpc/gen_ndr/ndr_winreg_c.h"
24 #include "../librpc/gen_ndr/ndr_misc.h"
26 static WERROR
cmd_winreg_enumkeys(struct rpc_pipe_client
*cli
,
27 TALLOC_CTX
*mem_ctx
, int argc
,
32 struct policy_handle handle
;
33 uint32_t enum_index
= 0;
34 struct winreg_StringBuf name
;
35 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
38 printf("usage: %s [name]\n", argv
[0]);
42 status
= dcerpc_winreg_OpenHKLM(b
, mem_ctx
,
44 SEC_FLAG_MAXIMUM_ALLOWED
,
47 if (!NT_STATUS_IS_OK(status
)) {
48 return ntstatus_to_werror(status
);
50 if (!W_ERROR_IS_OK(werr
)) {
57 name
.length
= strlen_m_term_null(name
.name
)*2;
58 name
.size
= name
.length
;
60 status
= dcerpc_winreg_EnumKey(b
, mem_ctx
,
67 if (!NT_STATUS_IS_OK(status
)) {
68 return ntstatus_to_werror(status
);
70 if (!W_ERROR_IS_OK(werr
)) {
77 /****************************************************************************
78 ****************************************************************************/
80 static WERROR
pull_winreg_Data(TALLOC_CTX
*mem_ctx
,
81 const DATA_BLOB
*blob
,
82 union winreg_Data
*data
,
83 enum winreg_Type type
)
85 enum ndr_err_code ndr_err
;
86 ndr_err
= ndr_pull_union_blob(blob
, mem_ctx
, data
, type
,
87 (ndr_pull_flags_fn_t
)ndr_pull_winreg_Data
);
88 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
89 return WERR_GEN_FAILURE
;
94 /****************************************************************************
95 ****************************************************************************/
97 static void display_winreg_data(const char *v
,
98 enum winreg_Type type
,
104 DATA_BLOB blob
= data_blob_const(data
, length
);
107 result
= pull_winreg_Data(talloc_tos(), &blob
, &r
, type
);
108 if (!W_ERROR_IS_OK(result
)) {
114 printf("%-20s: REG_DWORD: 0x%08x\n", v
, r
.value
);
117 printf("%-20s: REG_SZ: %s\n", v
, r
.string
);
120 char *hex
= hex_encode_talloc(NULL
,
121 r
.binary
.data
, r
.binary
.length
);
123 printf("%-20s: REG_BINARY:", v
);
125 for (i
=0; i
<len
; i
++) {
126 if (hex
[i
] == '\0') {
139 printf("%-20s: REG_MULTI_SZ: ", v
);
140 for (i
=0; r
.string_array
[i
] != NULL
; i
++) {
141 printf("%s ", r
.string_array
[i
]);
146 printf("%-20ss: unknown type 0x%02x:\n", v
, type
);
152 static WERROR
cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client
*cli
,
153 TALLOC_CTX
*mem_ctx
, int argc
,
154 const char **argv
, bool multiplevalues2
)
158 struct policy_handle handle
, key_handle
;
159 struct winreg_String key_name
= { 0, };
160 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
162 struct QueryMultipleValue
*values_in
, *values_out
;
164 uint8_t *buffer
= NULL
;
169 printf("usage: %s [key] [value1] [value2] ...\n", argv
[0]);
173 status
= dcerpc_winreg_OpenHKLM(b
, mem_ctx
,
175 SEC_FLAG_MAXIMUM_ALLOWED
,
178 if (!NT_STATUS_IS_OK(status
)) {
179 return ntstatus_to_werror(status
);
181 if (!W_ERROR_IS_OK(werr
)) {
185 key_name
.name
= argv
[1];
187 status
= dcerpc_winreg_OpenKey(b
, mem_ctx
,
191 SEC_FLAG_MAXIMUM_ALLOWED
,
194 if (!NT_STATUS_IS_OK(status
)) {
195 return ntstatus_to_werror(status
);
197 if (!W_ERROR_IS_OK(werr
)) {
203 values_in
= talloc_zero_array(mem_ctx
, struct QueryMultipleValue
, num_values
);
204 if (values_in
== NULL
) {
205 return WERR_NOT_ENOUGH_MEMORY
;
208 values_out
= talloc_zero_array(mem_ctx
, struct QueryMultipleValue
, num_values
);
209 if (values_out
== NULL
) {
210 return WERR_NOT_ENOUGH_MEMORY
;
213 for (i
=0; i
< num_values
; i
++) {
215 values_in
[i
].ve_valuename
= talloc_zero(values_in
, struct winreg_ValNameBuf
);
216 if (values_in
[i
].ve_valuename
== NULL
) {
217 return WERR_NOT_ENOUGH_MEMORY
;
220 values_in
[i
].ve_valuename
->name
= talloc_strdup(values_in
[i
].ve_valuename
, argv
[i
+2]);
221 values_in
[i
].ve_valuename
->length
= strlen_m_term_null(values_in
[i
].ve_valuename
->name
)*2;
222 values_in
[i
].ve_valuename
->size
= values_in
[i
].ve_valuename
->length
;
225 if (multiplevalues2
) {
227 uint32_t offered
= 0, needed
= 0;
229 status
= dcerpc_winreg_QueryMultipleValues2(b
, mem_ctx
,
238 if (!NT_STATUS_IS_OK(status
)) {
239 return ntstatus_to_werror(status
);
241 if (W_ERROR_EQUAL(werr
, WERR_MORE_DATA
)) {
244 buffer
= talloc_zero_array(mem_ctx
, uint8_t, needed
);
245 if (buffer
== NULL
) {
246 return WERR_NOT_ENOUGH_MEMORY
;
249 status
= dcerpc_winreg_QueryMultipleValues2(b
, mem_ctx
,
258 if (!NT_STATUS_IS_OK(status
)) {
259 return ntstatus_to_werror(status
);
261 if (!W_ERROR_IS_OK(werr
)) {
268 uint32_t buffer_size
= 0xff;
270 buffer
= talloc_zero_array(mem_ctx
, uint8_t, buffer_size
);
271 if (buffer
== NULL
) {
272 return WERR_NOT_ENOUGH_MEMORY
;
275 status
= dcerpc_winreg_QueryMultipleValues(b
, mem_ctx
,
283 if (!NT_STATUS_IS_OK(status
)) {
284 return ntstatus_to_werror(status
);
286 if (!W_ERROR_IS_OK(werr
)) {
291 for (i
=0; i
< num_values
; i
++) {
293 display_winreg_data(values_in
[i
].ve_valuename
->name
,
294 values_out
[i
].ve_type
,
295 buffer
+ values_out
[i
].ve_valueptr
,
296 values_out
[i
].ve_valuelen
);
303 static WERROR
cmd_winreg_querymultiplevalues(struct rpc_pipe_client
*cli
,
304 TALLOC_CTX
*mem_ctx
, int argc
,
307 return cmd_winreg_querymultiplevalues_ex(cli
, mem_ctx
, argc
, argv
, false);
310 static WERROR
cmd_winreg_querymultiplevalues2(struct rpc_pipe_client
*cli
,
311 TALLOC_CTX
*mem_ctx
, int argc
,
314 return cmd_winreg_querymultiplevalues_ex(cli
, mem_ctx
, argc
, argv
, true);
317 static WERROR
cmd_winreg_enumval(struct rpc_pipe_client
*cli
,
318 TALLOC_CTX
*mem_ctx
, int argc
,
323 struct dcerpc_binding_handle
*b
= cli
->binding_handle
;
324 struct policy_handle parent_handle
, handle
;
325 uint32_t enum_index
= 0;
327 if (argc
< 1 || argc
> 3) {
328 printf("usage: %s [name]\n", argv
[0]);
332 status
= dcerpc_winreg_OpenHKLM(b
, mem_ctx
,
334 SEC_FLAG_MAXIMUM_ALLOWED
,
337 if (!NT_STATUS_IS_OK(status
)) {
338 return ntstatus_to_werror(status
);
340 if (!W_ERROR_IS_OK(werr
)) {
346 struct winreg_String keyname
;
348 ZERO_STRUCT(keyname
);
350 keyname
.name
= argv
[1];
352 status
= dcerpc_winreg_OpenKey(b
, mem_ctx
,
356 SEC_FLAG_MAXIMUM_ALLOWED
,
359 if (!NT_STATUS_IS_OK(status
)) {
360 return ntstatus_to_werror(status
);
362 if (!W_ERROR_IS_OK(werr
)) {
366 handle
= parent_handle
;
370 struct winreg_ValNameBuf name
;
371 enum winreg_Type type
= REG_NONE
;
372 uint32_t size
= 0, length
= 0;
373 struct winreg_EnumValue r
;
378 r
.in
.handle
= &handle
;
379 r
.in
.enum_index
= enum_index
;
383 r
.in
.length
= &length
;
384 r
.in
.value
= talloc_array(mem_ctx
, uint8_t, size
);
385 if (r
.in
.value
== NULL
) {
386 werr
= WERR_NOT_ENOUGH_MEMORY
;
392 r
.out
.length
= &length
;
393 r
.out
.value
= r
.in
.value
;
395 status
= dcerpc_winreg_EnumValue_r(b
, mem_ctx
, &r
);
396 if (!NT_STATUS_IS_OK(status
)) {
397 werr
= ntstatus_to_werror(status
);
403 if (W_ERROR_EQUAL(werr
, WERR_MORE_DATA
)) {
404 *r
.in
.size
= *r
.out
.size
;
405 r
.in
.value
= talloc_zero_array(mem_ctx
, uint8_t, *r
.in
.size
);
406 if (r
.in
.value
== NULL
) {
407 werr
= WERR_NOT_ENOUGH_MEMORY
;
411 status
= dcerpc_winreg_EnumValue_r(b
, mem_ctx
, &r
);
412 if (!NT_STATUS_IS_OK(status
)) {
413 werr
= ntstatus_to_werror(status
);
419 if (!W_ERROR_IS_OK(r
.out
.result
)) {
423 printf("%02d: ", enum_index
++);
425 display_winreg_data(r
.out
.name
->name
,
430 } while (W_ERROR_IS_OK(werr
));
434 dcerpc_winreg_CloseKey(b
, mem_ctx
, &handle
, &ignore
);
436 dcerpc_winreg_CloseKey(b
, mem_ctx
, &parent_handle
, &ignore
);
441 /* List of commands exported by this module */
443 struct cmd_set winreg_commands
[] = {
449 .name
= "winreg_enumkey",
450 .returntype
= RPC_RTYPE_WERROR
,
452 .wfn
= cmd_winreg_enumkeys
,
453 .table
= &ndr_table_winreg
,
455 .description
= "Enumerate Keys",
459 .name
= "querymultiplevalues",
460 .returntype
= RPC_RTYPE_WERROR
,
462 .wfn
= cmd_winreg_querymultiplevalues
,
463 .table
= &ndr_table_winreg
,
465 .description
= "Query multiple values",
469 .name
= "querymultiplevalues2",
470 .returntype
= RPC_RTYPE_WERROR
,
472 .wfn
= cmd_winreg_querymultiplevalues2
,
473 .table
= &ndr_table_winreg
,
475 .description
= "Query multiple values",
479 .name
= "winreg_enumval",
480 .returntype
= RPC_RTYPE_WERROR
,
482 .wfn
= cmd_winreg_enumval
,
483 .table
= &ndr_table_winreg
,
485 .description
= "Enumerate Values",