source: trunk/server/source4/torture/rpc/winreg.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 84.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
4
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) GÃŒnther Deschner 2007,2010
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "includes.h"
24#include "librpc/gen_ndr/ndr_winreg_c.h"
25#include "librpc/gen_ndr/ndr_security.h"
26#include "libcli/security/security.h"
27#include "torture/rpc/torture_rpc.h"
28#include "param/param.h"
29#include "lib/registry/registry.h"
30
31#define TEST_KEY_BASE "winreg_torture_test"
32#define TEST_KEY1 "spottyfoot"
33#define TEST_KEY2 "with a SD (#1)"
34#define TEST_KEY3 "with a subkey"
35#define TEST_KEY4 "sd_tests"
36#define TEST_SUBKEY "subkey"
37#define TEST_SUBKEY_SD "subkey_sd"
38#define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39#define TEST_VALUE "torture_value_name"
40#define TEST_KEY_VOLATILE "torture_volatile_key"
41#define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42#define TEST_KEY_SYMLINK "torture_symlink_key"
43#define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
44
45#define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46
47static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48{
49 name->string = s;
50}
51
52static void init_winreg_String(struct winreg_String *name, const char *s)
53{
54 name->name = s;
55 if (s) {
56 name->name_len = 2 * (strlen_m(s) + 1);
57 name->name_size = name->name_len;
58 } else {
59 name->name_len = 0;
60 name->name_size = 0;
61 }
62}
63
64static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 struct torture_context *tctx,
66 struct policy_handle *handle)
67{
68 struct winreg_GetVersion r;
69 uint32_t v;
70
71 torture_comment(tctx, "Testing GetVersion\n");
72
73 ZERO_STRUCT(r);
74 r.in.handle = handle;
75 r.out.version = &v;
76
77 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78 "GetVersion failed");
79
80 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81
82 return true;
83}
84
85static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 struct torture_context *tctx,
87 struct policy_handle *handle)
88{
89 struct winreg_NotifyChangeKeyValue r;
90
91 ZERO_STRUCT(r);
92 r.in.handle = handle;
93 r.in.watch_subtree = true;
94 r.in.notify_filter = 0;
95 r.in.unknown = r.in.unknown2 = 0;
96 init_winreg_String(&r.in.string1, NULL);
97 init_winreg_String(&r.in.string2, NULL);
98
99 torture_assert_ntstatus_ok(tctx,
100 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 "NotifyChangeKeyValue failed");
102
103 if (!W_ERROR_IS_OK(r.out.result)) {
104 torture_comment(tctx,
105 "NotifyChangeKeyValue failed - %s - not considering\n",
106 win_errstr(r.out.result));
107 return true;
108 }
109
110 return true;
111}
112
113static bool test_CreateKey_opts(struct torture_context *tctx,
114 struct dcerpc_binding_handle *b,
115 struct policy_handle *handle,
116 const char *name,
117 const char *kclass,
118 uint32_t options,
119 uint32_t access_mask,
120 struct winreg_SecBuf *secdesc,
121 WERROR expected_result,
122 enum winreg_CreateAction *action_taken_p,
123 struct policy_handle *new_handle_p)
124{
125 struct winreg_CreateKey r;
126 struct policy_handle newhandle;
127 enum winreg_CreateAction action_taken = 0;
128
129 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130
131 ZERO_STRUCT(r);
132 r.in.handle = handle;
133 init_winreg_String(&r.in.name, name);
134 init_winreg_String(&r.in.keyclass, kclass);
135 r.in.options = options;
136 r.in.access_mask = access_mask;
137 r.in.action_taken = &action_taken;
138 r.in.secdesc = secdesc;
139 r.out.new_handle = &newhandle;
140 r.out.action_taken = &action_taken;
141
142 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143 "CreateKey failed");
144
145 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146
147 if (new_handle_p) {
148 *new_handle_p = newhandle;
149 }
150 if (action_taken_p) {
151 *action_taken_p = *r.out.action_taken;
152 }
153
154 return true;
155}
156
157static bool test_CreateKey(struct dcerpc_binding_handle *b,
158 struct torture_context *tctx,
159 struct policy_handle *handle, const char *name,
160 const char *kclass)
161{
162 return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 REG_OPTION_NON_VOLATILE,
164 SEC_FLAG_MAXIMUM_ALLOWED,
165 NULL, /* secdesc */
166 WERR_OK,
167 NULL, /* action_taken */
168 NULL /* new_handle */);
169}
170
171/*
172 createkey testing with a SD
173*/
174static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175 struct torture_context *tctx,
176 struct policy_handle *handle, const char *name,
177 const char *kclass,
178 struct policy_handle *newhandle)
179{
180 struct winreg_CreateKey r;
181 enum winreg_CreateAction action_taken = 0;
182 struct security_descriptor *sd;
183 DATA_BLOB sdblob;
184 struct winreg_SecBuf secbuf;
185
186 sd = security_descriptor_dacl_create(tctx,
187 0,
188 NULL, NULL,
189 SID_NT_AUTHENTICATED_USERS,
190 SEC_ACE_TYPE_ACCESS_ALLOWED,
191 SEC_GENERIC_ALL,
192 SEC_ACE_FLAG_OBJECT_INHERIT |
193 SEC_ACE_FLAG_CONTAINER_INHERIT,
194 NULL);
195
196 torture_assert_ndr_success(tctx,
197 ndr_push_struct_blob(&sdblob, tctx, sd,
198 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199 "Failed to push security_descriptor ?!\n");
200
201 secbuf.sd.data = sdblob.data;
202 secbuf.sd.len = sdblob.length;
203 secbuf.sd.size = sdblob.length;
204 secbuf.length = sdblob.length-10;
205 secbuf.inherit = 0;
206
207 ZERO_STRUCT(r);
208 r.in.handle = handle;
209 r.out.new_handle = newhandle;
210 init_winreg_String(&r.in.name, name);
211 init_winreg_String(&r.in.keyclass, kclass);
212 r.in.options = 0x0;
213 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 r.in.action_taken = r.out.action_taken = &action_taken;
215 r.in.secdesc = &secbuf;
216
217 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 "CreateKey with sd failed");
219
220 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221
222 return true;
223}
224
225static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226 struct torture_context *tctx,
227 struct policy_handle *handle,
228 uint32_t *sec_info_ptr,
229 WERROR get_werr,
230 struct security_descriptor **sd_out)
231{
232 struct winreg_GetKeySecurity r;
233 struct security_descriptor *sd = NULL;
234 uint32_t sec_info;
235 DATA_BLOB sdblob;
236 struct dcerpc_binding_handle *b = p->binding_handle;
237
238 if (sec_info_ptr) {
239 sec_info = *sec_info_ptr;
240 } else {
241 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
242 }
243
244 ZERO_STRUCT(r);
245
246 r.in.handle = handle;
247 r.in.sec_info = sec_info;
248 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 r.in.sd->size = 0x1000;
250
251 torture_assert_ntstatus_ok(tctx,
252 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 "GetKeySecurity failed");
254
255 torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 "GetKeySecurity failed");
257
258 sdblob.data = r.out.sd->data;
259 sdblob.length = r.out.sd->len;
260
261 sd = talloc_zero(tctx, struct security_descriptor);
262
263 torture_assert_ndr_success(tctx,
264 ndr_pull_struct_blob(&sdblob, tctx, sd,
265 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266 "pull_security_descriptor failed");
267
268 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 NDR_PRINT_DEBUG(security_descriptor, sd);
270 }
271
272 if (sd_out) {
273 *sd_out = sd;
274 } else {
275 talloc_free(sd);
276 }
277
278 return true;
279}
280
281static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282 struct torture_context *tctx,
283 struct policy_handle *handle,
284 struct security_descriptor **sd_out)
285{
286 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
287}
288
289static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290 struct torture_context *tctx,
291 struct policy_handle *handle,
292 uint32_t *sec_info_ptr,
293 struct security_descriptor *sd,
294 WERROR werr)
295{
296 struct winreg_SetKeySecurity r;
297 struct KeySecurityData *sdata = NULL;
298 DATA_BLOB sdblob;
299 uint32_t sec_info;
300 struct dcerpc_binding_handle *b = p->binding_handle;
301
302 ZERO_STRUCT(r);
303
304 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 NDR_PRINT_DEBUG(security_descriptor, sd);
306 }
307
308 torture_assert_ndr_success(tctx,
309 ndr_push_struct_blob(&sdblob, tctx, sd,
310 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311 "push_security_descriptor failed");
312
313 sdata = talloc_zero(tctx, struct KeySecurityData);
314 sdata->data = sdblob.data;
315 sdata->size = sdblob.length;
316 sdata->len = sdblob.length;
317
318 if (sec_info_ptr) {
319 sec_info = *sec_info_ptr;
320 } else {
321 sec_info = SECINFO_UNPROTECTED_SACL |
322 SECINFO_UNPROTECTED_DACL;
323 if (sd->owner_sid) {
324 sec_info |= SECINFO_OWNER;
325 }
326 if (sd->group_sid) {
327 sec_info |= SECINFO_GROUP;
328 }
329 if (sd->sacl) {
330 sec_info |= SECINFO_SACL;
331 }
332 if (sd->dacl) {
333 sec_info |= SECINFO_DACL;
334 }
335 }
336
337 r.in.handle = handle;
338 r.in.sec_info = sec_info;
339 r.in.sd = sdata;
340
341 torture_assert_ntstatus_ok(tctx,
342 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 "SetKeySecurity failed");
344
345 torture_assert_werr_equal(tctx, r.out.result, werr,
346 "SetKeySecurity failed");
347
348 return true;
349}
350
351static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352 struct torture_context *tctx,
353 struct policy_handle *handle,
354 struct security_descriptor *sd)
355{
356 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
357}
358
359static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 struct torture_context *tctx,
361 struct policy_handle *handle)
362{
363 struct winreg_CloseKey r;
364
365 ZERO_STRUCT(r);
366 r.in.handle = r.out.handle = handle;
367
368 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369 "CloseKey failed");
370
371 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372
373 return true;
374}
375
376static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 struct torture_context *tctx,
378 struct policy_handle *handle)
379{
380 struct winreg_FlushKey r;
381
382 ZERO_STRUCT(r);
383 r.in.handle = handle;
384
385 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386 "FlushKey failed");
387
388 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389
390 return true;
391}
392
393static bool test_OpenKey_opts(struct torture_context *tctx,
394 struct dcerpc_binding_handle *b,
395 struct policy_handle *hive_handle,
396 const char *keyname,
397 uint32_t options,
398 uint32_t access_mask,
399 struct policy_handle *key_handle,
400 WERROR expected_result)
401{
402 struct winreg_OpenKey r;
403
404 ZERO_STRUCT(r);
405 r.in.parent_handle = hive_handle;
406 init_winreg_String(&r.in.keyname, keyname);
407 r.in.options = options;
408 r.in.access_mask = access_mask;
409 r.out.handle = key_handle;
410
411 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412 "OpenKey failed");
413
414 torture_assert_werr_equal(tctx, r.out.result, expected_result,
415 "OpenKey failed");
416
417 return true;
418}
419
420static bool test_OpenKey(struct dcerpc_binding_handle *b,
421 struct torture_context *tctx,
422 struct policy_handle *hive_handle,
423 const char *keyname, struct policy_handle *key_handle)
424{
425 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 REG_OPTION_NON_VOLATILE,
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 key_handle,
429 WERR_OK);
430}
431
432static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 struct torture_context *tctx,
434 struct policy_handle *handle, const char *key)
435{
436 struct winreg_DeleteKey r;
437
438 ZERO_STRUCT(r);
439 r.in.handle = handle;
440
441 init_winreg_String(&r.in.key, key);
442 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443
444 return true;
445}
446
447static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448 struct torture_context *tctx,
449 struct policy_handle *handle,
450 WERROR get_werr,
451 WERROR set_werr)
452{
453 struct security_descriptor *sd = NULL;
454
455 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456 return false;
457 }
458
459 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460 return false;
461 }
462
463 return true;
464}
465
466static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467 struct torture_context *tctx,
468 struct policy_handle *handle,
469 const char *key)
470{
471 struct policy_handle new_handle;
472 bool ret = true;
473 struct dcerpc_binding_handle *b = p->binding_handle;
474
475 torture_comment(tctx, "SecurityDescriptor get & set\n");
476
477 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478 return false;
479 }
480
481 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482 WERR_OK, WERR_OK)) {
483 ret = false;
484 }
485
486 if (!test_CloseKey(b, tctx, &new_handle)) {
487 return false;
488 }
489
490 return ret;
491}
492
493static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494 struct torture_context *tctx,
495 struct policy_handle *handle,
496 uint32_t access_mask,
497 const char *key,
498 WERROR open_werr,
499 WERROR get_werr,
500 WERROR set_werr)
501{
502 struct policy_handle new_handle;
503 bool ret = true;
504 struct dcerpc_binding_handle *b = p->binding_handle;
505
506 torture_assert(tctx,
507 test_OpenKey_opts(tctx, b, handle, key,
508 REG_OPTION_NON_VOLATILE,
509 access_mask,
510 &new_handle,
511 open_werr),
512 "failed to open key");
513
514 if (!W_ERROR_IS_OK(open_werr)) {
515 return true;
516 }
517
518 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 get_werr, set_werr)) {
520 ret = false;
521 }
522
523 if (!test_CloseKey(b, tctx, &new_handle)) {
524 return false;
525 }
526
527 return ret;
528}
529
530static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531 struct torture_context *tctx,
532 struct policy_handle *handle,
533 const struct dom_sid *sid)
534{
535 struct security_descriptor *sd = NULL;
536 int i;
537
538 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539 return false;
540 }
541
542 if (!sd || !sd->dacl) {
543 return false;
544 }
545
546 for (i = 0; i < sd->dacl->num_aces; i++) {
547 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548 return true;
549 }
550 }
551
552 return false;
553}
554
555static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
556 struct torture_context *tctx,
557 struct policy_handle *handle,
558 const char *key,
559 const struct dom_sid *sid)
560{
561 struct policy_handle new_handle;
562 bool ret = true;
563 struct dcerpc_binding_handle *b = p->binding_handle;
564
565 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566 return false;
567 }
568
569 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570
571 test_CloseKey(b, tctx, &new_handle);
572
573 return ret;
574}
575
576static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
577 struct torture_context *tctx,
578 struct policy_handle *handle,
579 const struct dom_sid *sid)
580{
581 struct security_descriptor *sd = NULL;
582 int i;
583 uint32_t sec_info = SECINFO_SACL;
584
585 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586 return false;
587 }
588
589 if (!sd || !sd->sacl) {
590 return false;
591 }
592
593 for (i = 0; i < sd->sacl->num_aces; i++) {
594 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595 return true;
596 }
597 }
598
599 return false;
600}
601
602static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603 struct torture_context *tctx,
604 struct policy_handle *handle,
605 const char *key,
606 const struct dom_sid *sid)
607{
608 struct policy_handle new_handle;
609 bool ret = true;
610 struct dcerpc_binding_handle *b = p->binding_handle;
611
612 torture_assert(tctx,
613 test_OpenKey_opts(tctx, b, handle, key,
614 REG_OPTION_NON_VOLATILE,
615 SEC_FLAG_SYSTEM_SECURITY,
616 &new_handle,
617 WERR_OK),
618 "failed to open key");
619
620 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621
622 test_CloseKey(b, tctx, &new_handle);
623
624 return ret;
625}
626
627static bool test_owner_present(struct dcerpc_pipe *p,
628 struct torture_context *tctx,
629 struct policy_handle *handle,
630 const struct dom_sid *sid)
631{
632 struct security_descriptor *sd = NULL;
633 uint32_t sec_info = SECINFO_OWNER;
634
635 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636 return false;
637 }
638
639 if (!sd || !sd->owner_sid) {
640 return false;
641 }
642
643 return dom_sid_equal(sd->owner_sid, sid);
644}
645
646static bool _test_owner_present(struct dcerpc_pipe *p,
647 struct torture_context *tctx,
648 struct policy_handle *handle,
649 const char *key,
650 const struct dom_sid *sid)
651{
652 struct policy_handle new_handle;
653 bool ret = true;
654 struct dcerpc_binding_handle *b = p->binding_handle;
655
656 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657 return false;
658 }
659
660 ret = test_owner_present(p, tctx, &new_handle, sid);
661
662 test_CloseKey(b, tctx, &new_handle);
663
664 return ret;
665}
666
667static bool test_group_present(struct dcerpc_pipe *p,
668 struct torture_context *tctx,
669 struct policy_handle *handle,
670 const struct dom_sid *sid)
671{
672 struct security_descriptor *sd = NULL;
673 uint32_t sec_info = SECINFO_GROUP;
674
675 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676 return false;
677 }
678
679 if (!sd || !sd->group_sid) {
680 return false;
681 }
682
683 return dom_sid_equal(sd->group_sid, sid);
684}
685
686static bool _test_group_present(struct dcerpc_pipe *p,
687 struct torture_context *tctx,
688 struct policy_handle *handle,
689 const char *key,
690 const struct dom_sid *sid)
691{
692 struct policy_handle new_handle;
693 bool ret = true;
694 struct dcerpc_binding_handle *b = p->binding_handle;
695
696 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697 return false;
698 }
699
700 ret = test_group_present(p, tctx, &new_handle, sid);
701
702 test_CloseKey(b, tctx, &new_handle);
703
704 return ret;
705}
706
707static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708 struct torture_context *tctx,
709 struct policy_handle *handle,
710 const struct dom_sid *sid,
711 uint8_t flags)
712{
713 struct security_descriptor *sd = NULL;
714 int i;
715
716 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717 return false;
718 }
719
720 if (!sd || !sd->dacl) {
721 return false;
722 }
723
724 for (i = 0; i < sd->dacl->num_aces; i++) {
725 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 (sd->dacl->aces[i].flags == flags)) {
727 return true;
728 }
729 }
730
731 return false;
732}
733
734static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735 struct torture_context *tctx,
736 struct policy_handle *handle,
737 const struct security_ace *ace)
738{
739 struct security_descriptor *sd = NULL;
740 int i;
741
742 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743 return false;
744 }
745
746 if (!sd || !sd->dacl) {
747 return false;
748 }
749
750 for (i = 0; i < sd->dacl->num_aces; i++) {
751 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752 return true;
753 }
754 }
755
756 return false;
757}
758
759static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760 struct torture_context *tctx,
761 struct policy_handle *handle,
762 const char *key,
763 struct security_descriptor *sd)
764{
765 struct policy_handle new_handle;
766 bool ret = true;
767 struct dcerpc_binding_handle *b = p->binding_handle;
768
769 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770 return false;
771 }
772
773 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774 ret = false;
775 }
776
777 if (!test_CloseKey(b, tctx, &new_handle)) {
778 ret = false;
779 }
780
781 return ret;
782}
783
784static bool test_BackupSecurity(struct dcerpc_pipe *p,
785 struct torture_context *tctx,
786 struct policy_handle *handle,
787 const char *key,
788 struct security_descriptor **sd)
789{
790 struct policy_handle new_handle;
791 bool ret = true;
792 struct dcerpc_binding_handle *b = p->binding_handle;
793
794 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795 return false;
796 }
797
798 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799 ret = false;
800 }
801
802 if (!test_CloseKey(b, tctx, &new_handle)) {
803 ret = false;
804 }
805
806 return ret;
807}
808
809static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810 struct torture_context *tctx,
811 struct policy_handle *handle,
812 const char *key)
813{
814 /* get sd
815 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816 set sd
817 get sd
818 check ace
819 add subkey
820 get sd
821 check ace
822 add subsubkey
823 get sd
824 check ace
825 del subsubkey
826 del subkey
827 reset sd
828 */
829
830 struct security_descriptor *sd = NULL;
831 struct security_descriptor *sd_orig = NULL;
832 struct security_ace *ace = NULL;
833 struct policy_handle new_handle;
834 bool ret = true;
835 struct dcerpc_binding_handle *b = p->binding_handle;
836 const char *test_subkey_sd;
837 const char *test_subsubkey_sd;
838
839 torture_comment(tctx, "SecurityDescriptor inheritance\n");
840
841 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 return false;
843 }
844
845 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 return false;
847 }
848
849 sd_orig = security_descriptor_copy(tctx, sd);
850 if (sd_orig == NULL) {
851 return false;
852 }
853
854 ace = security_ace_create(tctx,
855 TEST_SID,
856 SEC_ACE_TYPE_ACCESS_ALLOWED,
857 SEC_STD_REQUIRED,
858 SEC_ACE_FLAG_CONTAINER_INHERIT);
859
860 torture_assert_ntstatus_ok(tctx,
861 security_descriptor_dacl_add(sd, ace),
862 "failed to add ace");
863
864 /* FIXME: add further tests for these flags */
865 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 SEC_DESC_SACL_AUTO_INHERITED;
867
868 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869 return false;
870 }
871
872 torture_assert(tctx,
873 test_dacl_ace_present(p, tctx, &new_handle, ace),
874 "new ACE not present!");
875
876 if (!test_CloseKey(b, tctx, &new_handle)) {
877 return false;
878 }
879
880 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881
882 if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883 ret = false;
884 goto out;
885 }
886
887 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888 ret = false;
889 goto out;
890 }
891
892 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 torture_comment(tctx, "inherited ACE not present!\n");
894 ret = false;
895 goto out;
896 }
897
898 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899
900 test_CloseKey(b, tctx, &new_handle);
901 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902 ret = false;
903 goto out;
904 }
905
906 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907 ret = false;
908 goto out;
909 }
910
911 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 torture_comment(tctx, "inherited ACE not present!\n");
913 ret = false;
914 goto out;
915 }
916
917 out:
918 test_CloseKey(b, tctx, &new_handle);
919 test_Cleanup(b, tctx, handle, test_subkey_sd);
920 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921
922 return ret;
923}
924
925static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926 struct torture_context *tctx,
927 struct policy_handle *handle,
928 const char *key)
929{
930 /* get sd
931 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
932 set sd
933 add subkey/subkey
934 get sd
935 check ace
936 get sd from subkey
937 check ace
938 del subkey/subkey
939 del subkey
940 reset sd
941 */
942
943 struct security_descriptor *sd = NULL;
944 struct security_descriptor *sd_orig = NULL;
945 struct security_ace *ace = NULL;
946 struct policy_handle new_handle;
947 struct dom_sid *sid = NULL;
948 bool ret = true;
949 uint8_t ace_flags = 0x0;
950 struct dcerpc_binding_handle *b = p->binding_handle;
951 const char *test_subkey_sd;
952 const char *test_subsubkey_sd;
953
954 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955
956 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957 return false;
958 }
959
960 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961 return false;
962 }
963
964 sd_orig = security_descriptor_copy(tctx, sd);
965 if (sd_orig == NULL) {
966 return false;
967 }
968
969 ace = security_ace_create(tctx,
970 TEST_SID,
971 SEC_ACE_TYPE_ACCESS_ALLOWED,
972 SEC_STD_REQUIRED,
973 SEC_ACE_FLAG_CONTAINER_INHERIT |
974 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
975
976 torture_assert_ntstatus_ok(tctx,
977 security_descriptor_dacl_add(sd, ace),
978 "failed to add ace");
979
980 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981 return false;
982 }
983
984 torture_assert(tctx,
985 test_dacl_ace_present(p, tctx, &new_handle, ace),
986 "new ACE not present!");
987
988 if (!test_CloseKey(b, tctx, &new_handle)) {
989 return false;
990 }
991
992 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994
995 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996 return false;
997 }
998
999 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000 ret = false;
1001 goto out;
1002 }
1003
1004 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 torture_comment(tctx, "inherited ACE present but should not!\n");
1006 ret = false;
1007 goto out;
1008 }
1009
1010 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011 if (sid == NULL) {
1012 return false;
1013 }
1014
1015 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017 ret = false;
1018 goto out;
1019 }
1020
1021 test_CloseKey(b, tctx, &new_handle);
1022
1023 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024 ret = false;
1025 goto out;
1026 }
1027
1028 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 torture_comment(tctx, "inherited ACE present but should not!\n");
1030 ret = false;
1031 goto out;
1032 }
1033
1034 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036 ace_flags);
1037 ret = false;
1038 goto out;
1039 }
1040
1041 out:
1042 test_CloseKey(b, tctx, &new_handle);
1043 test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045
1046 return ret;
1047}
1048
1049static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 struct torture_context *tctx,
1051 struct policy_handle *handle,
1052 const char *key)
1053{
1054 bool ret = true;
1055 int i;
1056
1057 struct winreg_mask_result_table {
1058 uint32_t access_mask;
1059 WERROR open_werr;
1060 WERROR get_werr;
1061 WERROR set_werr;
1062 } sd_mask_tests[] = {
1063 { 0,
1064 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1065 { SEC_FLAG_MAXIMUM_ALLOWED,
1066 WERR_OK, WERR_OK, WERR_OK },
1067 { SEC_STD_WRITE_DAC,
1068 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069 { SEC_FLAG_SYSTEM_SECURITY,
1070 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1071 };
1072
1073 /* FIXME: before this test can ever run successfully we need a way to
1074 * correctly read a NULL security_descritpor in ndr, get the required
1075 * length, requery, etc.
1076 */
1077
1078 return true;
1079
1080 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1081
1082 torture_comment(tctx,
1083 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084 sd_mask_tests[i].access_mask);
1085 torture_comment(tctx,
1086 "expecting: open %s, get: %s, set: %s\n",
1087 win_errstr(sd_mask_tests[i].open_werr),
1088 win_errstr(sd_mask_tests[i].get_werr),
1089 win_errstr(sd_mask_tests[i].set_werr));
1090
1091 if (_test_SecurityDescriptor(p, tctx, handle,
1092 sd_mask_tests[i].access_mask, key,
1093 sd_mask_tests[i].open_werr,
1094 sd_mask_tests[i].get_werr,
1095 sd_mask_tests[i].set_werr)) {
1096 ret = false;
1097 }
1098 }
1099
1100 return ret;
1101}
1102
1103typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104 struct torture_context *,
1105 struct policy_handle *,
1106 const char *,
1107 const struct dom_sid *);
1108
1109static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110 struct torture_context *tctx,
1111 struct policy_handle *handle,
1112 const char *key,
1113 const char *test,
1114 uint32_t access_mask,
1115 uint32_t sec_info,
1116 struct security_descriptor *sd,
1117 WERROR set_werr,
1118 bool expect_present,
1119 bool (*fn) (struct dcerpc_pipe *,
1120 struct torture_context *,
1121 struct policy_handle *,
1122 const char *,
1123 const struct dom_sid *),
1124 const struct dom_sid *sid)
1125{
1126 struct policy_handle new_handle;
1127 struct dcerpc_binding_handle *b = p->binding_handle;
1128
1129 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 "0x%08x, access_mask: 0x%08x\n",
1131 test, sec_info, access_mask);
1132
1133 torture_assert(tctx,
1134 test_OpenKey_opts(tctx, b, handle, key,
1135 REG_OPTION_NON_VOLATILE,
1136 access_mask,
1137 &new_handle,
1138 WERR_OK),
1139 "failed to open key");
1140
1141 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142 sd,
1143 set_werr)) {
1144 torture_warning(tctx,
1145 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1146 sec_info);
1147 smb_panic("");
1148 test_CloseKey(b, tctx, &new_handle);
1149 return false;
1150 }
1151
1152 test_CloseKey(b, tctx, &new_handle);
1153
1154 if (W_ERROR_IS_OK(set_werr)) {
1155 bool present;
1156 present = fn(p, tctx, handle, key, sid);
1157 if ((expect_present) && (!present)) {
1158 torture_warning(tctx,
1159 "%s sid is not present!\n",
1160 test);
1161 return false;
1162 }
1163 if ((!expect_present) && (present)) {
1164 torture_warning(tctx,
1165 "%s sid is present but not expected!\n",
1166 test);
1167 return false;
1168 }
1169 }
1170
1171 return true;
1172}
1173
1174static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 struct torture_context *tctx,
1176 struct policy_handle *handle,
1177 const char *key)
1178{
1179 struct security_descriptor *sd_orig = NULL;
1180 struct dom_sid *sid = NULL;
1181 bool ret = true;
1182 int i, a;
1183
1184 struct security_descriptor *sd_owner =
1185 security_descriptor_dacl_create(tctx,
1186 0,
1187 TEST_SID, NULL, NULL);
1188
1189 struct security_descriptor *sd_group =
1190 security_descriptor_dacl_create(tctx,
1191 0,
1192 NULL, TEST_SID, NULL);
1193
1194 struct security_descriptor *sd_dacl =
1195 security_descriptor_dacl_create(tctx,
1196 0,
1197 NULL, NULL,
1198 TEST_SID,
1199 SEC_ACE_TYPE_ACCESS_ALLOWED,
1200 SEC_GENERIC_ALL,
1201 0,
1202 SID_NT_AUTHENTICATED_USERS,
1203 SEC_ACE_TYPE_ACCESS_ALLOWED,
1204 SEC_GENERIC_ALL,
1205 0,
1206 NULL);
1207
1208 struct security_descriptor *sd_sacl =
1209 security_descriptor_sacl_create(tctx,
1210 0,
1211 NULL, NULL,
1212 TEST_SID,
1213 SEC_ACE_TYPE_SYSTEM_AUDIT,
1214 SEC_GENERIC_ALL,
1215 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1216 NULL);
1217
1218 struct winreg_secinfo_table {
1219 struct security_descriptor *sd;
1220 uint32_t sec_info;
1221 WERROR set_werr;
1222 bool sid_present;
1223 secinfo_verify_fn fn;
1224 };
1225
1226 struct winreg_secinfo_table sec_info_owner_tests[] = {
1227 { sd_owner, 0, WERR_OK,
1228 false, (secinfo_verify_fn)_test_owner_present },
1229 { sd_owner, SECINFO_OWNER, WERR_OK,
1230 true, (secinfo_verify_fn)_test_owner_present },
1231 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1232 { sd_owner, SECINFO_DACL, WERR_OK,
1233 true, (secinfo_verify_fn)_test_owner_present },
1234 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1235 };
1236
1237 uint32_t sd_owner_good_access_masks[] = {
1238 SEC_FLAG_MAXIMUM_ALLOWED,
1239 /* SEC_STD_WRITE_OWNER, */
1240 };
1241
1242 struct winreg_secinfo_table sec_info_group_tests[] = {
1243 { sd_group, 0, WERR_OK,
1244 false, (secinfo_verify_fn)_test_group_present },
1245 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1246 { sd_group, SECINFO_GROUP, WERR_OK,
1247 true, (secinfo_verify_fn)_test_group_present },
1248 { sd_group, SECINFO_DACL, WERR_OK,
1249 true, (secinfo_verify_fn)_test_group_present },
1250 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1251 };
1252
1253 uint32_t sd_group_good_access_masks[] = {
1254 SEC_FLAG_MAXIMUM_ALLOWED,
1255 };
1256
1257 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1258 { sd_dacl, 0, WERR_OK,
1259 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1260 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1261 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1262 { sd_dacl, SECINFO_DACL, WERR_OK,
1263 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1264 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1265 };
1266
1267 uint32_t sd_dacl_good_access_masks[] = {
1268 SEC_FLAG_MAXIMUM_ALLOWED,
1269 SEC_STD_WRITE_DAC,
1270 };
1271
1272 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1273 { sd_sacl, 0, WERR_OK,
1274 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1275 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1276 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1277 { sd_sacl, SECINFO_DACL, WERR_OK,
1278 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1279 { sd_sacl, SECINFO_SACL, WERR_OK,
1280 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1281 };
1282
1283 uint32_t sd_sacl_good_access_masks[] = {
1284 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1285 /* SEC_FLAG_SYSTEM_SECURITY, */
1286 };
1287
1288 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1289 if (sid == NULL) {
1290 return false;
1291 }
1292
1293 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1294 return false;
1295 }
1296
1297 /* OWNER */
1298
1299 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1300
1301 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1302
1303 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1304 key,
1305 "OWNER",
1306 sd_owner_good_access_masks[a],
1307 sec_info_owner_tests[i].sec_info,
1308 sec_info_owner_tests[i].sd,
1309 sec_info_owner_tests[i].set_werr,
1310 sec_info_owner_tests[i].sid_present,
1311 sec_info_owner_tests[i].fn,
1312 sid))
1313 {
1314 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1315 ret = false;
1316 goto out;
1317 }
1318 }
1319 }
1320
1321 /* GROUP */
1322
1323 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1324
1325 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1326
1327 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1328 key,
1329 "GROUP",
1330 sd_group_good_access_masks[a],
1331 sec_info_group_tests[i].sec_info,
1332 sec_info_group_tests[i].sd,
1333 sec_info_group_tests[i].set_werr,
1334 sec_info_group_tests[i].sid_present,
1335 sec_info_group_tests[i].fn,
1336 sid))
1337 {
1338 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1339 ret = false;
1340 goto out;
1341 }
1342 }
1343 }
1344
1345 /* DACL */
1346
1347 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1348
1349 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1350
1351 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1352 key,
1353 "DACL",
1354 sd_dacl_good_access_masks[a],
1355 sec_info_dacl_tests[i].sec_info,
1356 sec_info_dacl_tests[i].sd,
1357 sec_info_dacl_tests[i].set_werr,
1358 sec_info_dacl_tests[i].sid_present,
1359 sec_info_dacl_tests[i].fn,
1360 sid))
1361 {
1362 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1363 ret = false;
1364 goto out;
1365 }
1366 }
1367 }
1368
1369 /* SACL */
1370
1371 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1372
1373 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1374
1375 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1376 key,
1377 "SACL",
1378 sd_sacl_good_access_masks[a],
1379 sec_info_sacl_tests[i].sec_info,
1380 sec_info_sacl_tests[i].sd,
1381 sec_info_sacl_tests[i].set_werr,
1382 sec_info_sacl_tests[i].sid_present,
1383 sec_info_sacl_tests[i].fn,
1384 sid))
1385 {
1386 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1387 ret = false;
1388 goto out;
1389 }
1390 }
1391 }
1392
1393 out:
1394 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1395
1396 return ret;
1397}
1398
1399static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1400 struct torture_context *tctx,
1401 struct policy_handle *handle,
1402 const char *key)
1403{
1404 bool ret = true;
1405
1406 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1407 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1408 ret = false;
1409 }
1410
1411 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1412 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1413 ret = false;
1414 }
1415
1416 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1417 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1418 ret = false;
1419 }
1420
1421 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1422 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1423 ret = false;
1424 }
1425
1426 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1427 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1428 ret = false;
1429 }
1430
1431 return ret;
1432}
1433
1434static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1435 struct torture_context *tctx,
1436 struct policy_handle *handle,
1437 const char *key,
1438 WERROR expected_result)
1439{
1440 struct winreg_DeleteKey r;
1441
1442 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1443
1444 r.in.handle = handle;
1445 init_winreg_String(&r.in.key, key);
1446
1447 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1448 "Delete Key failed");
1449 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1450 "DeleteKey failed");
1451
1452 return true;
1453}
1454
1455static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1456 struct torture_context *tctx,
1457 struct policy_handle *handle, const char *key)
1458{
1459 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1460}
1461
1462static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1463 struct torture_context *tctx,
1464 struct policy_handle *handle,
1465 char *kclass,
1466 uint32_t *pmax_valnamelen,
1467 uint32_t *pmax_valbufsize)
1468{
1469 struct winreg_QueryInfoKey r;
1470 uint32_t num_subkeys, max_subkeylen, max_classlen,
1471 num_values, max_valnamelen, max_valbufsize,
1472 secdescsize;
1473 NTTIME last_changed_time;
1474
1475 ZERO_STRUCT(r);
1476 r.in.handle = handle;
1477 r.out.num_subkeys = &num_subkeys;
1478 r.out.max_subkeylen = &max_subkeylen;
1479 r.out.max_classlen = &max_classlen;
1480 r.out.num_values = &num_values;
1481 r.out.max_valnamelen = &max_valnamelen;
1482 r.out.max_valbufsize = &max_valbufsize;
1483 r.out.secdescsize = &secdescsize;
1484 r.out.last_changed_time = &last_changed_time;
1485
1486 r.out.classname = talloc(tctx, struct winreg_String);
1487
1488 r.in.classname = talloc(tctx, struct winreg_String);
1489 init_winreg_String(r.in.classname, kclass);
1490
1491 torture_assert_ntstatus_ok(tctx,
1492 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1493 "QueryInfoKey failed");
1494
1495 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1496
1497 if (pmax_valnamelen) {
1498 *pmax_valnamelen = max_valnamelen;
1499 }
1500
1501 if (pmax_valbufsize) {
1502 *pmax_valbufsize = max_valbufsize;
1503 }
1504
1505 return true;
1506}
1507
1508static bool test_SetValue(struct dcerpc_binding_handle *b,
1509 struct torture_context *tctx,
1510 struct policy_handle *handle,
1511 const char *value_name,
1512 enum winreg_Type type,
1513 uint8_t *data,
1514 uint32_t size)
1515{
1516 struct winreg_SetValue r;
1517 struct winreg_String name;
1518
1519 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1520 value_name, str_regtype(type), size);
1521
1522 init_winreg_String(&name, value_name);
1523
1524 r.in.handle = handle;
1525 r.in.name = name;
1526 r.in.type = type;
1527 r.in.data = data;
1528 r.in.size = size;
1529
1530 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1531 "winreg_SetValue failed");
1532 torture_assert_werr_ok(tctx, r.out.result,
1533 "winreg_SetValue failed");
1534
1535 return true;
1536}
1537
1538static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1539 struct torture_context *tctx,
1540 struct policy_handle *handle,
1541 const char *value_name)
1542{
1543 struct winreg_DeleteValue r;
1544 struct winreg_String value;
1545
1546 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1547
1548 init_winreg_String(&value, value_name);
1549
1550 r.in.handle = handle;
1551 r.in.value = value;
1552
1553 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1554 "winreg_DeleteValue failed");
1555 torture_assert_werr_ok(tctx, r.out.result,
1556 "winreg_DeleteValue failed");
1557
1558 return true;
1559}
1560
1561static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1562 struct policy_handle *handle, int depth,
1563 bool test_security);
1564
1565static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1566 struct policy_handle *handle, int depth,
1567 bool test_security)
1568{
1569 struct winreg_EnumKey r;
1570 struct winreg_StringBuf kclass, name;
1571 NTSTATUS status;
1572 NTTIME t = 0;
1573 struct dcerpc_binding_handle *b = p->binding_handle;
1574
1575 kclass.name = "";
1576 kclass.size = 1024;
1577
1578 ZERO_STRUCT(r);
1579 r.in.handle = handle;
1580 r.in.enum_index = 0;
1581 r.in.name = &name;
1582 r.in.keyclass = &kclass;
1583 r.out.name = &name;
1584 r.in.last_changed_time = &t;
1585
1586 do {
1587 name.name = NULL;
1588 name.size = 1024;
1589
1590 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1591
1592 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1593 struct policy_handle key_handle;
1594
1595 torture_comment(tctx, "EnumKey: %d: %s\n",
1596 r.in.enum_index,
1597 r.out.name->name);
1598
1599 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1600 &key_handle)) {
1601 } else {
1602 test_key(p, tctx, &key_handle,
1603 depth + 1, test_security);
1604 }
1605 }
1606
1607 r.in.enum_index++;
1608
1609 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1610
1611 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1612
1613 if (!W_ERROR_IS_OK(r.out.result) &&
1614 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1615 torture_fail(tctx, "EnumKey failed");
1616 }
1617
1618 return true;
1619}
1620
1621static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1622 struct torture_context *tctx,
1623 struct policy_handle *handle,
1624 const char *valuename)
1625{
1626 struct winreg_QueryMultipleValues r;
1627 uint32_t bufsize=0;
1628
1629 ZERO_STRUCT(r);
1630
1631 r.in.key_handle = handle;
1632 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1633 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1634 r.in.values_in[0].ve_valuename->name = valuename;
1635 /* size needs to be set manually for winreg_ValNameBuf */
1636 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1637
1638 r.in.num_values = 1;
1639 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1640 *r.in.buffer_size = bufsize;
1641 do {
1642 *r.in.buffer_size = bufsize;
1643 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1644 *r.in.buffer_size);
1645
1646 torture_assert_ntstatus_ok(tctx,
1647 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1648 "QueryMultipleValues failed");
1649
1650 talloc_free(r.in.buffer);
1651 bufsize += 0x20;
1652 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1653
1654 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1655
1656 return true;
1657}
1658
1659static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1660 struct torture_context *tctx,
1661 struct policy_handle *handle,
1662 uint32_t num_values,
1663 const char * const *valuenames,
1664 bool existing_value)
1665{
1666 struct winreg_QueryMultipleValues r;
1667 uint32_t bufsize = 0;
1668 int i;
1669
1670 torture_comment(tctx, "Testing QueryMultipleValues\n");
1671
1672 ZERO_STRUCT(r);
1673
1674 r.in.key_handle = handle;
1675 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1676 r.in.buffer_size = r.out.buffer_size = &bufsize;
1677
1678 torture_assert_ntstatus_ok(tctx,
1679 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1680 "QueryMultipleValues failed");
1681 torture_assert_werr_ok(tctx, r.out.result,
1682 "QueryMultipleValues failed");
1683
1684 /* this test crashes w2k8 remote registry */
1685#if 0
1686 r.in.num_values = num_values;
1687 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1688
1689 torture_assert_ntstatus_ok(tctx,
1690 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1691 "QueryMultipleValues failed");
1692 torture_assert_werr_ok(tctx, r.out.result,
1693 "QueryMultipleValues failed");
1694#endif
1695 r.in.num_values = num_values;
1696 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1697 for (i=0; i < r.in.num_values; i++) {
1698 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1699 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1700 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1701 }
1702
1703 torture_assert_ntstatus_ok(tctx,
1704 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1705 "QueryMultipleValues failed");
1706 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1707 "QueryMultipleValues failed");
1708
1709 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1710 return true;
1711 }
1712
1713 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1714 *r.in.buffer_size = 0xff;
1715 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1716
1717 torture_assert_ntstatus_ok(tctx,
1718 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1719 "QueryMultipleValues failed");
1720 }
1721
1722 torture_assert_werr_ok(tctx, r.out.result,
1723 "QueryMultipleValues failed");
1724
1725 return true;
1726}
1727
1728
1729static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1730 struct torture_context *tctx,
1731 struct policy_handle *handle,
1732 uint32_t num_values,
1733 const char * const *valuenames,
1734 bool existing_value)
1735{
1736 struct winreg_QueryMultipleValues2 r;
1737 uint32_t offered = 0, needed;
1738 int i;
1739
1740 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1741
1742 ZERO_STRUCT(r);
1743
1744 r.in.key_handle = handle;
1745 r.in.offered = &offered;
1746 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1747 r.out.needed = &needed;
1748
1749 torture_assert_ntstatus_ok(tctx,
1750 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1751 "QueryMultipleValues2 failed");
1752 torture_assert_werr_ok(tctx, r.out.result,
1753 "QueryMultipleValues2 failed");
1754
1755 /* this test crashes w2k8 remote registry */
1756#if 0
1757 r.in.num_values = num_values;
1758 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1759
1760 torture_assert_ntstatus_ok(tctx,
1761 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1762 "QueryMultipleValues2 failed");
1763 torture_assert_werr_ok(tctx, r.out.result,
1764 "QueryMultipleValues2 failed");
1765#endif
1766 r.in.num_values = num_values;
1767 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1768 for (i=0; i < r.in.num_values; i++) {
1769 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1770 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1771 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1772 }
1773
1774 torture_assert_ntstatus_ok(tctx,
1775 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1776 "QueryMultipleValues2 failed");
1777 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1778 "QueryMultipleValues2 failed");
1779
1780 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1781 return true;
1782 }
1783
1784 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1785 *r.in.offered = *r.out.needed;
1786 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1787
1788 torture_assert_ntstatus_ok(tctx,
1789 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1790 "QueryMultipleValues2 failed");
1791 }
1792
1793 torture_assert_werr_ok(tctx, r.out.result,
1794 "QueryMultipleValues2 failed");
1795
1796 return true;
1797}
1798
1799static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1800 struct torture_context *tctx,
1801 struct policy_handle *handle,
1802 const char *valuename)
1803{
1804 struct winreg_QueryMultipleValues2 r;
1805 uint32_t offered = 0, needed;
1806
1807 ZERO_STRUCT(r);
1808
1809 r.in.key_handle = handle;
1810 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1811 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1812 r.in.values_in[0].ve_valuename->name = valuename;
1813 /* size needs to be set manually for winreg_ValNameBuf */
1814 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1815
1816 r.in.num_values = 1;
1817 r.in.offered = &offered;
1818 r.out.needed = &needed;
1819
1820 torture_assert_ntstatus_ok(tctx,
1821 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1822 "QueryMultipleValues2 failed");
1823 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1824 *r.in.offered = *r.out.needed;
1825 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1826
1827 torture_assert_ntstatus_ok(tctx,
1828 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1829 "QueryMultipleValues2 failed");
1830 }
1831
1832 torture_assert_werr_ok(tctx, r.out.result,
1833 "QueryMultipleValues2 failed");
1834
1835 return true;
1836}
1837
1838static bool test_QueryValue(struct dcerpc_binding_handle *b,
1839 struct torture_context *tctx,
1840 struct policy_handle *handle,
1841 const char *valuename)
1842{
1843 struct winreg_QueryValue r;
1844 NTSTATUS status;
1845 enum winreg_Type zero_type = 0;
1846 uint32_t offered = 0xfff;
1847 uint32_t zero = 0;
1848
1849 ZERO_STRUCT(r);
1850 r.in.handle = handle;
1851 r.in.data = NULL;
1852 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1853 r.in.value_name->name = valuename;
1854 r.in.type = &zero_type;
1855 r.in.data_size = &offered;
1856 r.in.data_length = &zero;
1857
1858 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1859 if (NT_STATUS_IS_ERR(status)) {
1860 torture_fail(tctx, "QueryValue failed");
1861 }
1862
1863 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1864
1865 return true;
1866}
1867
1868static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1869 struct torture_context *tctx,
1870 struct policy_handle *handle,
1871 const char *valuename,
1872 bool existing_value)
1873{
1874 struct winreg_QueryValue r;
1875 struct winreg_String value_name;
1876 enum winreg_Type type = REG_NONE;
1877 uint32_t data_size = 0;
1878 uint32_t real_data_size = 0;
1879 uint32_t data_length = 0;
1880 uint8_t *data = NULL;
1881 WERROR expected_error = WERR_BADFILE;
1882 const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1883
1884 if (valuename == NULL) {
1885 expected_error = WERR_INVALID_PARAM;
1886 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1887 }
1888
1889 ZERO_STRUCT(r);
1890
1891 init_winreg_String(&value_name, NULL);
1892
1893 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1894
1895 r.in.handle = handle;
1896 r.in.value_name = &value_name;
1897
1898 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1899 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1900 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1901
1902 init_winreg_String(&value_name, valuename);
1903 r.in.value_name = &value_name;
1904
1905 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1906 "QueryValue failed");
1907 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1908 "expected WERR_INVALID_PARAM for missing type length and size");
1909
1910 r.in.type = &type;
1911 r.out.type = &type;
1912 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1913 "QueryValue failed");
1914 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1915 "expected WERR_INVALID_PARAM for missing length and size");
1916
1917 r.in.data_length = &data_length;
1918 r.out.data_length = &data_length;
1919 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1920 "QueryValue failed");
1921 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1922 "expected WERR_INVALID_PARAM for missing size");
1923
1924 r.in.data_size = &data_size;
1925 r.out.data_size = &data_size;
1926 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1927 "QueryValue failed");
1928 if (existing_value) {
1929 torture_assert_werr_ok(tctx, r.out.result,
1930 "QueryValue failed");
1931 } else {
1932 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1933 errmsg_nonexisting);
1934 }
1935
1936 real_data_size = *r.out.data_size;
1937
1938 data = talloc_zero_array(tctx, uint8_t, 0);
1939 r.in.data = data;
1940 r.out.data = data;
1941 *r.in.data_size = 0;
1942 *r.out.data_size = 0;
1943 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1944 "QueryValue failed");
1945 if (existing_value) {
1946 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1947 "expected WERR_MORE_DATA for query with too small buffer");
1948 } else {
1949 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1950 errmsg_nonexisting);
1951 }
1952
1953 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1954 r.in.data = data;
1955 r.out.data = data;
1956 r.in.data_size = &real_data_size;
1957 r.out.data_size = &real_data_size;
1958 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1959 "QueryValue failed");
1960 if (existing_value) {
1961 torture_assert_werr_ok(tctx, r.out.result,
1962 "QueryValue failed");
1963 } else {
1964 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1965 errmsg_nonexisting);
1966 }
1967
1968 return true;
1969}
1970
1971static bool test_EnumValue(struct dcerpc_binding_handle *b,
1972 struct torture_context *tctx,
1973 struct policy_handle *handle, int max_valnamelen,
1974 int max_valbufsize)
1975{
1976 struct winreg_EnumValue r;
1977 enum winreg_Type type = 0;
1978 uint32_t size = max_valbufsize, zero = 0;
1979 bool ret = true;
1980 uint8_t *data = NULL;
1981 struct winreg_ValNameBuf name;
1982 char n = '\0';
1983
1984 ZERO_STRUCT(r);
1985 r.in.handle = handle;
1986 r.in.enum_index = 0;
1987 r.in.name = &name;
1988 r.out.name = &name;
1989 r.in.type = &type;
1990 r.in.length = &zero;
1991 r.in.size = &size;
1992
1993 do {
1994 name.name = &n;
1995 name.size = max_valnamelen + 2;
1996 name.length = 0;
1997
1998 data = NULL;
1999 if (size) {
2000 data = (uint8_t *) talloc_array(tctx, uint8_t *, size);
2001 }
2002 r.in.value = data;
2003
2004 torture_assert_ntstatus_ok(tctx,
2005 dcerpc_winreg_EnumValue_r(b, tctx, &r),
2006 "EnumValue failed");
2007
2008 if (W_ERROR_IS_OK(r.out.result)) {
2009 ret &= test_QueryValue(b, tctx, handle,
2010 r.out.name->name);
2011 ret &= test_QueryMultipleValues(b, tctx, handle,
2012 r.out.name->name);
2013 ret &= test_QueryMultipleValues2(b, tctx, handle,
2014 r.out.name->name);
2015 }
2016
2017 talloc_free(data);
2018
2019 r.in.enum_index++;
2020 } while (W_ERROR_IS_OK(r.out.result));
2021
2022 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2023 "EnumValue failed");
2024
2025 return ret;
2026}
2027
2028static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2029 struct torture_context *tctx)
2030{
2031 struct winreg_AbortSystemShutdown r;
2032 uint16_t server = 0x0;
2033
2034 ZERO_STRUCT(r);
2035 r.in.server = &server;
2036
2037 torture_assert_ntstatus_ok(tctx,
2038 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2039 "AbortSystemShutdown failed");
2040
2041 torture_assert_werr_ok(tctx, r.out.result,
2042 "AbortSystemShutdown failed");
2043
2044 return true;
2045}
2046
2047static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2048 struct dcerpc_pipe *p)
2049{
2050 struct winreg_InitiateSystemShutdown r;
2051 uint16_t hostname = 0x0;
2052 struct dcerpc_binding_handle *b = p->binding_handle;
2053
2054 ZERO_STRUCT(r);
2055 r.in.hostname = &hostname;
2056 r.in.message = talloc(tctx, struct lsa_StringLarge);
2057 init_lsa_StringLarge(r.in.message, "spottyfood");
2058 r.in.force_apps = 1;
2059 r.in.timeout = 30;
2060 r.in.do_reboot = 1;
2061
2062 torture_assert_ntstatus_ok(tctx,
2063 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2064 "InitiateSystemShutdown failed");
2065
2066 torture_assert_werr_ok(tctx, r.out.result,
2067 "InitiateSystemShutdown failed");
2068
2069 return test_AbortSystemShutdown(b, tctx);
2070}
2071
2072
2073static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2074 struct dcerpc_pipe *p)
2075{
2076 struct winreg_InitiateSystemShutdownEx r;
2077 uint16_t hostname = 0x0;
2078 struct dcerpc_binding_handle *b = p->binding_handle;
2079
2080 ZERO_STRUCT(r);
2081 r.in.hostname = &hostname;
2082 r.in.message = talloc(tctx, struct lsa_StringLarge);
2083 init_lsa_StringLarge(r.in.message, "spottyfood");
2084 r.in.force_apps = 1;
2085 r.in.timeout = 30;
2086 r.in.do_reboot = 1;
2087 r.in.reason = 0;
2088
2089 torture_assert_ntstatus_ok(tctx,
2090 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2091 "InitiateSystemShutdownEx failed");
2092
2093 torture_assert_werr_ok(tctx, r.out.result,
2094 "InitiateSystemShutdownEx failed");
2095
2096 return test_AbortSystemShutdown(b, tctx);
2097}
2098#define MAX_DEPTH 2 /* Only go this far down the tree */
2099
2100static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2101 struct policy_handle *handle, int depth,
2102 bool test_security)
2103{
2104 struct dcerpc_binding_handle *b = p->binding_handle;
2105 uint32_t max_valnamelen = 0;
2106 uint32_t max_valbufsize = 0;
2107
2108 if (depth == MAX_DEPTH)
2109 return true;
2110
2111 if (!test_QueryInfoKey(b, tctx, handle, NULL,
2112 &max_valnamelen, &max_valbufsize)) {
2113 }
2114
2115 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2116 }
2117
2118 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2119 }
2120
2121 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2122 }
2123
2124 if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2125 }
2126
2127 if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2128 }
2129
2130 test_CloseKey(b, tctx, handle);
2131
2132 return true;
2133}
2134
2135static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2136 struct torture_context *tctx,
2137 struct policy_handle *handle)
2138{
2139 const char *value_name = TEST_VALUE;
2140 uint32_t value = 0x12345678;
2141 uint64_t value2 = 0x12345678;
2142 const char *string = "torture";
2143 const char *array[2];
2144 DATA_BLOB blob;
2145 enum winreg_Type types[] = {
2146 REG_DWORD,
2147 REG_DWORD_BIG_ENDIAN,
2148 REG_QWORD,
2149 REG_BINARY,
2150 REG_SZ,
2151 REG_MULTI_SZ
2152 };
2153 int t;
2154
2155 array[0] = "array0";
2156 array[1] = NULL;
2157
2158 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2159
2160 for (t=0; t < ARRAY_SIZE(types); t++) {
2161
2162 enum winreg_Type w_type;
2163 uint32_t w_size, w_length;
2164 uint8_t *w_data;
2165
2166 switch (types[t]) {
2167 case REG_DWORD:
2168 case REG_DWORD_BIG_ENDIAN:
2169 blob = data_blob_talloc_zero(tctx, 4);
2170 SIVAL(blob.data, 0, value);
2171 break;
2172 case REG_QWORD:
2173 blob = data_blob_talloc_zero(tctx, 8);
2174 SBVAL(blob.data, 0, value2);
2175 break;
2176 case REG_BINARY:
2177 blob = data_blob_string_const("binary_blob");
2178 break;
2179 case REG_SZ:
2180 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2181 break;
2182 case REG_MULTI_SZ:
2183 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2184 break;
2185 default:
2186 break;
2187 }
2188
2189 torture_assert(tctx,
2190 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2191 "test_SetValue failed");
2192 torture_assert(tctx,
2193 test_QueryValue_full(b, tctx, handle, value_name, true),
2194 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2195 torture_assert(tctx,
2196 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2197 "test_winreg_QueryValue failed");
2198 torture_assert(tctx,
2199 test_DeleteValue(b, tctx, handle, value_name),
2200 "test_DeleteValue failed");
2201
2202 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2203 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2204 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2205 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2206 }
2207
2208 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2209
2210 return true;
2211}
2212
2213static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2214 struct torture_context *tctx,
2215 struct policy_handle *handle)
2216{
2217 DATA_BLOB blob;
2218 const char *values[] = {
2219 "torture_value",
2220 "torture value",
2221 "torture,value",
2222 "torture;value",
2223 "torture/value",
2224 "torture\\value",
2225 "torture_value_name",
2226 "torture value name",
2227 "torture,value,name",
2228 "torture;value;name",
2229 "torture/value/name",
2230 "torture\\value\\name",
2231 };
2232 int i;
2233
2234 torture_comment(tctx, "Testing SetValue (values)\n");
2235
2236 for (i=0; i < ARRAY_SIZE(values); i++) {
2237
2238 enum winreg_Type w_type;
2239 uint32_t w_size, w_length;
2240 uint8_t *w_data;
2241
2242 blob = data_blob_talloc(tctx, NULL, 32);
2243
2244 generate_random_buffer(blob.data, 32);
2245
2246 torture_assert(tctx,
2247 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2248 "test_SetValue failed");
2249 torture_assert(tctx,
2250 test_QueryValue_full(b, tctx, handle, values[i], true),
2251 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2252 torture_assert(tctx,
2253 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2254 "test_winreg_QueryValue failed");
2255 torture_assert(tctx,
2256 test_DeleteValue(b, tctx, handle, values[i]),
2257 "test_DeleteValue failed");
2258
2259 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2260 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2261 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2262 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2263 }
2264
2265 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2266
2267 return true;
2268}
2269
2270typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2271
2272static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2273 struct torture_context *tctx,
2274 struct policy_handle *handle)
2275{
2276 const char *value_name = TEST_VALUE;
2277 enum winreg_Type types[] = {
2278 REG_NONE,
2279 REG_SZ,
2280 REG_EXPAND_SZ,
2281 REG_BINARY,
2282 REG_DWORD,
2283 REG_DWORD_BIG_ENDIAN,
2284 REG_LINK,
2285 REG_MULTI_SZ,
2286 REG_RESOURCE_LIST,
2287 REG_FULL_RESOURCE_DESCRIPTOR,
2288 REG_RESOURCE_REQUIREMENTS_LIST,
2289 REG_QWORD,
2290 12,
2291 13,
2292 14,
2293 55,
2294 123456,
2295 653210,
2296 __LINE__
2297 };
2298 int t, l;
2299
2300 if (torture_setting_bool(tctx, "samba4", false)) {
2301 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2302 }
2303
2304 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2305
2306 for (t=0; t < ARRAY_SIZE(types); t++) {
2307 for (l=0; l < 16; l++) {
2308
2309 enum winreg_Type w_type;
2310 uint32_t w_size, w_length;
2311 uint8_t *w_data;
2312
2313 uint32_t size;
2314 uint8_t *data;
2315
2316 size = l;
2317 data = talloc_array(tctx, uint8_t, size);
2318
2319 generate_random_buffer(data, size);
2320
2321 torture_assert(tctx,
2322 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2323 "test_SetValue failed");
2324
2325 torture_assert(tctx,
2326 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2327 "test_winreg_QueryValue failed");
2328
2329 torture_assert(tctx,
2330 test_DeleteValue(b, tctx, handle, value_name),
2331 "test_DeleteValue failed");
2332
2333 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2334 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2335 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2336 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2337 }
2338 }
2339
2340 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2341
2342 return true;
2343}
2344
2345static bool test_create_keynames(struct dcerpc_binding_handle *b,
2346 struct torture_context *tctx,
2347 struct policy_handle *handle)
2348{
2349 const char *keys[] = {
2350 "torture_key",
2351 "torture key",
2352 "torture,key",
2353 "torture/key",
2354 "torture\\key",
2355 };
2356 int i;
2357
2358 for (i=0; i < ARRAY_SIZE(keys); i++) {
2359
2360 enum winreg_CreateAction action_taken;
2361 struct policy_handle new_handle;
2362 char *q, *tmp;
2363
2364 torture_assert(tctx,
2365 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2366 REG_OPTION_NON_VOLATILE,
2367 SEC_FLAG_MAXIMUM_ALLOWED,
2368 NULL,
2369 WERR_OK,
2370 &action_taken,
2371 &new_handle),
2372 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2373
2374 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2375
2376 torture_assert(tctx,
2377 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2378 "failed to delete key");
2379
2380 torture_assert(tctx,
2381 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2382 "failed 2nd delete key");
2383
2384 tmp = talloc_strdup(tctx, keys[i]);
2385
2386 q = strchr(tmp, '\\');
2387 if (q != NULL) {
2388 *q = '\0';
2389 q++;
2390
2391 torture_assert(tctx,
2392 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2393 "failed to delete key");
2394
2395 torture_assert(tctx,
2396 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2397 "failed 2nd delete key");
2398 }
2399 }
2400
2401 return true;
2402}
2403
2404#define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2405#define VALUE_CURRENT_VERSION "CurrentVersion"
2406#define VALUE_SYSTEM_ROOT "SystemRoot"
2407
2408static const struct {
2409 const char *values[3];
2410 uint32_t num_values;
2411 bool existing_value;
2412 const char *error_message;
2413} multiple_values_tests[] = {
2414 {
2415 .values = { VALUE_CURRENT_VERSION, NULL, NULL },
2416 .num_values = 1,
2417 .existing_value = true,
2418 .error_message = NULL
2419 },{
2420 .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2421 .num_values = 1,
2422 .existing_value = true,
2423 .error_message = NULL
2424 },{
2425 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2426 .num_values = 2,
2427 .existing_value = true,
2428 .error_message = NULL
2429 },{
2430 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2431 VALUE_CURRENT_VERSION },
2432 .num_values = 3,
2433 .existing_value = true,
2434 .error_message = NULL
2435 },{
2436 .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2437 .num_values = 3,
2438 .existing_value = false,
2439 .error_message = NULL
2440 },{
2441 .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2442 .num_values = 3,
2443 .existing_value = false,
2444 .error_message = NULL
2445 },{
2446 .values = { "IDoNotExist", NULL, NULL },
2447 .num_values = 1,
2448 .existing_value = false,
2449 .error_message = NULL
2450 },{
2451 .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2452 .num_values = 2,
2453 .existing_value = false,
2454 .error_message = NULL
2455 },{
2456 .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2457 .num_values = 2,
2458 .existing_value = false,
2459 .error_message = NULL
2460 }
2461};
2462
2463static bool test_HKLM_wellknown(struct torture_context *tctx,
2464 struct dcerpc_binding_handle *b,
2465 struct policy_handle *handle)
2466{
2467 struct policy_handle newhandle;
2468 int i;
2469
2470 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2471 if (torture_setting_bool(tctx, "samba3", false)) {
2472 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2473 KEY_CURRENT_VERSION,
2474 REG_OPTION_NON_VOLATILE,
2475 KEY_QUERY_VALUE,
2476 &newhandle,
2477 WERR_OK),
2478 "failed to open current version key");
2479 } else {
2480 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2481 "failed to open current version key");
2482 }
2483
2484 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2485 "failed to query current version");
2486 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2487 "succeeded to query nonexistent value");
2488 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2489 "succeeded to query value with NULL name");
2490 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2491 "succeeded to query nonexistent default value (\"\")");
2492
2493 if (torture_setting_bool(tctx, "samba4", false)) {
2494 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2495 goto close_key;
2496 }
2497
2498 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2499 const char *msg;
2500 msg = talloc_asprintf(tctx,
2501 "failed to query %d %sexisting values\n",
2502 multiple_values_tests[i].num_values,
2503 multiple_values_tests[i].existing_value ? "":"non");
2504
2505 torture_assert(tctx,
2506 test_QueryMultipleValues_full(b, tctx, &newhandle,
2507 multiple_values_tests[i].num_values,
2508 multiple_values_tests[i].values,
2509 multiple_values_tests[i].existing_value),
2510 msg);
2511 torture_assert(tctx,
2512 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2513 multiple_values_tests[i].num_values,
2514 multiple_values_tests[i].values,
2515 multiple_values_tests[i].existing_value),
2516 msg);
2517 }
2518
2519 close_key:
2520 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2521 "failed to close current version key");
2522
2523 return true;
2524}
2525
2526static bool test_OpenHive(struct torture_context *tctx,
2527 struct dcerpc_binding_handle *b,
2528 struct policy_handle *handle,
2529 int hkey)
2530{
2531 struct winreg_OpenHKLM r;
2532
2533 r.in.system_name = 0;
2534 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2535 r.out.handle = handle;
2536
2537 switch (hkey) {
2538 case HKEY_LOCAL_MACHINE:
2539 torture_assert_ntstatus_ok(tctx,
2540 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2541 "failed to open HKLM");
2542 torture_assert_werr_ok(tctx, r.out.result,
2543 "failed to open HKLM");
2544 break;
2545 case HKEY_CURRENT_USER:
2546 torture_assert_ntstatus_ok(tctx,
2547 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2548 "failed to open HKCU");
2549 torture_assert_werr_ok(tctx, r.out.result,
2550 "failed to open HKCU");
2551 break;
2552 case HKEY_USERS:
2553 torture_assert_ntstatus_ok(tctx,
2554 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2555 "failed to open HKU");
2556 torture_assert_werr_ok(tctx, r.out.result,
2557 "failed to open HKU");
2558 break;
2559 case HKEY_CLASSES_ROOT:
2560 torture_assert_ntstatus_ok(tctx,
2561 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2562 "failed to open HKCR");
2563 torture_assert_werr_ok(tctx, r.out.result,
2564 "failed to open HKCR");
2565 break;
2566 default:
2567 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2568 return false;
2569 }
2570
2571 return true;
2572}
2573
2574static bool test_volatile_keys(struct torture_context *tctx,
2575 struct dcerpc_binding_handle *b,
2576 struct policy_handle *handle,
2577 int hkey)
2578{
2579 struct policy_handle new_handle, hive_handle;
2580 enum winreg_CreateAction action_taken;
2581
2582 torture_comment(tctx, "Testing VOLATILE key\n");
2583
2584 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2585
2586 torture_assert(tctx,
2587 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2588 REG_OPTION_VOLATILE,
2589 SEC_FLAG_MAXIMUM_ALLOWED,
2590 NULL,
2591 WERR_OK,
2592 &action_taken,
2593 &new_handle),
2594 "failed to create REG_OPTION_VOLATILE type key");
2595
2596 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2597
2598 torture_assert(tctx,
2599 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2600 REG_OPTION_NON_VOLATILE,
2601 SEC_FLAG_MAXIMUM_ALLOWED,
2602 NULL,
2603 WERR_CHILD_MUST_BE_VOLATILE,
2604 NULL,
2605 NULL),
2606 "failed to fail create REG_OPTION_VOLATILE type key");
2607
2608 torture_assert(tctx,
2609 test_CloseKey(b, tctx, &new_handle),
2610 "failed to close");
2611
2612 torture_assert(tctx,
2613 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2614 REG_OPTION_NON_VOLATILE,
2615 SEC_FLAG_MAXIMUM_ALLOWED,
2616 &new_handle,
2617 WERR_OK),
2618 "failed to open volatile key");
2619
2620 torture_assert(tctx,
2621 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2622 "failed to delete key");
2623
2624 torture_assert(tctx,
2625 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2626 REG_OPTION_VOLATILE,
2627 SEC_FLAG_MAXIMUM_ALLOWED,
2628 NULL,
2629 WERR_OK,
2630 &action_taken,
2631 &new_handle),
2632 "failed to create REG_OPTION_VOLATILE type key");
2633
2634 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2635
2636 torture_assert(tctx,
2637 test_CloseKey(b, tctx, &new_handle),
2638 "failed to close");
2639
2640 torture_assert(tctx,
2641 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2642 REG_OPTION_VOLATILE,
2643 SEC_FLAG_MAXIMUM_ALLOWED,
2644 &new_handle,
2645 WERR_OK),
2646 "failed to open volatile key");
2647
2648 torture_assert(tctx,
2649 test_CloseKey(b, tctx, &new_handle),
2650 "failed to close");
2651
2652 torture_assert(tctx,
2653 test_OpenHive(tctx, b, &hive_handle, hkey),
2654 "failed top open hive");
2655
2656 torture_assert(tctx,
2657 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2658 REG_OPTION_VOLATILE,
2659 SEC_FLAG_MAXIMUM_ALLOWED,
2660 &new_handle,
2661 WERR_BADFILE),
2662 "failed to open volatile key");
2663
2664 torture_assert(tctx,
2665 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2666 REG_OPTION_NON_VOLATILE,
2667 SEC_FLAG_MAXIMUM_ALLOWED,
2668 &new_handle,
2669 WERR_BADFILE),
2670 "failed to open volatile key");
2671
2672 torture_assert(tctx,
2673 test_CloseKey(b, tctx, &hive_handle),
2674 "failed to close");
2675
2676 torture_assert(tctx,
2677 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2678 "failed to delete key");
2679
2680
2681 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2682
2683 return true;
2684}
2685
2686static const char *kernel_mode_registry_path(struct torture_context *tctx,
2687 int hkey,
2688 const char *sid_string,
2689 const char *path)
2690{
2691 switch (hkey) {
2692 case HKEY_LOCAL_MACHINE:
2693 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2694 case HKEY_CURRENT_USER:
2695 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2696 case HKEY_USERS:
2697 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2698 case HKEY_CLASSES_ROOT:
2699 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2700 default:
2701 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2702 return NULL;
2703 }
2704}
2705
2706static bool test_symlink_keys(struct torture_context *tctx,
2707 struct dcerpc_binding_handle *b,
2708 struct policy_handle *handle,
2709 const char *key,
2710 int hkey)
2711{
2712 struct policy_handle new_handle;
2713 enum winreg_CreateAction action_taken;
2714 DATA_BLOB blob;
2715 uint32_t value = 42;
2716 const char *test_key_symlink_dest;
2717 const char *test_key_symlink;
2718 const char *kernel_mode_path;
2719
2720 /* disable until we know how to delete a symbolic link */
2721 torture_skip(tctx, "symlink test disabled");
2722
2723 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2724
2725 /* create destination key with testvalue */
2726 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2727 key, TEST_KEY_SYMLINK);
2728 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2729 key, TEST_KEY_SYMLINK_DEST);
2730
2731 test_DeleteKey(b, tctx, handle, test_key_symlink);
2732
2733 torture_assert(tctx,
2734 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2735 0,
2736 SEC_FLAG_MAXIMUM_ALLOWED,
2737 NULL,
2738 WERR_OK,
2739 &action_taken,
2740 &new_handle),
2741 "failed to create symlink destination");
2742
2743 blob = data_blob_talloc_zero(tctx, 4);
2744 SIVAL(blob.data, 0, value);
2745
2746 torture_assert(tctx,
2747 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2748 "failed to create TestValue");
2749
2750 torture_assert(tctx,
2751 test_CloseKey(b, tctx, &new_handle),
2752 "failed to close");
2753
2754 /* create symlink */
2755
2756 torture_assert(tctx,
2757 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2758 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2759 SEC_FLAG_MAXIMUM_ALLOWED,
2760 NULL,
2761 WERR_OK,
2762 &action_taken,
2763 &new_handle),
2764 "failed to create REG_OPTION_CREATE_LINK type key");
2765
2766 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2767
2768 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2769
2770 torture_assert(tctx,
2771 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2772 kernel_mode_path,
2773 strlen(kernel_mode_path), /* not NULL terminated */
2774 &blob.data, &blob.length,
2775 false),
2776 "failed to convert");
2777
2778 torture_assert(tctx,
2779 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2780 "failed to create SymbolicLinkValue value");
2781
2782 torture_assert(tctx,
2783 test_CloseKey(b, tctx, &new_handle),
2784 "failed to close");
2785
2786 /* test follow symlink */
2787
2788 torture_assert(tctx,
2789 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2790 0,
2791 SEC_FLAG_MAXIMUM_ALLOWED,
2792 &new_handle,
2793 WERR_OK),
2794 "failed to follow symlink key");
2795
2796 torture_assert(tctx,
2797 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2798 "failed to query value");
2799
2800 torture_assert(tctx,
2801 test_CloseKey(b, tctx, &new_handle),
2802 "failed to close");
2803
2804 /* delete link */
2805
2806 torture_assert(tctx,
2807 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2808 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2809 SEC_FLAG_MAXIMUM_ALLOWED,
2810 &new_handle,
2811 WERR_OK),
2812 "failed to open symlink key");
2813
2814 torture_assert(tctx,
2815 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2816 "failed to delete value SymbolicLinkValue");
2817
2818 torture_assert(tctx,
2819 test_CloseKey(b, tctx, &new_handle),
2820 "failed to close");
2821
2822 torture_assert(tctx,
2823 test_DeleteKey(b, tctx, handle, test_key_symlink),
2824 "failed to delete key");
2825
2826 /* delete destination */
2827
2828 torture_assert(tctx,
2829 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2830 "failed to delete key");
2831
2832 return true;
2833}
2834
2835static bool test_CreateKey_keytypes(struct torture_context *tctx,
2836 struct dcerpc_binding_handle *b,
2837 struct policy_handle *handle,
2838 const char *key,
2839 int hkey)
2840{
2841
2842 if (torture_setting_bool(tctx, "samba3", false) ||
2843 torture_setting_bool(tctx, "samba4", false)) {
2844 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2845 }
2846
2847 torture_assert(tctx,
2848 test_volatile_keys(tctx, b, handle, hkey),
2849 "failed to test volatile keys");
2850
2851 torture_assert(tctx,
2852 test_symlink_keys(tctx, b, handle, key, hkey),
2853 "failed to test symlink keys");
2854
2855 return true;
2856}
2857
2858static bool test_key_base(struct torture_context *tctx,
2859 struct dcerpc_binding_handle *b,
2860 struct policy_handle *handle,
2861 const char *base_key,
2862 int hkey)
2863{
2864 struct policy_handle newhandle;
2865 bool ret = true, created = false, deleted = false;
2866 bool created3 = false;
2867 const char *test_key1;
2868 const char *test_key3;
2869 const char *test_subkey;
2870
2871 test_Cleanup(b, tctx, handle, base_key);
2872
2873 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2874 torture_comment(tctx,
2875 "CreateKey(%s) failed\n", base_key);
2876 }
2877
2878 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2879
2880 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2881 torture_comment(tctx,
2882 "CreateKey failed - not considering a failure\n");
2883 } else {
2884 created = true;
2885 }
2886
2887 if (created) {
2888 if (!test_FlushKey(b, tctx, handle)) {
2889 torture_comment(tctx, "FlushKey failed\n");
2890 ret = false;
2891 }
2892
2893 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2894 torture_fail(tctx,
2895 "CreateKey failed (OpenKey after Create didn't work)\n");
2896 }
2897
2898 if (hkey == HKEY_CURRENT_USER) {
2899 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2900 "simple SetValue test failed");
2901 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2902 "values SetValue test failed");
2903 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2904 "extended SetValue test failed");
2905 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2906 "keyname CreateKey test failed");
2907 } else {
2908 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2909 "keytype test failed");
2910 }
2911
2912 if (!test_CloseKey(b, tctx, &newhandle)) {
2913 torture_fail(tctx,
2914 "CreateKey failed (CloseKey after Open didn't work)\n");
2915 }
2916
2917 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2918 torture_comment(tctx, "DeleteKey(%s) failed\n",
2919 test_key1);
2920 ret = false;
2921 } else {
2922 deleted = true;
2923 }
2924
2925 if (!test_FlushKey(b, tctx, handle)) {
2926 torture_comment(tctx, "FlushKey failed\n");
2927 ret = false;
2928 }
2929
2930 if (deleted) {
2931 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2932 REG_OPTION_NON_VOLATILE,
2933 SEC_FLAG_MAXIMUM_ALLOWED,
2934 &newhandle,
2935 WERR_BADFILE)) {
2936 torture_comment(tctx,
2937 "DeleteKey failed (OpenKey after Delete "
2938 "did not return WERR_BADFILE)\n");
2939 ret = false;
2940 }
2941 }
2942
2943 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2944
2945 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2946 created3 = true;
2947 }
2948
2949 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2950
2951 if (created3) {
2952 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2953 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2954 torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
2955 ret = false;
2956 }
2957 }
2958
2959 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2960 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
2961 ret = false;
2962 }
2963 }
2964 }
2965
2966 test_Cleanup(b, tctx, handle, base_key);
2967
2968 return ret;
2969}
2970
2971static bool test_key_base_sd(struct torture_context *tctx,
2972 struct dcerpc_pipe *p,
2973 struct policy_handle *handle,
2974 const char *base_key)
2975{
2976 struct policy_handle newhandle;
2977 bool ret = true, created2 = false, created4 = false;
2978 struct dcerpc_binding_handle *b = p->binding_handle;
2979 const char *test_key2;
2980 const char *test_key4;
2981
2982 torture_skip(tctx, "security descriptor test disabled\n");
2983
2984 if (torture_setting_bool(tctx, "samba3", false) ||
2985 torture_setting_bool(tctx, "samba4", false)) {
2986 torture_skip(tctx, "skipping security descriptor tests against Samba");
2987 }
2988
2989 test_Cleanup(b, tctx, handle, base_key);
2990
2991 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2992 torture_comment(tctx,
2993 "CreateKey(%s) failed\n", base_key);
2994 }
2995
2996 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2997
2998 if (test_CreateKey_sd(b, tctx, handle, test_key2,
2999 NULL, &newhandle)) {
3000 created2 = true;
3001 }
3002
3003 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3004 torture_comment(tctx, "CloseKey failed\n");
3005 ret = false;
3006 }
3007
3008 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3009
3010 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3011 created4 = true;
3012 }
3013
3014 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3015 torture_comment(tctx, "CloseKey failed\n");
3016 ret = false;
3017 }
3018
3019 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3020 ret = false;
3021 }
3022
3023 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3024 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3025 ret = false;
3026 }
3027
3028 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3029 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3030 ret = false;
3031 }
3032
3033 test_Cleanup(b, tctx, handle, base_key);
3034
3035 return ret;
3036}
3037
3038static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3039 void *userdata)
3040{
3041 struct policy_handle handle;
3042 bool ret = true;
3043 struct winreg_OpenHKLM r;
3044 struct dcerpc_binding_handle *b = p->binding_handle;
3045 const char *torture_base_key;
3046 int hkey = 0;
3047
3048 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3049
3050 r.in.system_name = 0;
3051 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3052 r.out.handle = &handle;
3053
3054 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3055 "open");
3056
3057 if (!test_GetVersion(b, tctx, &handle)) {
3058 torture_comment(tctx, "GetVersion failed\n");
3059 ret = false;
3060 }
3061
3062 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3063 hkey = HKEY_LOCAL_MACHINE;
3064 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3065 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3066 hkey = HKEY_USERS;
3067 torture_base_key = TEST_KEY_BASE;
3068 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3069 hkey = HKEY_CLASSES_ROOT;
3070 torture_base_key = TEST_KEY_BASE;
3071 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3072 hkey = HKEY_CURRENT_USER;
3073 torture_base_key = TEST_KEY_BASE;
3074 } else {
3075 torture_fail(tctx, "unsupported hkey");
3076 }
3077
3078 if (hkey == HKEY_LOCAL_MACHINE) {
3079 torture_assert(tctx,
3080 test_HKLM_wellknown(tctx, b, &handle),
3081 "failed to test HKLM wellknown keys");
3082 }
3083
3084 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3085 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3086 torture_base_key);
3087 ret = false;
3088 }
3089
3090 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3091 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3092 torture_base_key);
3093 ret = false;
3094 }
3095
3096 /* The HKCR hive has a very large fanout */
3097 if (hkey == HKEY_CLASSES_ROOT) {
3098 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3099 ret = false;
3100 }
3101 } else if (hkey == HKEY_LOCAL_MACHINE) {
3102 /* FIXME we are not allowed to enum values in the HKLM root */
3103 } else {
3104 if (!test_key(p, tctx, &handle, 0, false)) {
3105 ret = false;
3106 }
3107 }
3108
3109 return ret;
3110}
3111
3112struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3113{
3114 struct torture_rpc_tcase *tcase;
3115 struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3116 struct torture_test *test;
3117
3118 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3119 &ndr_table_winreg);
3120
3121 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3122 test_InitiateSystemShutdown);
3123 test->dangerous = true;
3124
3125 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3126 test_InitiateSystemShutdownEx);
3127 test->dangerous = true;
3128
3129 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3130 test_Open,
3131 (void *)dcerpc_winreg_OpenHKLM_r);
3132 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3133 test_Open,
3134 (void *)dcerpc_winreg_OpenHKU_r);
3135 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3136 test_Open,
3137 (void *)dcerpc_winreg_OpenHKCR_r);
3138 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3139 test_Open,
3140 (void *)dcerpc_winreg_OpenHKCU_r);
3141
3142 return suite;
3143}
Note: See TracBrowser for help on using the repository browser.