Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : RPC pipe client
4 :
5 : Copyright (C) Guenther Deschner 2009
6 :
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.
11 :
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.
16 :
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/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "rpcclient.h"
23 : #include "../librpc/gen_ndr/ndr_winreg_c.h"
24 : #include "../librpc/gen_ndr/ndr_misc.h"
25 :
26 0 : static WERROR cmd_winreg_enumkeys(struct rpc_pipe_client *cli,
27 : TALLOC_CTX *mem_ctx, int argc,
28 : const char **argv)
29 : {
30 : NTSTATUS status;
31 : WERROR werr;
32 : struct policy_handle handle;
33 0 : uint32_t enum_index = 0;
34 : struct winreg_StringBuf name;
35 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
36 :
37 0 : if (argc < 2) {
38 0 : printf("usage: %s [name]\n", argv[0]);
39 0 : return WERR_OK;
40 : }
41 :
42 0 : status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
43 : NULL,
44 : SEC_FLAG_MAXIMUM_ALLOWED,
45 : &handle,
46 : &werr);
47 0 : if (!NT_STATUS_IS_OK(status)) {
48 0 : return ntstatus_to_werror(status);
49 : }
50 0 : if (!W_ERROR_IS_OK(werr)) {
51 0 : return werr;
52 : }
53 :
54 0 : ZERO_STRUCT(name);
55 :
56 0 : name.name = argv[1];
57 0 : name.length = strlen_m_term_null(name.name)*2;
58 0 : name.size = name.length;
59 :
60 0 : status = dcerpc_winreg_EnumKey(b, mem_ctx,
61 : &handle,
62 : enum_index,
63 : &name,
64 : NULL,
65 : NULL,
66 : &werr);
67 0 : if (!NT_STATUS_IS_OK(status)) {
68 0 : return ntstatus_to_werror(status);
69 : }
70 0 : if (!W_ERROR_IS_OK(werr)) {
71 0 : return werr;
72 : }
73 :
74 0 : return WERR_OK;
75 : }
76 :
77 : /****************************************************************************
78 : ****************************************************************************/
79 :
80 0 : static WERROR pull_winreg_Data(TALLOC_CTX *mem_ctx,
81 : const DATA_BLOB *blob,
82 : union winreg_Data *data,
83 : enum winreg_Type type)
84 : {
85 : enum ndr_err_code ndr_err;
86 0 : ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
87 : (ndr_pull_flags_fn_t)ndr_pull_winreg_Data);
88 0 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
89 0 : return WERR_GEN_FAILURE;
90 : }
91 0 : return WERR_OK;
92 : }
93 :
94 : /****************************************************************************
95 : ****************************************************************************/
96 :
97 0 : static void display_winreg_data(const char *v,
98 : enum winreg_Type type,
99 : uint8_t *data,
100 : uint32_t length)
101 : {
102 : size_t i;
103 : union winreg_Data r;
104 0 : DATA_BLOB blob = data_blob_const(data, length);
105 : WERROR result;
106 :
107 0 : result = pull_winreg_Data(talloc_tos(), &blob, &r, type);
108 0 : if (!W_ERROR_IS_OK(result)) {
109 0 : return;
110 : }
111 :
112 0 : switch (type) {
113 0 : case REG_DWORD:
114 0 : printf("%-20s: REG_DWORD: 0x%08x\n", v, r.value);
115 0 : break;
116 0 : case REG_SZ:
117 0 : printf("%-20s: REG_SZ: %s\n", v, r.string);
118 0 : break;
119 0 : case REG_BINARY: {
120 0 : char *hex = hex_encode_talloc(NULL,
121 0 : r.binary.data, r.binary.length);
122 : size_t len;
123 0 : printf("%-20s: REG_BINARY:", v);
124 0 : len = strlen(hex);
125 0 : for (i=0; i<len; i++) {
126 0 : if (hex[i] == '\0') {
127 0 : break;
128 : }
129 0 : if (i%40 == 0) {
130 0 : putchar('\n');
131 : }
132 0 : putchar(hex[i]);
133 : }
134 0 : TALLOC_FREE(hex);
135 0 : putchar('\n');
136 0 : break;
137 : }
138 0 : case REG_MULTI_SZ:
139 0 : printf("%-20s: REG_MULTI_SZ: ", v);
140 0 : for (i=0; r.string_array[i] != NULL; i++) {
141 0 : printf("%s ", r.string_array[i]);
142 : }
143 0 : printf("\n");
144 0 : break;
145 0 : default:
146 0 : printf("%-20ss: unknown type 0x%02x:\n", v, type);
147 0 : break;
148 : }
149 : }
150 :
151 :
152 0 : static WERROR cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client *cli,
153 : TALLOC_CTX *mem_ctx, int argc,
154 : const char **argv, bool multiplevalues2)
155 : {
156 : NTSTATUS status;
157 : WERROR werr;
158 : struct policy_handle handle, key_handle;
159 0 : struct winreg_String key_name = { 0, };
160 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
161 :
162 : struct QueryMultipleValue *values_in, *values_out;
163 : uint32_t num_values;
164 0 : uint8_t *buffer = NULL;
165 : uint32_t i;
166 :
167 :
168 0 : if (argc < 2) {
169 0 : printf("usage: %s [key] [value1] [value2] ...\n", argv[0]);
170 0 : return WERR_OK;
171 : }
172 :
173 0 : status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
174 : NULL,
175 : SEC_FLAG_MAXIMUM_ALLOWED,
176 : &handle,
177 : &werr);
178 0 : if (!NT_STATUS_IS_OK(status)) {
179 0 : return ntstatus_to_werror(status);
180 : }
181 0 : if (!W_ERROR_IS_OK(werr)) {
182 0 : return werr;
183 : }
184 :
185 0 : key_name.name = argv[1];
186 :
187 0 : status = dcerpc_winreg_OpenKey(b, mem_ctx,
188 : &handle,
189 : key_name,
190 : 0, /* options */
191 : SEC_FLAG_MAXIMUM_ALLOWED,
192 : &key_handle,
193 : &werr);
194 0 : if (!NT_STATUS_IS_OK(status)) {
195 0 : return ntstatus_to_werror(status);
196 : }
197 0 : if (!W_ERROR_IS_OK(werr)) {
198 0 : return werr;
199 : }
200 :
201 0 : num_values = argc-2;
202 :
203 0 : values_in = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
204 0 : if (values_in == NULL) {
205 0 : return WERR_NOT_ENOUGH_MEMORY;
206 : }
207 :
208 0 : values_out = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values);
209 0 : if (values_out == NULL) {
210 0 : return WERR_NOT_ENOUGH_MEMORY;
211 : }
212 :
213 0 : for (i=0; i < num_values; i++) {
214 :
215 0 : values_in[i].ve_valuename = talloc_zero(values_in, struct winreg_ValNameBuf);
216 0 : if (values_in[i].ve_valuename == NULL) {
217 0 : return WERR_NOT_ENOUGH_MEMORY;
218 : }
219 :
220 0 : values_in[i].ve_valuename->name = talloc_strdup(values_in[i].ve_valuename, argv[i+2]);
221 0 : values_in[i].ve_valuename->length = strlen_m_term_null(values_in[i].ve_valuename->name)*2;
222 0 : values_in[i].ve_valuename->size = values_in[i].ve_valuename->length;
223 : }
224 :
225 0 : if (multiplevalues2) {
226 :
227 0 : uint32_t offered = 0, needed = 0;
228 :
229 0 : status = dcerpc_winreg_QueryMultipleValues2(b, mem_ctx,
230 : &key_handle,
231 : values_in,
232 : values_out,
233 : num_values,
234 : buffer,
235 : &offered,
236 : &needed,
237 : &werr);
238 0 : if (!NT_STATUS_IS_OK(status)) {
239 0 : return ntstatus_to_werror(status);
240 : }
241 0 : if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
242 0 : offered = needed;
243 :
244 0 : buffer = talloc_zero_array(mem_ctx, uint8_t, needed);
245 0 : if (buffer == NULL) {
246 0 : return WERR_NOT_ENOUGH_MEMORY;
247 : }
248 :
249 0 : status = dcerpc_winreg_QueryMultipleValues2(b, mem_ctx,
250 : &key_handle,
251 : values_in,
252 : values_out,
253 : num_values,
254 : buffer,
255 : &offered,
256 : &needed,
257 : &werr);
258 0 : if (!NT_STATUS_IS_OK(status)) {
259 0 : return ntstatus_to_werror(status);
260 : }
261 0 : if (!W_ERROR_IS_OK(werr)) {
262 0 : return werr;
263 : }
264 : }
265 :
266 : } else {
267 :
268 0 : uint32_t buffer_size = 0xff;
269 :
270 0 : buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_size);
271 0 : if (buffer == NULL) {
272 0 : return WERR_NOT_ENOUGH_MEMORY;
273 : }
274 :
275 0 : status = dcerpc_winreg_QueryMultipleValues(b, mem_ctx,
276 : &key_handle,
277 : values_in,
278 : values_out,
279 : num_values,
280 : buffer,
281 : &buffer_size,
282 : &werr);
283 0 : if (!NT_STATUS_IS_OK(status)) {
284 0 : return ntstatus_to_werror(status);
285 : }
286 0 : if (!W_ERROR_IS_OK(werr)) {
287 0 : return werr;
288 : }
289 : }
290 :
291 0 : for (i=0; i < num_values; i++) {
292 0 : if (buffer) {
293 0 : display_winreg_data(values_in[i].ve_valuename->name,
294 0 : values_out[i].ve_type,
295 0 : buffer + values_out[i].ve_valueptr,
296 0 : values_out[i].ve_valuelen);
297 : }
298 : }
299 :
300 0 : return WERR_OK;
301 : }
302 :
303 0 : static WERROR cmd_winreg_querymultiplevalues(struct rpc_pipe_client *cli,
304 : TALLOC_CTX *mem_ctx, int argc,
305 : const char **argv)
306 : {
307 0 : return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, false);
308 : }
309 :
310 0 : static WERROR cmd_winreg_querymultiplevalues2(struct rpc_pipe_client *cli,
311 : TALLOC_CTX *mem_ctx, int argc,
312 : const char **argv)
313 : {
314 0 : return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, true);
315 : }
316 :
317 0 : static WERROR cmd_winreg_enumval(struct rpc_pipe_client *cli,
318 : TALLOC_CTX *mem_ctx, int argc,
319 : const char **argv)
320 : {
321 : NTSTATUS status;
322 : WERROR werr, ignore;
323 0 : struct dcerpc_binding_handle *b = cli->binding_handle;
324 : struct policy_handle parent_handle, handle;
325 0 : uint32_t enum_index = 0;
326 :
327 0 : if (argc < 1 || argc > 3) {
328 0 : printf("usage: %s [name]\n", argv[0]);
329 0 : return WERR_OK;
330 : }
331 :
332 0 : status = dcerpc_winreg_OpenHKLM(b, mem_ctx,
333 : NULL,
334 : SEC_FLAG_MAXIMUM_ALLOWED,
335 : &parent_handle,
336 : &werr);
337 0 : if (!NT_STATUS_IS_OK(status)) {
338 0 : return ntstatus_to_werror(status);
339 : }
340 0 : if (!W_ERROR_IS_OK(werr)) {
341 0 : return werr;
342 : }
343 :
344 0 : if (argc >= 2) {
345 :
346 : struct winreg_String keyname;
347 :
348 0 : ZERO_STRUCT(keyname);
349 :
350 0 : keyname.name = argv[1];
351 :
352 0 : status = dcerpc_winreg_OpenKey(b, mem_ctx,
353 : &parent_handle,
354 : keyname,
355 : 0,
356 : SEC_FLAG_MAXIMUM_ALLOWED,
357 : &handle,
358 : &werr);
359 0 : if (!NT_STATUS_IS_OK(status)) {
360 0 : return ntstatus_to_werror(status);
361 : }
362 0 : if (!W_ERROR_IS_OK(werr)) {
363 0 : return werr;
364 : }
365 : } else {
366 0 : handle = parent_handle;
367 : }
368 :
369 : do {
370 : struct winreg_ValNameBuf name;
371 0 : enum winreg_Type type = REG_NONE;
372 0 : uint32_t size = 0, length = 0;
373 : struct winreg_EnumValue r;
374 :
375 0 : name.name = "";
376 0 : name.size = 1024;
377 :
378 0 : r.in.handle = &handle;
379 0 : r.in.enum_index = enum_index;
380 0 : r.in.name = &name;
381 0 : r.in.type = &type;
382 0 : r.in.size = &size;
383 0 : r.in.length = &length;
384 0 : r.in.value = talloc_array(mem_ctx, uint8_t, size);
385 0 : if (r.in.value == NULL) {
386 0 : werr = WERR_NOT_ENOUGH_MEMORY;
387 0 : goto done;
388 : }
389 0 : r.out.name = &name;
390 0 : r.out.type = &type;
391 0 : r.out.size = &size;
392 0 : r.out.length = &length;
393 0 : r.out.value = r.in.value;
394 :
395 0 : status = dcerpc_winreg_EnumValue_r(b, mem_ctx, &r);
396 0 : if (!NT_STATUS_IS_OK(status)) {
397 0 : werr = ntstatus_to_werror(status);
398 0 : goto done;
399 : }
400 :
401 0 : werr = r.out.result;
402 :
403 0 : if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) {
404 0 : *r.in.size = *r.out.size;
405 0 : r.in.value = talloc_zero_array(mem_ctx, uint8_t, *r.in.size);
406 0 : if (r.in.value == NULL) {
407 0 : werr = WERR_NOT_ENOUGH_MEMORY;
408 0 : goto done;
409 : }
410 :
411 0 : status = dcerpc_winreg_EnumValue_r(b, mem_ctx, &r);
412 0 : if (!NT_STATUS_IS_OK(status)) {
413 0 : werr = ntstatus_to_werror(status);
414 0 : goto done;
415 : }
416 :
417 0 : werr = r.out.result;
418 : }
419 0 : if (!W_ERROR_IS_OK(r.out.result)) {
420 0 : goto done;
421 : }
422 :
423 0 : printf("%02d: ", enum_index++);
424 :
425 0 : display_winreg_data(r.out.name->name,
426 0 : *r.out.type,
427 : r.out.value,
428 0 : *r.out.size);
429 :
430 0 : } while (W_ERROR_IS_OK(werr));
431 :
432 0 : done:
433 0 : if (argc >= 2) {
434 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &handle, &ignore);
435 : }
436 0 : dcerpc_winreg_CloseKey(b, mem_ctx, &parent_handle, &ignore);
437 :
438 0 : return werr;
439 : }
440 :
441 : /* List of commands exported by this module */
442 :
443 : struct cmd_set winreg_commands[] = {
444 :
445 : {
446 : .name = "WINREG",
447 : },
448 : {
449 : .name = "winreg_enumkey",
450 : .returntype = RPC_RTYPE_WERROR,
451 : .ntfn = NULL,
452 : .wfn = cmd_winreg_enumkeys,
453 : .table = &ndr_table_winreg,
454 : .rpc_pipe = NULL,
455 : .description = "Enumerate Keys",
456 : .usage = "",
457 : },
458 : {
459 : .name = "querymultiplevalues",
460 : .returntype = RPC_RTYPE_WERROR,
461 : .ntfn = NULL,
462 : .wfn = cmd_winreg_querymultiplevalues,
463 : .table = &ndr_table_winreg,
464 : .rpc_pipe = NULL,
465 : .description = "Query multiple values",
466 : .usage = "",
467 : },
468 : {
469 : .name = "querymultiplevalues2",
470 : .returntype = RPC_RTYPE_WERROR,
471 : .ntfn = NULL,
472 : .wfn = cmd_winreg_querymultiplevalues2,
473 : .table = &ndr_table_winreg,
474 : .rpc_pipe = NULL,
475 : .description = "Query multiple values",
476 : .usage = "",
477 : },
478 : {
479 : .name = "winreg_enumval",
480 : .returntype = RPC_RTYPE_WERROR,
481 : .ntfn = NULL,
482 : .wfn = cmd_winreg_enumval,
483 : .table = &ndr_table_winreg,
484 : .rpc_pipe = NULL,
485 : .description = "Enumerate Values",
486 : .usage = "",
487 : },
488 : {
489 : .name = NULL,
490 : },
491 : };
|