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 0 : 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 : struct winreg_String wvalue;
36 0 : enum winreg_Type type = REG_NONE;
37 0 : uint32_t value_len = 0;
38 0 : uint32_t data_size = 0;
39 : NTSTATUS status;
40 : DATA_BLOB blob;
41 :
42 0 : wvalue.name = value;
43 :
44 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
54 0 : return status;
55 : }
56 0 : if (!W_ERROR_IS_OK(*pwerr)) {
57 0 : return status;
58 : }
59 :
60 0 : if (type != REG_DWORD) {
61 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
62 : }
63 :
64 0 : if (data_size != 4) {
65 0 : return NT_STATUS_INVALID_PARAMETER;
66 : }
67 :
68 0 : blob = data_blob_talloc_zero(mem_ctx, data_size);
69 0 : if (blob.data == NULL) {
70 0 : return NT_STATUS_NO_MEMORY;
71 : }
72 0 : value_len = 0;
73 :
74 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
84 0 : return status;
85 : }
86 0 : if (!W_ERROR_IS_OK(*pwerr)) {
87 0 : return status;
88 : }
89 :
90 0 : if (data) {
91 0 : *data = IVAL(blob.data, 0);
92 : }
93 :
94 0 : return status;
95 : }
96 :
97 0 : 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 : struct winreg_String wvalue;
105 0 : enum winreg_Type type = REG_NONE;
106 0 : uint32_t value_len = 0;
107 0 : uint32_t data_size = 0;
108 : NTSTATUS status;
109 : DATA_BLOB blob;
110 :
111 0 : ZERO_STRUCT(wvalue);
112 0 : wvalue.name = value;
113 :
114 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
124 0 : return status;
125 : }
126 0 : if (!W_ERROR_IS_OK(*pwerr)) {
127 0 : return status;
128 : }
129 :
130 0 : if (type != REG_BINARY) {
131 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
132 : }
133 :
134 0 : blob = data_blob_talloc_zero(mem_ctx, data_size);
135 0 : if (blob.data == NULL) {
136 0 : return NT_STATUS_NO_MEMORY;
137 : }
138 0 : value_len = 0;
139 :
140 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
150 0 : return status;
151 : }
152 0 : if (!W_ERROR_IS_OK(*pwerr)) {
153 0 : return status;
154 : }
155 :
156 0 : if (data) {
157 0 : data->data = blob.data;
158 0 : data->length = blob.length;
159 : }
160 :
161 0 : return status;
162 : }
163 :
164 36 : 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 : struct winreg_String wvalue;
172 36 : enum winreg_Type type = REG_NONE;
173 36 : uint32_t value_len = 0;
174 36 : uint32_t data_size = 0;
175 : NTSTATUS status;
176 : DATA_BLOB blob;
177 :
178 36 : wvalue.name = value;
179 :
180 36 : 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 36 : if (!NT_STATUS_IS_OK(status)) {
190 0 : return status;
191 : }
192 36 : if (!W_ERROR_IS_OK(*pwerr)) {
193 36 : 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 : 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 0 : 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 : struct winreg_String wvalue;
242 0 : enum winreg_Type type = REG_NONE;
243 0 : uint32_t value_len = 0;
244 0 : uint32_t data_size = 0;
245 : NTSTATUS status;
246 : DATA_BLOB blob;
247 :
248 0 : wvalue.name = value;
249 :
250 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
260 0 : return status;
261 : }
262 0 : if (!W_ERROR_IS_OK(*pwerr)) {
263 0 : return status;
264 : }
265 :
266 0 : if (type != REG_SZ) {
267 0 : return NT_STATUS_OBJECT_TYPE_MISMATCH;
268 : }
269 :
270 0 : blob = data_blob_talloc_zero(mem_ctx, data_size);
271 0 : if (blob.data == NULL) {
272 0 : return NT_STATUS_NO_MEMORY;
273 : }
274 0 : value_len = 0;
275 :
276 0 : 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 0 : if (!NT_STATUS_IS_OK(status)) {
286 0 : return status;
287 : }
288 0 : if (!W_ERROR_IS_OK(*pwerr)) {
289 0 : return status;
290 : }
291 :
292 0 : if (data) {
293 : bool ok;
294 :
295 0 : ok = pull_reg_sz(mem_ctx, &blob, data);
296 0 : if (!ok) {
297 0 : status = NT_STATUS_NO_MEMORY;
298 : }
299 : }
300 :
301 0 : return status;
302 : }
303 :
304 0 : 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 : NTSTATUS status;
312 : DATA_BLOB blob;
313 :
314 0 : status = dcerpc_winreg_query_binary(mem_ctx,
315 : h,
316 : key_handle,
317 : value,
318 : &blob,
319 : pwerr);
320 0 : if (!NT_STATUS_IS_OK(status)) {
321 0 : return status;
322 : }
323 0 : if (!W_ERROR_IS_OK(*pwerr)) {
324 0 : return status;
325 : }
326 :
327 0 : if (data) {
328 : struct security_descriptor *sd;
329 : enum ndr_err_code ndr_err;
330 :
331 0 : sd = talloc_zero(mem_ctx, struct security_descriptor);
332 0 : if (sd == NULL) {
333 0 : return NT_STATUS_NO_MEMORY;
334 : }
335 :
336 0 : ndr_err = ndr_pull_struct_blob(&blob,
337 : sd,
338 : sd,
339 : (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
340 0 : 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 0 : *data = sd;
347 : }
348 :
349 0 : return status;
350 : }
351 :
352 456 : 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 : struct winreg_String wvalue;
360 : DATA_BLOB blob;
361 : NTSTATUS status;
362 :
363 456 : ZERO_STRUCT(wvalue);
364 456 : wvalue.name = value;
365 456 : blob = data_blob_talloc_zero(mem_ctx, 4);
366 456 : SIVAL(blob.data, 0, data);
367 :
368 456 : status = dcerpc_winreg_SetValue(h,
369 : mem_ctx,
370 : key_handle,
371 : wvalue,
372 : REG_DWORD,
373 : blob.data,
374 456 : blob.length,
375 : pwerr);
376 :
377 456 : return status;
378 : }
379 :
380 500 : 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 500 : struct winreg_String wvalue = { 0, };
388 : DATA_BLOB blob;
389 : NTSTATUS status;
390 :
391 500 : wvalue.name = value;
392 500 : if (data == NULL) {
393 0 : blob = data_blob_string_const("");
394 : } else {
395 500 : 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 500 : status = dcerpc_winreg_SetValue(h,
404 : mem_ctx,
405 : key_handle,
406 : wvalue,
407 : REG_SZ,
408 : blob.data,
409 500 : blob.length,
410 : pwerr);
411 :
412 500 : return status;
413 : }
414 :
415 72 : 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 72 : struct winreg_String wvalue = { 0, };
423 : DATA_BLOB blob;
424 : NTSTATUS status;
425 :
426 72 : wvalue.name = value;
427 72 : if (data == NULL) {
428 0 : blob = data_blob_string_const("");
429 : } else {
430 72 : 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 72 : status = dcerpc_winreg_SetValue(h,
439 : mem_ctx,
440 : key_handle,
441 : wvalue,
442 : REG_EXPAND_SZ,
443 : blob.data,
444 72 : blob.length,
445 : pwerr);
446 :
447 72 : return status;
448 : }
449 :
450 36 : 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 36 : struct winreg_String wvalue = { 0, };
458 : DATA_BLOB blob;
459 : NTSTATUS status;
460 :
461 36 : wvalue.name = value;
462 36 : 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 36 : status = dcerpc_winreg_SetValue(h,
470 : mem_ctx,
471 : key_handle,
472 : wvalue,
473 : REG_MULTI_SZ,
474 : blob.data,
475 36 : blob.length,
476 : pwerr);
477 :
478 36 : return status;
479 : }
480 :
481 116 : 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 116 : struct winreg_String wvalue = { 0, };
489 : NTSTATUS status;
490 :
491 116 : wvalue.name = value;
492 :
493 116 : status = dcerpc_winreg_SetValue(h,
494 : mem_ctx,
495 : key_handle,
496 : wvalue,
497 : REG_BINARY,
498 : data->data,
499 116 : data->length,
500 : pwerr);
501 :
502 116 : return status;
503 : }
504 :
505 116 : 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 : enum ndr_err_code ndr_err;
513 : DATA_BLOB blob;
514 :
515 116 : ndr_err = ndr_push_struct_blob(&blob,
516 : mem_ctx,
517 : data,
518 : (ndr_push_flags_fn_t) ndr_push_security_descriptor);
519 116 : 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 116 : return dcerpc_winreg_set_binary(mem_ctx,
526 : h,
527 : key_handle,
528 : value,
529 : &blob,
530 : pwerr);
531 : }
532 :
533 36 : 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 36 : const char **a = NULL;
541 : const char **p;
542 : uint32_t i;
543 : NTSTATUS status;
544 :
545 36 : 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 36 : for (p = a, i = 0; p && *p; p++, i++);
554 :
555 36 : p = talloc_realloc(mem_ctx, a, const char *, i + 2);
556 36 : if (p == NULL) {
557 0 : return NT_STATUS_NO_MEMORY;
558 : }
559 :
560 36 : p[i] = data;
561 36 : p[i + 1] = NULL;
562 :
563 36 : status = dcerpc_winreg_set_multi_sz(mem_ctx,
564 : h,
565 : key_handle,
566 : value,
567 : p,
568 : pwerr);
569 :
570 36 : return status;
571 : }
572 :
573 58 : 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 : const char **subkeys;
581 : uint32_t num_subkeys, max_subkeylen, max_classlen;
582 : uint32_t num_values, max_valnamelen, max_valbufsize;
583 : uint32_t i;
584 : NTTIME last_changed_time;
585 : uint32_t secdescsize;
586 : struct winreg_String classname;
587 : NTSTATUS status;
588 : TALLOC_CTX *tmp_ctx;
589 :
590 58 : tmp_ctx = talloc_stackframe();
591 58 : if (tmp_ctx == NULL) {
592 0 : return NT_STATUS_NO_MEMORY;
593 : }
594 :
595 58 : ZERO_STRUCT(classname);
596 :
597 58 : 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 58 : if (!NT_STATUS_IS_OK(status)) {
611 0 : goto error;
612 : }
613 58 : if (!W_ERROR_IS_OK(*pwerr)) {
614 0 : goto error;
615 : }
616 :
617 58 : subkeys = talloc_zero_array(tmp_ctx, const char *, num_subkeys + 2);
618 58 : if (subkeys == NULL) {
619 0 : status = NT_STATUS_NO_MEMORY;
620 0 : goto error;
621 : }
622 :
623 58 : if (num_subkeys == 0) {
624 21 : subkeys[0] = talloc_strdup(subkeys, "");
625 21 : if (subkeys[0] == NULL) {
626 0 : status = NT_STATUS_NO_MEMORY;
627 0 : goto error;
628 : }
629 21 : *pnum_subkeys = 0;
630 21 : if (psubkeys) {
631 21 : *psubkeys = talloc_move(mem_ctx, &subkeys);
632 : }
633 :
634 21 : TALLOC_FREE(tmp_ctx);
635 21 : return NT_STATUS_OK;
636 : }
637 :
638 314 : for (i = 0; i < num_subkeys; i++) {
639 162 : char c = '\0';
640 162 : char n = '\0';
641 162 : char *name = NULL;
642 : struct winreg_StringBuf class_buf;
643 : struct winreg_StringBuf name_buf;
644 : NTTIME modtime;
645 :
646 162 : class_buf.name = &c;
647 162 : class_buf.size = max_classlen + 2;
648 162 : class_buf.length = 0;
649 :
650 162 : name_buf.name = &n;
651 162 : name_buf.size = max_subkeylen + 2;
652 162 : name_buf.length = 0;
653 :
654 162 : ZERO_STRUCT(modtime);
655 :
656 162 : status = dcerpc_winreg_EnumKey(h,
657 : tmp_ctx,
658 : key_hnd,
659 : i,
660 : &name_buf,
661 : &class_buf,
662 : &modtime,
663 : pwerr);
664 162 : 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 162 : if (W_ERROR_EQUAL(*pwerr, WERR_NO_MORE_ITEMS)) {
671 0 : *pwerr = WERR_OK;
672 0 : break;
673 : }
674 162 : 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 162 : if (name_buf.name == NULL) {
681 0 : *pwerr = WERR_INVALID_PARAMETER;
682 0 : goto error;
683 : }
684 :
685 162 : name = talloc_strdup(subkeys, name_buf.name);
686 162 : if (name == NULL) {
687 0 : status = NT_STATUS_NO_MEMORY;
688 0 : goto error;
689 : }
690 :
691 162 : subkeys[i] = name;
692 : }
693 :
694 37 : *pnum_subkeys = num_subkeys;
695 37 : if (psubkeys) {
696 37 : *psubkeys = talloc_move(mem_ctx, &subkeys);
697 : }
698 :
699 21 : error:
700 37 : TALLOC_FREE(tmp_ctx);
701 :
702 37 : return status;
703 : }
704 :
705 0 : 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 0 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
715 0 : uint32_t num_subkeys = 0, max_subkeylen = 0, max_classlen = 0;
716 0 : uint32_t num_values = 0, max_valnamelen = 0, max_valbufsize = 0;
717 0 : uint32_t secdescsize = 0;
718 : uint32_t i;
719 0 : NTTIME last_changed_time = 0;
720 0 : struct winreg_String classname = { .name = NULL };
721 :
722 0 : const char **enum_names = NULL;
723 0 : enum winreg_Type *enum_types = NULL;
724 0 : DATA_BLOB *enum_data_blobs = NULL;
725 :
726 :
727 0 : WERROR result = WERR_OK;
728 : NTSTATUS status;
729 :
730 0 : 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 0 : 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 0 : 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 0 : if (num_values == 0) {
756 0 : *pnum_values = 0;
757 0 : TALLOC_FREE(tmp_ctx);
758 0 : *pwerr = WERR_OK;
759 0 : return status;
760 : }
761 :
762 0 : enum_names = talloc_zero_array(tmp_ctx, const char *, num_values);
763 :
764 0 : if (enum_names == NULL) {
765 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
766 0 : goto error;
767 : }
768 :
769 0 : enum_types = talloc_zero_array(tmp_ctx, enum winreg_Type, num_values);
770 :
771 0 : if (enum_types == NULL) {
772 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
773 0 : goto error;
774 : }
775 :
776 0 : enum_data_blobs = talloc_zero_array(tmp_ctx, DATA_BLOB, num_values);
777 :
778 0 : if (enum_data_blobs == NULL) {
779 0 : *pwerr = WERR_NOT_ENOUGH_MEMORY;
780 0 : goto error;
781 : }
782 :
783 0 : for (i = 0; i < num_values; i++) {
784 : const char *name;
785 : struct winreg_ValNameBuf name_buf;
786 0 : enum winreg_Type type = REG_NONE;
787 : uint8_t *data;
788 : uint32_t data_size;
789 : uint32_t length;
790 0 : char n = '\0';
791 :
792 :
793 0 : name_buf.name = &n;
794 0 : name_buf.size = max_valnamelen + 2;
795 0 : name_buf.length = 0;
796 :
797 0 : data_size = max_valbufsize;
798 0 : data = NULL;
799 0 : if (data_size) {
800 0 : data = (uint8_t *) TALLOC(tmp_ctx, data_size);
801 : }
802 0 : length = 0;
803 :
804 0 : status = dcerpc_winreg_EnumValue(h,
805 : tmp_ctx,
806 : key_hnd,
807 : i,
808 : &name_buf,
809 : &type,
810 : data,
811 0 : data_size ? &data_size : NULL,
812 : &length,
813 : &result);
814 0 : 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 0 : 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 0 : 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 0 : if (name_buf.name == NULL) {
833 0 : result = WERR_INVALID_PARAMETER;
834 0 : *pwerr = result;
835 0 : goto error;
836 : }
837 :
838 0 : name = talloc_strdup(enum_names, name_buf.name);
839 0 : 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 0 : enum_data_blobs[i] = data_blob_talloc(enum_data_blobs, data, length);
847 0 : enum_names[i] = name;
848 0 : enum_types[i] = type;
849 :
850 : }
851 : /* move to the main mem context */
852 0 : *pnum_values = num_values;
853 0 : if (pnames) {
854 0 : *pnames = talloc_move(mem_ctx, &enum_names);
855 : }
856 : /* can this fail in any way? */
857 0 : if (_type) {
858 0 : *_type = talloc_move(mem_ctx, &enum_types);
859 : }
860 :
861 0 : if (pdata){
862 0 : *pdata = talloc_move(mem_ctx, &enum_data_blobs);
863 : }
864 :
865 :
866 0 : result = WERR_OK;
867 :
868 0 : error:
869 0 : TALLOC_FREE(tmp_ctx);
870 0 : *pwerr = result;
871 :
872 0 : return status;
873 : }
874 :
875 0 : 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 0 : const char **subkeys = NULL;
883 0 : uint32_t num_subkeys = 0;
884 : struct policy_handle key_hnd;
885 0 : struct winreg_String wkey = { 0, };
886 0 : WERROR result = WERR_OK;
887 : NTSTATUS status;
888 : uint32_t i;
889 :
890 0 : ZERO_STRUCT(key_hnd);
891 0 : wkey.name = key;
892 :
893 0 : DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete key %s\n", key));
894 : /* open the key */
895 0 : status = dcerpc_winreg_OpenKey(h,
896 : mem_ctx,
897 : hive_handle,
898 : wkey,
899 : 0,
900 : access_mask,
901 : &key_hnd,
902 : &result);
903 0 : 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 0 : if (!W_ERROR_IS_OK(result)) {
909 0 : DEBUG(0, ("dcerpc_winreg_delete_subkeys_recursive: Could not open key %s: %s\n",
910 : wkey.name, win_errstr(result)));
911 0 : *pwerr = result;
912 0 : goto done;
913 : }
914 :
915 0 : status = dcerpc_winreg_enum_keys(mem_ctx,
916 : h,
917 : &key_hnd,
918 : &num_subkeys,
919 : &subkeys,
920 : &result);
921 0 : if (!NT_STATUS_IS_OK(status)) {
922 0 : goto done;
923 : }
924 0 : if (!W_ERROR_IS_OK(result)) {
925 0 : goto done;
926 : }
927 :
928 0 : for (i = 0; i < num_subkeys; i++) {
929 : /* create key + subkey */
930 0 : char *subkey = talloc_asprintf(mem_ctx, "%s\\%s", key, subkeys[i]);
931 0 : if (subkey == NULL) {
932 0 : goto done;
933 : }
934 :
935 0 : DEBUG(2, ("dcerpc_winreg_delete_subkeys_recursive: delete subkey %s\n", subkey));
936 0 : status = dcerpc_winreg_delete_subkeys_recursive(mem_ctx,
937 : h,
938 : hive_handle,
939 : access_mask,
940 : subkey,
941 : &result);
942 0 : if (!W_ERROR_IS_OK(result)) {
943 0 : goto done;
944 : }
945 : }
946 :
947 0 : if (is_valid_policy_hnd(&key_hnd)) {
948 : WERROR ignore;
949 0 : dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
950 : }
951 :
952 0 : wkey.name = key;
953 :
954 0 : status = dcerpc_winreg_DeleteKey(h,
955 : mem_ctx,
956 : hive_handle,
957 : wkey,
958 : &result);
959 0 : if (!NT_STATUS_IS_OK(status)) {
960 0 : *pwerr = result;
961 0 : goto done;
962 : }
963 :
964 0 : done:
965 0 : if (is_valid_policy_hnd(&key_hnd)) {
966 : WERROR ignore;
967 :
968 0 : dcerpc_winreg_CloseKey(h, mem_ctx, &key_hnd, &ignore);
969 : }
970 :
971 0 : *pwerr = result;
972 0 : return status;
973 : }
974 :
975 : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
|