Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * WINREG client routines
5 : *
6 : * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
7 : *
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.
12 : *
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.
17 : *
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/>.
20 : */
21 :
22 : #include "includes.h"
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"
27 :
28 364 : NTSTATUS dcerpc_winreg_query_dword(TALLOC_CTX *mem_ctx,
29 : struct dcerpc_binding_handle *h,
30 : struct policy_handle *key_handle,
31 : const char *value,
32 : uint32_t *data,
33 : WERROR *pwerr)
34 : {
35 0 : struct winreg_String wvalue;
36 364 : enum winreg_Type type = REG_NONE;
37 364 : uint32_t value_len = 0;
38 364 : uint32_t data_size = 0;
39 0 : NTSTATUS status;
40 0 : DATA_BLOB blob;
41 :
42 364 : wvalue.name = value;
43 :
44 364 : status = dcerpc_winreg_QueryValue(h,
45 : mem_ctx,
46 : key_handle,
47 : &wvalue,
48 : &type,
49 : NULL,
50 : &data_size,
51 : &value_len,
52 : pwerr);
53 364 : if (!NT_STATUS_IS_OK(status)) {
54 0 : return status;
55 : }
56 364 : if (!W_ERROR_IS_OK(*pwerr)) {
57 0 : return status;
58 : }
59 :
60 364 : if (type != REG_DWORD) {
61 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
62 : }
63 :
64 364 : if (data_size != 4) {
65 0 : return NT_STATUS_INVALID_PARAMETER;
66 : }
67 :
68 364 : blob = data_blob_talloc_zero(mem_ctx, data_size);
69 364 : if (blob.data == NULL) {
70 0 : return NT_STATUS_NO_MEMORY;
71 : }
72 364 : value_len = 0;
73 :
74 364 : status = dcerpc_winreg_QueryValue(h,
75 : mem_ctx,
76 : key_handle,
77 : &wvalue,
78 : &type,
79 : blob.data,
80 : &data_size,
81 : &value_len,
82 : pwerr);
83 364 : if (!NT_STATUS_IS_OK(status)) {
84 0 : return status;
85 : }
86 364 : if (!W_ERROR_IS_OK(*pwerr)) {
87 0 : return status;
88 : }
89 :
90 364 : if (data) {
91 364 : *data = IVAL(blob.data, 0);
92 : }
93 :
94 364 : return status;
95 : }
96 :
97 21222 : NTSTATUS dcerpc_winreg_query_binary(TALLOC_CTX *mem_ctx,
98 : struct dcerpc_binding_handle *h,
99 : struct policy_handle *key_handle,
100 : const char *value,
101 : DATA_BLOB *data,
102 : WERROR *pwerr)
103 : {
104 0 : struct winreg_String wvalue;
105 21222 : enum winreg_Type type = REG_NONE;
106 21222 : uint32_t value_len = 0;
107 21222 : uint32_t data_size = 0;
108 0 : NTSTATUS status;
109 0 : DATA_BLOB blob;
110 :
111 21222 : ZERO_STRUCT(wvalue);
112 21222 : wvalue.name = value;
113 :
114 21222 : status = dcerpc_winreg_QueryValue(h,
115 : mem_ctx,
116 : key_handle,
117 : &wvalue,
118 : &type,
119 : NULL,
120 : &data_size,
121 : &value_len,
122 : pwerr);
123 21222 : if (!NT_STATUS_IS_OK(status)) {
124 0 : return status;
125 : }
126 21222 : if (!W_ERROR_IS_OK(*pwerr)) {
127 7590 : return status;
128 : }
129 :
130 13632 : if (type != REG_BINARY) {
131 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
132 : }
133 :
134 13632 : blob = data_blob_talloc_zero(mem_ctx, data_size);
135 13632 : if (blob.data == NULL) {
136 0 : return NT_STATUS_NO_MEMORY;
137 : }
138 13632 : value_len = 0;
139 :
140 13632 : status = dcerpc_winreg_QueryValue(h,
141 : mem_ctx,
142 : key_handle,
143 : &wvalue,
144 : &type,
145 : blob.data,
146 : &data_size,
147 : &value_len,
148 : pwerr);
149 13632 : if (!NT_STATUS_IS_OK(status)) {
150 0 : return status;
151 : }
152 13632 : if (!W_ERROR_IS_OK(*pwerr)) {
153 0 : return status;
154 : }
155 :
156 13632 : if (data) {
157 13632 : data->data = blob.data;
158 13632 : data->length = blob.length;
159 : }
160 :
161 13632 : return status;
162 : }
163 :
164 86 : NTSTATUS dcerpc_winreg_query_multi_sz(TALLOC_CTX *mem_ctx,
165 : struct dcerpc_binding_handle *h,
166 : struct policy_handle *key_handle,
167 : const char *value,
168 : const char ***data,
169 : WERROR *pwerr)
170 : {
171 0 : struct winreg_String wvalue;
172 86 : enum winreg_Type type = REG_NONE;
173 86 : uint32_t value_len = 0;
174 86 : uint32_t data_size = 0;
175 0 : NTSTATUS status;
176 0 : DATA_BLOB blob;
177 :
178 86 : wvalue.name = value;
179 :
180 86 : status = dcerpc_winreg_QueryValue(h,
181 : mem_ctx,
182 : key_handle,
183 : &wvalue,
184 : &type,
185 : NULL,
186 : &data_size,
187 : &value_len,
188 : pwerr);
189 86 : if (!NT_STATUS_IS_OK(status)) {
190 0 : return status;
191 : }
192 86 : if (!W_ERROR_IS_OK(*pwerr)) {
193 86 : return status;
194 : }
195 :
196 0 : if (type != REG_MULTI_SZ) {
197 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
198 : }
199 :
200 0 : blob = data_blob_talloc_zero(mem_ctx, data_size);
201 0 : if (blob.data == NULL) {
202 0 : return NT_STATUS_NO_MEMORY;
203 : }
204 0 : value_len = 0;
205 :
206 0 : status = dcerpc_winreg_QueryValue(h,
207 : mem_ctx,
208 : key_handle,
209 : &wvalue,
210 : &type,
211 : blob.data,
212 : &data_size,
213 : &value_len,
214 : pwerr);
215 0 : if (!NT_STATUS_IS_OK(status)) {
216 0 : return status;
217 : }
218 0 : if (!W_ERROR_IS_OK(*pwerr)) {
219 0 : return status;
220 : }
221 :
222 0 : if (data) {
223 0 : bool ok;
224 :
225 0 : ok = pull_reg_multi_sz(mem_ctx, &blob, data);
226 0 : if (!ok) {
227 0 : status = NT_STATUS_NO_MEMORY;
228 : }
229 : }
230 :
231 0 : return status;
232 : }
233 :
234 88 : NTSTATUS dcerpc_winreg_query_sz(TALLOC_CTX *mem_ctx,
235 : struct dcerpc_binding_handle *h,
236 : struct policy_handle *key_handle,
237 : const char *value,
238 : const char **data,
239 : WERROR *pwerr)
240 : {
241 0 : struct winreg_String wvalue;
242 88 : enum winreg_Type type = REG_NONE;
243 88 : uint32_t value_len = 0;
244 88 : uint32_t data_size = 0;
245 0 : NTSTATUS status;
246 0 : DATA_BLOB blob;
247 :
248 88 : wvalue.name = value;
249 :
250 88 : status = dcerpc_winreg_QueryValue(h,
251 : mem_ctx,
252 : key_handle,
253 : &wvalue,
254 : &type,
255 : NULL,
256 : &data_size,
257 : &value_len,
258 : pwerr);
259 88 : if (!NT_STATUS_IS_OK(status)) {
260 0 : return status;
261 : }
262 88 : if (!W_ERROR_IS_OK(*pwerr)) {
263 0 : return status;
264 : }
265 :
266 88 : if (type != REG_SZ) {
267 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
268 : }
269 :
270 88 : blob = data_blob_talloc_zero(mem_ctx, data_size);
271 88 : if (blob.data == NULL) {
272 0 : return NT_STATUS_NO_MEMORY;
273 : }
274 88 : value_len = 0;
275 :
276 88 : status = dcerpc_winreg_QueryValue(h,
277 : mem_ctx,
278 : key_handle,
279 : &wvalue,
280 : &type,
281 : blob.data,
282 : &data_size,
283 : &value_len,
284 : pwerr);
285 88 : if (!NT_STATUS_IS_OK(status)) {
286 0 : return status;
287 : }
288 88 : if (!W_ERROR_IS_OK(*pwerr)) {
289 0 : return status;
290 : }
291 :
292 88 : if (data) {
293 0 : bool ok;
294 :
295 88 : ok = pull_reg_sz(mem_ctx, &blob, data);
296 88 : if (!ok) {
297 0 : status = NT_STATUS_NO_MEMORY;
298 : }
299 : }
300 :
301 88 : return status;
302 : }
303 :
304 10724 : NTSTATUS dcerpc_winreg_query_sd(TALLOC_CTX *mem_ctx,
305 : struct dcerpc_binding_handle *h,
306 : struct policy_handle *key_handle,
307 : const char *value,
308 : struct security_descriptor **data,
309 : WERROR *pwerr)
310 : {
311 0 : NTSTATUS status;
312 0 : DATA_BLOB blob;
313 :
314 10724 : status = dcerpc_winreg_query_binary(mem_ctx,
315 : h,
316 : key_handle,
317 : value,
318 : &blob,
319 : pwerr);
320 10724 : if (!NT_STATUS_IS_OK(status)) {
321 0 : return status;
322 : }
323 10724 : if (!W_ERROR_IS_OK(*pwerr)) {
324 4 : return status;
325 : }
326 :
327 10720 : if (data) {
328 0 : struct security_descriptor *sd;
329 0 : enum ndr_err_code ndr_err;
330 :
331 10720 : sd = talloc_zero(mem_ctx, struct security_descriptor);
332 10720 : if (sd == NULL) {
333 0 : return NT_STATUS_NO_MEMORY;
334 : }
335 :
336 10720 : ndr_err = ndr_pull_struct_blob(&blob,
337 : sd,
338 : sd,
339 : (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
340 10720 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
341 0 : DEBUG(2, ("dcerpc_winreg_query_sd: Failed to marshall "
342 : "security descriptor\n"));
343 0 : return NT_STATUS_NO_MEMORY;
344 : }
345 :
346 10720 : *data = sd;
347 : }
348 :
349 10720 : return status;
350 : }
351 :
352 6496 : NTSTATUS dcerpc_winreg_set_dword(TALLOC_CTX *mem_ctx,
353 : struct dcerpc_binding_handle *h,
354 : struct policy_handle *key_handle,
355 : const char *value,
356 : uint32_t data,
357 : WERROR *pwerr)
358 : {
359 0 : struct winreg_String wvalue;
360 0 : DATA_BLOB blob;
361 0 : NTSTATUS status;
362 :
363 6496 : ZERO_STRUCT(wvalue);
364 6496 : wvalue.name = value;
365 6496 : blob = data_blob_talloc_zero(mem_ctx, 4);
366 6496 : SIVAL(blob.data, 0, data);
367 :
368 6496 : status = dcerpc_winreg_SetValue(h,
369 : mem_ctx,
370 : key_handle,
371 : wvalue,
372 : REG_DWORD,
373 : blob.data,
374 6496 : blob.length,
375 : pwerr);
376 :
377 6496 : return status;
378 : }
379 :
380 5354 : NTSTATUS dcerpc_winreg_set_sz(TALLOC_CTX *mem_ctx,
381 : struct dcerpc_binding_handle *h,
382 : struct policy_handle *key_handle,
383 : const char *value,
384 : const char *data,
385 : WERROR *pwerr)
386 : {
387 5354 : struct winreg_String wvalue = { 0, };
388 0 : DATA_BLOB blob;
389 0 : NTSTATUS status;
390 :
391 5354 : wvalue.name = value;
392 5354 : if (data == NULL) {
393 80 : blob = data_blob_string_const("");
394 : } else {
395 5274 : if (!push_reg_sz(mem_ctx, &blob, data)) {
396 0 : DEBUG(2, ("dcerpc_winreg_set_sz: Could not marshall "
397 : "string %s for %s\n",
398 : data, wvalue.name));
399 0 : return NT_STATUS_NO_MEMORY;
400 : }
401 : }
402 :
403 5354 : status = dcerpc_winreg_SetValue(h,
404 : mem_ctx,
405 : key_handle,
406 : wvalue,
407 : REG_SZ,
408 : blob.data,
409 5354 : blob.length,
410 : pwerr);
411 :
412 5354 : return status;
413 : }
414 :
415 172 : NTSTATUS dcerpc_winreg_set_expand_sz(TALLOC_CTX *mem_ctx,
416 : struct dcerpc_binding_handle *h,
417 : struct policy_handle *key_handle,
418 : const char *value,
419 : const char *data,
420 : WERROR *pwerr)
421 : {
422 172 : struct winreg_String wvalue = { 0, };
423 0 : DATA_BLOB blob;
424 0 : NTSTATUS status;
425 :
426 172 : wvalue.name = value;
427 172 : if (data == NULL) {
428 0 : blob = data_blob_string_const("");
429 : } else {
430 172 : if (!push_reg_sz(mem_ctx, &blob, data)) {
431 0 : DEBUG(2, ("dcerpc_winreg_set_expand_sz: Could not marshall "
432 : "string %s for %s\n",
433 : data, wvalue.name));
434 0 : return NT_STATUS_NO_MEMORY;
435 : }
436 : }
437 :
438 172 : status = dcerpc_winreg_SetValue(h,
439 : mem_ctx,
440 : key_handle,
441 : wvalue,
442 : REG_EXPAND_SZ,
443 : blob.data,
444 172 : blob.length,
445 : pwerr);
446 :
447 172 : return status;
448 : }
449 :
450 88 : NTSTATUS dcerpc_winreg_set_multi_sz(TALLOC_CTX *mem_ctx,
451 : struct dcerpc_binding_handle *h,
452 : struct policy_handle *key_handle,
453 : const char *value,
454 : const char **data,
455 : WERROR *pwerr)
456 : {
457 88 : struct winreg_String wvalue = { 0, };
458 0 : DATA_BLOB blob;
459 0 : NTSTATUS status;
460 :
461 88 : wvalue.name = value;
462 88 : if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
463 0 : DEBUG(2, ("dcerpc_winreg_set_multi_sz: Could not marshall "
464 : "string multi sz for %s\n",
465 : wvalue.name));
466 0 : return NT_STATUS_NO_MEMORY;
467 : }
468 :
469 88 : status = dcerpc_winreg_SetValue(h,
470 : mem_ctx,
471 : key_handle,
472 : wvalue,
473 : REG_MULTI_SZ,
474 : blob.data,
475 88 : blob.length,
476 : pwerr);
477 :
478 88 : return status;
479 : }
480 :
481 912 : NTSTATUS dcerpc_winreg_set_binary(TALLOC_CTX *mem_ctx,
482 : struct dcerpc_binding_handle *h,
483 : struct policy_handle *key_handle,
484 : const char *value,
485 : DATA_BLOB *data,
486 : WERROR *pwerr)
487 : {
488 912 : struct winreg_String wvalue = { 0, };
489 0 : NTSTATUS status;
490 :
491 912 : wvalue.name = value;
492 :
493 912 : status = dcerpc_winreg_SetValue(h,
494 : mem_ctx,
495 : key_handle,
496 : wvalue,
497 : REG_BINARY,
498 : data->data,
499 912 : data->length,
500 : pwerr);
501 :
502 912 : return status;
503 : }
504 :
505 640 : NTSTATUS dcerpc_winreg_set_sd(TALLOC_CTX *mem_ctx,
506 : struct dcerpc_binding_handle *h,
507 : struct policy_handle *key_handle,
508 : const char *value,
509 : const struct security_descriptor *data,
510 : WERROR *pwerr)
511 : {
512 0 : enum ndr_err_code ndr_err;
513 0 : DATA_BLOB blob;
514 :
515 640 : ndr_err = ndr_push_struct_blob(&blob,
516 : mem_ctx,
517 : data,
518 : (ndr_push_flags_fn_t) ndr_push_security_descriptor);
519 640 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
520 0 : DEBUG(2, ("dcerpc_winreg_set_sd: Failed to marshall security "
521 : "descriptor\n"));
522 0 : return NT_STATUS_NO_MEMORY;
523 : }
524 :
525 640 : return dcerpc_winreg_set_binary(mem_ctx,
526 : h,
527 : key_handle,
528 : value,
529 : &blob,
530 : pwerr);
531 : }
532 :
533 86 : NTSTATUS dcerpc_winreg_add_multi_sz(TALLOC_CTX *mem_ctx,
534 : struct dcerpc_binding_handle *h,
535 : struct policy_handle *key_handle,
536 : const char *value,
537 : const char *data,
538 : WERROR *pwerr)
539 : {
540 86 : const char **a = NULL;
541 0 : const char **p;
542 0 : uint32_t i;
543 0 : NTSTATUS status;
544 :
545 86 : status = dcerpc_winreg_query_multi_sz(mem_ctx,
546 : h,
547 : key_handle,
548 : value,
549 : &a,
550 : pwerr);
551 :
552 : /* count the elements */
553 86 : for (p = a, i = 0; p && *p; p++, i++);
554 :
555 86 : p = talloc_realloc(mem_ctx, a, const char *, i + 2);
556 86 : if (p == NULL) {
557 0 : return NT_STATUS_NO_MEMORY;
558 : }
559 :
560 86 : p[i] = data;
561 86 : p[i + 1] = NULL;
562 :
563 86 : status = dcerpc_winreg_set_multi_sz(mem_ctx,
564 : h,
565 : key_handle,
566 : value,
567 : p,
568 : pwerr);
569 :
570 86 : return status;
571 : }
572 :
573 5236 : NTSTATUS dcerpc_winreg_enum_keys(TALLOC_CTX *mem_ctx,
574 : struct dcerpc_binding_handle *h,
575 : struct policy_handle *key_hnd,
576 : uint32_t *pnum_subkeys,
577 : const char ***psubkeys,
578 : WERROR *pwerr)
579 : {
580 0 : const char **subkeys;
581 0 : uint32_t num_subkeys, max_subkeylen, max_classlen;
582 0 : uint32_t num_values, max_valnamelen, max_valbufsize;
583 0 : uint32_t i;
584 0 : NTTIME last_changed_time;
585 0 : uint32_t secdescsize;
586 0 : struct winreg_String classname;
587 0 : NTSTATUS status;
588 0 : TALLOC_CTX *tmp_ctx;
589 :
590 5236 : tmp_ctx = talloc_stackframe();
591 5236 : if (tmp_ctx == NULL) {
592 0 : return NT_STATUS_NO_MEMORY;
593 : }
594 :
595 5236 : ZERO_STRUCT(classname);
596 :
597 5236 : status = dcerpc_winreg_QueryInfoKey(h,
598 : tmp_ctx,
599 : key_hnd,
600 : &classname,
601 : &num_subkeys,
602 : &max_subkeylen,
603 : &max_classlen,
604 : &num_values,
605 : &max_valnamelen,
606 : &max_valbufsize,
607 : &secdescsize,
608 : &last_changed_time,
609 : pwerr);
610 5236 : if (!NT_STATUS_IS_OK(status)) {
611 0 : goto error;
612 : }
613 5236 : if (!W_ERROR_IS_OK(*pwerr)) {
614 0 : goto error;
615 : }
616 :
617 5236 : subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
618 5236 : if (subkeys == NULL) {
619 0 : status = NT_STATUS_NO_MEMORY;
620 0 : goto error;
621 : }
622 :
623 5236 : if (num_subkeys == 0) {
624 1960 : subkeys[0] = talloc_strdup(subkeys, "");
625 1960 : if (subkeys[0] == NULL) {
626 0 : status = NT_STATUS_NO_MEMORY;
627 0 : goto error;
628 : }
629 1960 : *pnum_subkeys = 0;
630 1960 : if (psubkeys) {
631 1960 : *psubkeys = talloc_move(mem_ctx, &subkeys);
632 : }
633 :
634 1960 : TALLOC_FREE(tmp_ctx);
635 1960 : return NT_STATUS_OK;
636 : }
637 :
638 69084 : for (i = 0; i < num_subkeys; i++) {
639 65808 : char c = '\0';
640 65808 : char n = '\0';
641 65808 : char *name = NULL;
642 0 : struct winreg_StringBuf class_buf;
643 0 : struct winreg_StringBuf name_buf;
644 0 : NTTIME modtime;
645 :
646 65808 : class_buf.name = &c;
647 65808 : class_buf.size = max_classlen + 2;
648 65808 : class_buf.length = 0;
649 :
650 65808 : name_buf.name = &n;
651 65808 : name_buf.size = max_subkeylen + 2;
652 65808 : name_buf.length = 0;
653 :
654 65808 : ZERO_STRUCT(modtime);
655 :
656 65808 : status = dcerpc_winreg_EnumKey(h,
657 : tmp_ctx,
658 : key_hnd,
659 : i,
660 : &name_buf,
661 : &class_buf,
662 : &modtime,
663 : pwerr);
664 65808 : if (!NT_STATUS_IS_OK(status)) {
665 0 : DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
666 : nt_errstr(status)));
667 0 : goto error;
668 : }
669 :
670 65808 : if (W_ERROR_EQUAL(*pwerr, WERR_NO_MORE_ITEMS)) {
671 0 : *pwerr = WERR_OK;
672 0 : break;
673 : }
674 65808 : if (!W_ERROR_IS_OK(*pwerr)) {
675 0 : DEBUG(5, ("dcerpc_winreg_enum_keys: Could not enumerate keys: %s\n",
676 : win_errstr(*pwerr)));
677 0 : goto error;
678 : }
679 :
680 65808 : if (name_buf.name == NULL) {
681 0 : *pwerr = WERR_INVALID_PARAMETER;
682 0 : goto error;
683 : }
684 :
685 65808 : name = talloc_strdup(subkeys, name_buf.name);
686 65808 : if (name == NULL) {
687 0 : status = NT_STATUS_NO_MEMORY;
688 0 : goto error;
689 : }
690 :
691 65808 : subkeys[i] = name;
692 : }
693 :
694 3276 : *pnum_subkeys = num_subkeys;
695 3276 : if (psubkeys) {
696 3276 : *psubkeys = talloc_move(mem_ctx, &subkeys);
697 : }
698 :
699 0 : error:
700 3276 : TALLOC_FREE(tmp_ctx);
701 :
702 3276 : return status;
703 : }
704 :
705 14998 : NTSTATUS dcerpc_winreg_enumvals(TALLOC_CTX *mem_ctx,
706 : struct dcerpc_binding_handle *h,
707 : struct policy_handle *key_hnd,
708 : uint32_t *pnum_values,
709 : const char ***pnames,
710 : enum winreg_Type **_type,
711 : DATA_BLOB **pdata,
712 : WERROR *pwerr)
713 : {
714 14998 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
715 14998 : uint32_t num_subkeys = 0, max_subkeylen = 0, max_classlen = 0;
716 14998 : uint32_t num_values = 0, max_valnamelen = 0, max_valbufsize = 0;
717 14998 : uint32_t secdescsize = 0;
718 0 : uint32_t i;
719 14998 : NTTIME last_changed_time = 0;
720 14998 : struct winreg_String classname = { .name = NULL };
721 :
722 14998 : const char **enum_names = NULL;
723 14998 : enum winreg_Type *enum_types = NULL;
724 14998 : DATA_BLOB *enum_data_blobs = NULL;
725 :
726 :
727 14998 : WERROR result = WERR_OK;
728 0 : NTSTATUS status;
729 :
730 14998 : status = dcerpc_winreg_QueryInfoKey(h,
731 : tmp_ctx,
732 : key_hnd,
733 : &classname,
734 : &num_subkeys,
735 : &max_subkeylen,
736 : &max_classlen,
737 : &num_values,
738 : &max_valnamelen,
739 : &max_valbufsize,
740 : &secdescsize,
741 : &last_changed_time,
742 : &result);
743 14998 : if (!NT_STATUS_IS_OK(status)) {
744 0 : DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
745 : nt_errstr(status)));
746 0 : goto error;
747 : }
748 14998 : if (!W_ERROR_IS_OK(result)) {
749 0 : DEBUG(0, ("dcerpc_winreg_enumvals: Could not query info: %s\n",
750 : win_errstr(result)));
751 0 : *pwerr = result;
752 0 : goto error;
753 : }
754 :
755 14998 : if (num_values == 0) {
756 840 : *pnum_values = 0;
757 840 : TALLOC_FREE(tmp_ctx);
758 840 : *pwerr = WERR_OK;
759 840 : return status;
760 : }
761 :
762 14158 : enum_names = talloc_zero_array(tmp_ctx, const char *, num_values);
763 :
764 14158 : if (enum_names == NULL) {
765 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
766 0 : goto error;
767 : }
768 :
769 14158 : enum_types = talloc_zero_array(tmp_ctx, enum winreg_Type, num_values);
770 :
771 14158 : if (enum_types == NULL) {
772 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
773 0 : goto error;
774 : }
775 :
776 14158 : enum_data_blobs = talloc_zero_array(tmp_ctx, DATA_BLOB, num_values);
777 :
778 14158 : if (enum_data_blobs == NULL) {
779 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
780 0 : goto error;
781 : }
782 :
783 204360 : for (i = 0; i < num_values; i++) {
784 0 : const char *name;
785 0 : struct winreg_ValNameBuf name_buf;
786 190202 : enum winreg_Type type = REG_NONE;
787 0 : uint8_t *data;
788 0 : uint32_t data_size;
789 0 : uint32_t length;
790 190202 : char n = '\0';
791 :
792 :
793 190202 : name_buf.name = &n;
794 190202 : name_buf.size = max_valnamelen + 2;
795 190202 : name_buf.length = 0;
796 :
797 190202 : data_size = max_valbufsize;
798 190202 : data = NULL;
799 190202 : if (data_size) {
800 190130 : data = (uint8_t *) TALLOC(tmp_ctx, data_size);
801 : }
802 190202 : length = 0;
803 :
804 190202 : status = dcerpc_winreg_EnumValue(h,
805 : tmp_ctx,
806 : key_hnd,
807 : i,
808 : &name_buf,
809 : &type,
810 : data,
811 190202 : data_size ? &data_size : NULL,
812 : &length,
813 : &result);
814 190202 : if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
815 0 : result = WERR_OK;
816 0 : status = NT_STATUS_OK;
817 0 : break;
818 : }
819 :
820 190202 : if (!NT_STATUS_IS_OK(status)) {
821 0 : DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
822 : nt_errstr(status)));
823 0 : goto error;
824 : }
825 190202 : if (!W_ERROR_IS_OK(result)) {
826 0 : DEBUG(0, ("dcerpc_winreg_enumvals: Could not enumerate values: %s\n",
827 : win_errstr(result)));
828 0 : *pwerr = result;
829 0 : goto error;
830 : }
831 :
832 190202 : if (name_buf.name == NULL) {
833 0 : result = WERR_INVALID_PARAMETER;
834 0 : *pwerr = result;
835 0 : goto error;
836 : }
837 :
838 190202 : name = talloc_strdup(enum_names, name_buf.name);
839 190202 : if (name == NULL) {
840 0 : result = WERR_NOT_ENOUGH_MEMORY;
841 0 : *pwerr = result;
842 0 : goto error;
843 : }
844 : /* place name, type and datablob in the enum return params */
845 :
846 190202 : enum_data_blobs[i] = data_blob_talloc(enum_data_blobs, data, length);
847 190202 : enum_names[i] = name;
848 190202 : enum_types[i] = type;
849 :
850 : }
851 : /* move to the main mem context */
852 14158 : *pnum_values = num_values;
853 14158 : if (pnames) {
854 14158 : *pnames = talloc_move(mem_ctx, &enum_names);
855 : }
856 : /* can this fail in any way? */
857 14158 : if (_type) {
858 14158 : *_type = talloc_move(mem_ctx, &enum_types);
859 : }
860 :
861 14158 : if (pdata){
862 14158 : *pdata = talloc_move(mem_ctx, &enum_data_blobs);
863 : }
864 :
865 :
866 14158 : result = WERR_OK;
867 :
868 14158 : error:
869 14158 : TALLOC_FREE(tmp_ctx);
870 14158 : *pwerr = result;
871 :
872 14158 : return status;
873 : }
874 :
875 954 : NTSTATUS dcerpc_winreg_delete_subkeys_recursive(TALLOC_CTX *mem_ctx,
876 : struct dcerpc_binding_handle *h,
877 : struct policy_handle *hive_handle,
878 : uint32_t access_mask,
879 : const char *key,
880 : WERROR *pwerr)
881 : {
882 954 : const char **subkeys = NULL;
883 954 : uint32_t num_subkeys = 0;
884 0 : struct policy_handle key_hnd;
885 954 : struct winreg_String wkey = { 0, };
886 954 : WERROR result = WERR_OK;
887 0 : NTSTATUS status;
888 0 : uint32_t i;
889 :
890 954 : ZERO_STRUCT(key_hnd);
891 954 : wkey.name = key;
892 :
893 954 : DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key));
894 : /* open the key */
895 954 : status = dcerpc_winreg_OpenKey(h,
896 : mem_ctx,
897 : hive_handle,
898 : wkey,
899 : 0,
900 : access_mask,
901 : &key_hnd,
902 : &result);
903 954 : if (!NT_STATUS_IS_OK(status)) {
904 0 : DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
905 : wkey.name, nt_errstr(status)));
906 0 : goto done;
907 : }
908 954 : if (!W_ERROR_IS_OK(result)) {
909 2 : DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
910 : wkey.name, win_errstr(result)));
911 2 : *pwerr = result;
912 2 : goto done;
913 : }
914 :
915 952 : status = dcerpc_winreg_enum_keys(mem_ctx,
916 : h,
917 : &key_hnd,
918 : &num_subkeys,
919 : &subkeys,
920 : &result);
921 952 : if (!NT_STATUS_IS_OK(status)) {
922 0 : goto done;
923 : }
924 952 : if (!W_ERROR_IS_OK(result)) {
925 0 : goto done;
926 : }
927 :
928 1640 : for (i = 0; i < num_subkeys; i++) {
929 : /* create key + subkey */
930 688 : char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
931 688 : if (subkey == NULL) {
932 0 : goto done;
933 : }
934 :
935 688 : DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey));
936 688 : status = dcerpc_winreg_delete_subkeys_recursive(mem_ctx,
937 : h,
938 : hive_handle,
939 : access_mask,
940 : subkey,
941 : &result);
942 688 : if (!W_ERROR_IS_OK(result)) {
943 0 : goto done;
944 : }
945 : }
946 :
947 952 : if (is_valid_policy_hnd(&key_hnd)) {
948 0 : WERROR ignore;
949 952 : dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
950 : }
951 :
952 952 : wkey.name = key;
953 :
954 952 : status = dcerpc_winreg_DeleteKey(h,
955 : mem_ctx,
956 : hive_handle,
957 : wkey,
958 : &result);
959 952 : if (!NT_STATUS_IS_OK(status)) {
960 0 : *pwerr = result;
961 0 : goto done;
962 : }
963 :
964 952 : done:
965 954 : if (is_valid_policy_hnd(&key_hnd)) {
966 0 : WERROR ignore;
967 :
968 0 : dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
969 : }
970 :
971 954 : *pwerr = result;
972 954 : return status;
973 : }
974 :
975 : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
|