Don't fail if the domain has a trust already.
[Samba/vfs_proxy.git] / source4 / torture / rpc / winreg.c
blob8b602ef652dce3d270b29fa1f1f9ab51e07e8edd
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007
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.
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.
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/>.
23 #include "includes.h"
24 #include "torture/torture.h"
25 #include "librpc/gen_ndr/ndr_winreg_c.h"
26 #include "librpc/gen_ndr/ndr_security.h"
27 #include "libcli/security/security.h"
28 #include "torture/rpc/rpc.h"
30 #define TEST_KEY_BASE "smbtorture test"
31 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
32 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
33 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
34 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
35 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
36 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
37 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
39 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
41 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
43 name->string = s;
46 static void init_winreg_String(struct winreg_String *name, const char *s)
48 name->name = s;
49 if (s) {
50 name->name_len = 2 * (strlen_m(s) + 1);
51 name->name_size = name->name_len;
52 } else {
53 name->name_len = 0;
54 name->name_size = 0;
58 static bool test_GetVersion(struct dcerpc_pipe *p,
59 struct torture_context *tctx,
60 struct policy_handle *handle)
62 struct winreg_GetVersion r;
63 uint32_t v;
65 ZERO_STRUCT(r);
66 r.in.handle = handle;
67 r.out.version = &v;
69 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
70 "GetVersion failed");
72 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
74 return true;
77 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
78 struct torture_context *tctx,
79 struct policy_handle *handle)
81 struct winreg_NotifyChangeKeyValue r;
83 r.in.handle = handle;
84 r.in.watch_subtree = true;
85 r.in.notify_filter = 0;
86 r.in.unknown = r.in.unknown2 = 0;
87 init_winreg_String(&r.in.string1, NULL);
88 init_winreg_String(&r.in.string2, NULL);
90 torture_assert_ntstatus_ok(tctx,
91 dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
92 "NotifyChangeKeyValue failed");
94 if (!W_ERROR_IS_OK(r.out.result)) {
95 torture_comment(tctx,
96 "NotifyChangeKeyValue failed - %s - not considering\n",
97 win_errstr(r.out.result));
98 return true;
101 return true;
104 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
105 struct policy_handle *handle, const char *name,
106 const char *class)
108 struct winreg_CreateKey r;
109 struct policy_handle newhandle;
110 enum winreg_CreateAction action_taken = 0;
112 r.in.handle = handle;
113 r.out.new_handle = &newhandle;
114 init_winreg_String(&r.in.name, name);
115 init_winreg_String(&r.in.keyclass, class);
116 r.in.options = 0x0;
117 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
118 r.in.action_taken = r.out.action_taken = &action_taken;
119 r.in.secdesc = NULL;
121 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
122 "CreateKey failed");
124 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
126 return true;
131 createkey testing with a SD
133 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
134 struct torture_context *tctx,
135 struct policy_handle *handle, const char *name,
136 const char *class,
137 struct policy_handle *newhandle)
139 struct winreg_CreateKey r;
140 enum winreg_CreateAction action_taken = 0;
141 struct security_descriptor *sd;
142 DATA_BLOB sdblob;
143 struct winreg_SecBuf secbuf;
145 sd = security_descriptor_dacl_create(tctx,
147 NULL, NULL,
148 SID_NT_AUTHENTICATED_USERS,
149 SEC_ACE_TYPE_ACCESS_ALLOWED,
150 SEC_GENERIC_ALL,
151 SEC_ACE_FLAG_OBJECT_INHERIT |
152 SEC_ACE_FLAG_CONTAINER_INHERIT,
153 NULL);
155 torture_assert_ndr_success(tctx,
156 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
157 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
158 "Failed to push security_descriptor ?!\n");
160 secbuf.sd.data = sdblob.data;
161 secbuf.sd.len = sdblob.length;
162 secbuf.sd.size = sdblob.length;
163 secbuf.length = sdblob.length-10;
164 secbuf.inherit = 0;
166 r.in.handle = handle;
167 r.out.new_handle = newhandle;
168 init_winreg_String(&r.in.name, name);
169 init_winreg_String(&r.in.keyclass, class);
170 r.in.options = 0x0;
171 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
172 r.in.action_taken = r.out.action_taken = &action_taken;
173 r.in.secdesc = &secbuf;
175 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
176 "CreateKey with sd failed");
178 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
180 return true;
183 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
184 struct torture_context *tctx,
185 struct policy_handle *handle,
186 uint32_t *sec_info_ptr,
187 WERROR get_werr,
188 struct security_descriptor **sd_out)
190 struct winreg_GetKeySecurity r;
191 struct security_descriptor *sd = NULL;
192 uint32_t sec_info;
193 DATA_BLOB sdblob;
195 if (sec_info_ptr) {
196 sec_info = *sec_info_ptr;
197 } else {
198 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
201 ZERO_STRUCT(r);
203 r.in.handle = handle;
204 r.in.sec_info = sec_info;
205 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
206 r.in.sd->size = 0x1000;
208 torture_assert_ntstatus_ok(tctx,
209 dcerpc_winreg_GetKeySecurity(p, tctx, &r),
210 "GetKeySecurity failed");
212 torture_assert_werr_equal(tctx, r.out.result, get_werr,
213 "GetKeySecurity failed");
215 sdblob.data = r.out.sd->data;
216 sdblob.length = r.out.sd->len;
218 sd = talloc_zero(tctx, struct security_descriptor);
220 torture_assert_ndr_success(tctx,
221 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
222 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
223 "pull_security_descriptor failed");
225 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
226 NDR_PRINT_DEBUG(security_descriptor, sd);
229 if (sd_out) {
230 *sd_out = sd;
231 } else {
232 talloc_free(sd);
235 return true;
238 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
239 struct torture_context *tctx,
240 struct policy_handle *handle,
241 struct security_descriptor **sd_out)
243 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
246 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
247 struct torture_context *tctx,
248 struct policy_handle *handle,
249 uint32_t *sec_info_ptr,
250 struct security_descriptor *sd,
251 WERROR werr)
253 struct winreg_SetKeySecurity r;
254 struct KeySecurityData *sdata = NULL;
255 DATA_BLOB sdblob;
256 uint32_t sec_info;
258 ZERO_STRUCT(r);
260 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
261 NDR_PRINT_DEBUG(security_descriptor, sd);
264 torture_assert_ndr_success(tctx,
265 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
266 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
267 "push_security_descriptor failed");
269 sdata = talloc_zero(tctx, struct KeySecurityData);
270 sdata->data = sdblob.data;
271 sdata->size = sdblob.length;
272 sdata->len = sdblob.length;
274 if (sec_info_ptr) {
275 sec_info = *sec_info_ptr;
276 } else {
277 sec_info = SECINFO_UNPROTECTED_SACL |
278 SECINFO_UNPROTECTED_DACL;
279 if (sd->owner_sid) {
280 sec_info |= SECINFO_OWNER;
282 if (sd->group_sid) {
283 sec_info |= SECINFO_GROUP;
285 if (sd->sacl) {
286 sec_info |= SECINFO_SACL;
288 if (sd->dacl) {
289 sec_info |= SECINFO_DACL;
293 r.in.handle = handle;
294 r.in.sec_info = sec_info;
295 r.in.sd = sdata;
297 torture_assert_ntstatus_ok(tctx,
298 dcerpc_winreg_SetKeySecurity(p, tctx, &r),
299 "SetKeySecurity failed");
301 torture_assert_werr_equal(tctx, r.out.result, werr,
302 "SetKeySecurity failed");
304 return true;
307 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
308 struct torture_context *tctx,
309 struct policy_handle *handle,
310 struct security_descriptor *sd)
312 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
315 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
316 struct policy_handle *handle)
318 struct winreg_CloseKey r;
320 r.in.handle = r.out.handle = handle;
322 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
323 "CloseKey failed");
325 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
327 return true;
330 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
331 struct policy_handle *handle)
333 struct winreg_FlushKey r;
335 r.in.handle = handle;
337 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
338 "FlushKey failed");
340 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
342 return true;
345 static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
346 struct policy_handle *hive_handle,
347 const char *keyname, uint32_t access_mask,
348 struct policy_handle *key_handle,
349 WERROR open_werr,
350 bool *success)
352 struct winreg_OpenKey r;
354 r.in.parent_handle = hive_handle;
355 init_winreg_String(&r.in.keyname, keyname);
356 r.in.unknown = 0x00000000;
357 r.in.access_mask = access_mask;
358 r.out.handle = key_handle;
360 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
361 "OpenKey failed");
363 torture_assert_werr_equal(tctx, r.out.result, open_werr,
364 "OpenKey failed");
366 if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
367 *success = true;
370 return true;
373 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
374 struct policy_handle *hive_handle,
375 const char *keyname, struct policy_handle *key_handle)
377 return _test_OpenKey(p, tctx, hive_handle, keyname,
378 SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
379 WERR_OK, NULL);
382 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
383 struct policy_handle *handle, const char *key)
385 struct winreg_DeleteKey r;
387 r.in.handle = handle;
389 init_winreg_String(&r.in.key, key);
390 dcerpc_winreg_DeleteKey(p, tctx, &r);
392 return true;
395 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
396 struct torture_context *tctx,
397 struct policy_handle *handle,
398 WERROR get_werr,
399 WERROR set_werr)
401 struct security_descriptor *sd = NULL;
403 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
404 return false;
407 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
408 return false;
411 return true;
414 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
415 struct torture_context *tctx,
416 struct policy_handle *handle,
417 const char *key)
419 struct policy_handle new_handle;
420 bool ret = true;
422 torture_comment(tctx, "SecurityDescriptor get & set\n");
424 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
425 return false;
428 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
429 WERR_OK, WERR_OK)) {
430 ret = false;
433 if (!test_CloseKey(p, tctx, &new_handle)) {
434 return false;
437 return ret;
440 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
441 struct torture_context *tctx,
442 struct policy_handle *handle,
443 uint32_t access_mask,
444 const char *key,
445 WERROR open_werr,
446 WERROR get_werr,
447 WERROR set_werr)
449 struct policy_handle new_handle;
450 bool ret = true;
451 bool got_key = false;
453 if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
454 open_werr, &got_key)) {
455 return false;
458 if (!got_key) {
459 return true;
462 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
463 get_werr, set_werr)) {
464 ret = false;
467 if (!test_CloseKey(p, tctx, &new_handle)) {
468 return false;
471 return ret;
474 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
475 struct torture_context *tctx,
476 struct policy_handle *handle,
477 const struct dom_sid *sid)
479 struct security_descriptor *sd = NULL;
480 int i;
482 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
483 return false;
486 if (!sd || !sd->dacl) {
487 return false;
490 for (i = 0; i < sd->dacl->num_aces; i++) {
491 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
492 return true;
496 return false;
499 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
500 struct torture_context *tctx,
501 struct policy_handle *handle,
502 const char *key,
503 const struct dom_sid *sid)
505 struct policy_handle new_handle;
506 bool ret = true;
508 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
509 return false;
512 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
514 test_CloseKey(p, tctx, &new_handle);
516 return ret;
519 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
520 struct torture_context *tctx,
521 struct policy_handle *handle,
522 const struct dom_sid *sid)
524 struct security_descriptor *sd = NULL;
525 int i;
526 uint32_t sec_info = SECINFO_SACL;
528 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
529 return false;
532 if (!sd || !sd->sacl) {
533 return false;
536 for (i = 0; i < sd->sacl->num_aces; i++) {
537 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
538 return true;
542 return false;
545 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
546 struct torture_context *tctx,
547 struct policy_handle *handle,
548 const char *key,
549 const struct dom_sid *sid)
551 struct policy_handle new_handle;
552 bool ret = true;
554 if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
555 &new_handle, WERR_OK, NULL)) {
556 return false;
559 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
561 test_CloseKey(p, tctx, &new_handle);
563 return ret;
566 static bool test_owner_present(struct dcerpc_pipe *p,
567 struct torture_context *tctx,
568 struct policy_handle *handle,
569 const struct dom_sid *sid)
571 struct security_descriptor *sd = NULL;
572 uint32_t sec_info = SECINFO_OWNER;
574 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
575 return false;
578 if (!sd || !sd->owner_sid) {
579 return false;
582 return dom_sid_equal(sd->owner_sid, sid);
585 static bool _test_owner_present(struct dcerpc_pipe *p,
586 struct torture_context *tctx,
587 struct policy_handle *handle,
588 const char *key,
589 const struct dom_sid *sid)
591 struct policy_handle new_handle;
592 bool ret = true;
594 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
595 return false;
598 ret = test_owner_present(p, tctx, &new_handle, sid);
600 test_CloseKey(p, tctx, &new_handle);
602 return ret;
605 static bool test_group_present(struct dcerpc_pipe *p,
606 struct torture_context *tctx,
607 struct policy_handle *handle,
608 const struct dom_sid *sid)
610 struct security_descriptor *sd = NULL;
611 uint32_t sec_info = SECINFO_GROUP;
613 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
614 return false;
617 if (!sd || !sd->group_sid) {
618 return false;
621 return dom_sid_equal(sd->group_sid, sid);
624 static bool _test_group_present(struct dcerpc_pipe *p,
625 struct torture_context *tctx,
626 struct policy_handle *handle,
627 const char *key,
628 const struct dom_sid *sid)
630 struct policy_handle new_handle;
631 bool ret = true;
633 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
634 return false;
637 ret = test_group_present(p, tctx, &new_handle, sid);
639 test_CloseKey(p, tctx, &new_handle);
641 return ret;
644 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
645 struct torture_context *tctx,
646 struct policy_handle *handle,
647 const struct dom_sid *sid,
648 uint8_t flags)
650 struct security_descriptor *sd = NULL;
651 int i;
653 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
654 return false;
657 if (!sd || !sd->dacl) {
658 return false;
661 for (i = 0; i < sd->dacl->num_aces; i++) {
662 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
663 (sd->dacl->aces[i].flags == flags)) {
664 return true;
668 return false;
671 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
672 struct torture_context *tctx,
673 struct policy_handle *handle,
674 const struct security_ace *ace)
676 struct security_descriptor *sd = NULL;
677 int i;
679 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
680 return false;
683 if (!sd || !sd->dacl) {
684 return false;
687 for (i = 0; i < sd->dacl->num_aces; i++) {
688 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
689 return true;
693 return false;
696 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
697 struct torture_context *tctx,
698 struct policy_handle *handle,
699 const char *key,
700 struct security_descriptor *sd)
702 struct policy_handle new_handle;
703 bool ret = true;
705 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
706 return false;
709 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
710 ret = false;
713 if (!test_CloseKey(p, tctx, &new_handle)) {
714 ret = false;
717 return ret;
720 static bool test_BackupSecurity(struct dcerpc_pipe *p,
721 struct torture_context *tctx,
722 struct policy_handle *handle,
723 const char *key,
724 struct security_descriptor **sd)
726 struct policy_handle new_handle;
727 bool ret = true;
729 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
730 return false;
733 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
734 ret = false;
737 if (!test_CloseKey(p, tctx, &new_handle)) {
738 ret = false;
741 return ret;
744 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
745 struct torture_context *tctx,
746 struct policy_handle *handle,
747 const char *key)
749 /* get sd
750 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
751 set sd
752 get sd
753 check ace
754 add subkey
755 get sd
756 check ace
757 add subsubkey
758 get sd
759 check ace
760 del subsubkey
761 del subkey
762 reset sd
765 struct security_descriptor *sd = NULL;
766 struct security_descriptor *sd_orig = NULL;
767 struct security_ace *ace = NULL;
768 struct policy_handle new_handle;
769 NTSTATUS status;
770 bool ret = true;
772 torture_comment(tctx, "SecurityDescriptor inheritance\n");
774 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
775 return false;
778 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
779 return false;
782 sd_orig = security_descriptor_copy(tctx, sd);
783 if (sd_orig == NULL) {
784 return false;
787 ace = security_ace_create(tctx,
788 TEST_SID,
789 SEC_ACE_TYPE_ACCESS_ALLOWED,
790 SEC_STD_REQUIRED,
791 SEC_ACE_FLAG_CONTAINER_INHERIT);
793 status = security_descriptor_dacl_add(sd, ace);
794 if (!NT_STATUS_IS_OK(status)) {
795 printf("failed to add ace: %s\n", nt_errstr(status));
796 return false;
799 /* FIXME: add further tests for these flags */
800 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
801 SEC_DESC_SACL_AUTO_INHERITED;
803 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
804 return false;
807 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
808 printf("new ACE not present!\n");
809 return false;
812 if (!test_CloseKey(p, tctx, &new_handle)) {
813 return false;
816 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
817 ret = false;
818 goto out;
821 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
822 ret = false;
823 goto out;
826 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
827 printf("inherited ACE not present!\n");
828 ret = false;
829 goto out;
832 test_CloseKey(p, tctx, &new_handle);
833 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
834 ret = false;
835 goto out;
838 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
839 ret = false;
840 goto out;
843 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
844 printf("inherited ACE not present!\n");
845 ret = false;
846 goto out;
849 out:
850 test_CloseKey(p, tctx, &new_handle);
851 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
852 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
854 return true;
857 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
858 struct torture_context *tctx,
859 struct policy_handle *handle,
860 const char *key)
862 /* get sd
863 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
864 set sd
865 add subkey/subkey
866 get sd
867 check ace
868 get sd from subkey
869 check ace
870 del subkey/subkey
871 del subkey
872 reset sd
875 struct security_descriptor *sd = NULL;
876 struct security_descriptor *sd_orig = NULL;
877 struct security_ace *ace = NULL;
878 struct policy_handle new_handle;
879 struct dom_sid *sid = NULL;
880 NTSTATUS status;
881 bool ret = true;
882 uint8_t ace_flags = 0x0;
884 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
886 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
887 return false;
890 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
891 return false;
894 sd_orig = security_descriptor_copy(tctx, sd);
895 if (sd_orig == NULL) {
896 return false;
899 ace = security_ace_create(tctx,
900 TEST_SID,
901 SEC_ACE_TYPE_ACCESS_ALLOWED,
902 SEC_STD_REQUIRED,
903 SEC_ACE_FLAG_CONTAINER_INHERIT |
904 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
906 status = security_descriptor_dacl_add(sd, ace);
907 if (!NT_STATUS_IS_OK(status)) {
908 printf("failed to add ace: %s\n", nt_errstr(status));
909 return false;
912 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
913 return false;
916 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
917 printf("new ACE not present!\n");
918 return false;
921 if (!test_CloseKey(p, tctx, &new_handle)) {
922 return false;
925 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
926 return false;
929 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
930 ret = false;
931 goto out;
934 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
935 printf("inherited ACE present but should not!\n");
936 ret = false;
937 goto out;
940 sid = dom_sid_parse_talloc(tctx, TEST_SID);
941 if (sid == NULL) {
942 return false;
945 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
946 printf("inherited trustee SID present but should not!\n");
947 ret = false;
948 goto out;
951 test_CloseKey(p, tctx, &new_handle);
953 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
954 ret = false;
955 goto out;
958 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
959 printf("inherited ACE present but should not!\n");
960 ret = false;
961 goto out;
964 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
965 printf("inherited trustee SID with flags 0x%02x not present!\n",
966 ace_flags);
967 ret = false;
968 goto out;
971 out:
972 test_CloseKey(p, tctx, &new_handle);
973 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
974 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
976 return ret;
979 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
980 struct torture_context *tctx,
981 struct policy_handle *handle,
982 const char *key)
984 bool ret = true;
985 int i;
987 struct winreg_mask_result_table {
988 uint32_t access_mask;
989 WERROR open_werr;
990 WERROR get_werr;
991 WERROR set_werr;
992 } sd_mask_tests[] = {
993 { 0,
994 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
995 { SEC_FLAG_MAXIMUM_ALLOWED,
996 WERR_OK, WERR_OK, WERR_OK },
997 { SEC_STD_WRITE_DAC,
998 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
999 { SEC_FLAG_SYSTEM_SECURITY,
1000 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1003 /* FIXME: before this test can ever run successfully we need a way to
1004 * correctly read a NULL security_descritpor in ndr, get the required
1005 * length, requery, etc.
1008 return true;
1010 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1012 torture_comment(tctx,
1013 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1014 sd_mask_tests[i].access_mask);
1015 torture_comment(tctx,
1016 "expecting: open %s, get: %s, set: %s\n",
1017 win_errstr(sd_mask_tests[i].open_werr),
1018 win_errstr(sd_mask_tests[i].get_werr),
1019 win_errstr(sd_mask_tests[i].set_werr));
1021 if (_test_SecurityDescriptor(p, tctx, handle,
1022 sd_mask_tests[i].access_mask, key,
1023 sd_mask_tests[i].open_werr,
1024 sd_mask_tests[i].get_werr,
1025 sd_mask_tests[i].set_werr)) {
1026 ret = false;
1030 return ret;
1033 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1034 struct torture_context *,
1035 struct policy_handle *,
1036 const char *,
1037 const struct dom_sid *);
1039 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1040 struct torture_context *tctx,
1041 struct policy_handle *handle,
1042 const char *key,
1043 const char *test,
1044 uint32_t access_mask,
1045 uint32_t sec_info,
1046 struct security_descriptor *sd,
1047 WERROR set_werr,
1048 bool expect_present,
1049 bool (*fn) (struct dcerpc_pipe *,
1050 struct torture_context *,
1051 struct policy_handle *,
1052 const char *,
1053 const struct dom_sid *),
1054 const struct dom_sid *sid)
1056 struct policy_handle new_handle;
1057 bool open_success = false;
1059 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1060 "0x%08x, access_mask: 0x%08x\n",
1061 test, sec_info, access_mask);
1063 if (!_test_OpenKey(p, tctx, handle, key,
1064 access_mask,
1065 &new_handle,
1066 WERR_OK,
1067 &open_success)) {
1068 return false;
1071 if (!open_success) {
1072 printf("key did not open\n");
1073 test_CloseKey(p, tctx, &new_handle);
1074 return false;
1077 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1079 set_werr)) {
1080 torture_warning(tctx,
1081 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1082 sec_info);
1083 smb_panic("");
1084 test_CloseKey(p, tctx, &new_handle);
1085 return false;
1088 test_CloseKey(p, tctx, &new_handle);
1090 if (W_ERROR_IS_OK(set_werr)) {
1091 bool present;
1092 present = fn(p, tctx, handle, key, sid);
1093 if ((expect_present) && (!present)) {
1094 torture_warning(tctx,
1095 "%s sid is not present!\n",
1096 test);
1097 return false;
1099 if ((!expect_present) && (present)) {
1100 torture_warning(tctx,
1101 "%s sid is present but not expected!\n",
1102 test);
1103 return false;
1107 return true;
1110 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1111 struct torture_context *tctx,
1112 struct policy_handle *handle,
1113 const char *key)
1115 struct security_descriptor *sd_orig = NULL;
1116 struct dom_sid *sid = NULL;
1117 bool ret = true;
1118 int i, a;
1120 struct security_descriptor *sd_owner =
1121 security_descriptor_dacl_create(tctx,
1123 TEST_SID, NULL, NULL);
1125 struct security_descriptor *sd_group =
1126 security_descriptor_dacl_create(tctx,
1128 NULL, TEST_SID, NULL);
1130 struct security_descriptor *sd_dacl =
1131 security_descriptor_dacl_create(tctx,
1133 NULL, NULL,
1134 TEST_SID,
1135 SEC_ACE_TYPE_ACCESS_ALLOWED,
1136 SEC_GENERIC_ALL,
1138 SID_NT_AUTHENTICATED_USERS,
1139 SEC_ACE_TYPE_ACCESS_ALLOWED,
1140 SEC_GENERIC_ALL,
1142 NULL);
1144 struct security_descriptor *sd_sacl =
1145 security_descriptor_sacl_create(tctx,
1147 NULL, NULL,
1148 TEST_SID,
1149 SEC_ACE_TYPE_SYSTEM_AUDIT,
1150 SEC_GENERIC_ALL,
1151 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1152 NULL);
1154 struct winreg_secinfo_table {
1155 struct security_descriptor *sd;
1156 uint32_t sec_info;
1157 WERROR set_werr;
1158 bool sid_present;
1159 secinfo_verify_fn fn;
1162 struct winreg_secinfo_table sec_info_owner_tests[] = {
1163 { sd_owner, 0, WERR_OK,
1164 false, (secinfo_verify_fn)_test_owner_present },
1165 { sd_owner, SECINFO_OWNER, WERR_OK,
1166 true, (secinfo_verify_fn)_test_owner_present },
1167 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1168 { sd_owner, SECINFO_DACL, WERR_OK,
1169 true, (secinfo_verify_fn)_test_owner_present },
1170 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1173 uint32_t sd_owner_good_access_masks[] = {
1174 SEC_FLAG_MAXIMUM_ALLOWED,
1175 /* SEC_STD_WRITE_OWNER, */
1178 struct winreg_secinfo_table sec_info_group_tests[] = {
1179 { sd_group, 0, WERR_OK,
1180 false, (secinfo_verify_fn)_test_group_present },
1181 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1182 { sd_group, SECINFO_GROUP, WERR_OK,
1183 true, (secinfo_verify_fn)_test_group_present },
1184 { sd_group, SECINFO_DACL, WERR_OK,
1185 true, (secinfo_verify_fn)_test_group_present },
1186 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1189 uint32_t sd_group_good_access_masks[] = {
1190 SEC_FLAG_MAXIMUM_ALLOWED,
1193 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1194 { sd_dacl, 0, WERR_OK,
1195 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1196 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1197 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1198 { sd_dacl, SECINFO_DACL, WERR_OK,
1199 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1200 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1203 uint32_t sd_dacl_good_access_masks[] = {
1204 SEC_FLAG_MAXIMUM_ALLOWED,
1205 SEC_STD_WRITE_DAC,
1208 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1209 { sd_sacl, 0, WERR_OK,
1210 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1211 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1212 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1213 { sd_sacl, SECINFO_DACL, WERR_OK,
1214 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1215 { sd_sacl, SECINFO_SACL, WERR_OK,
1216 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1219 uint32_t sd_sacl_good_access_masks[] = {
1220 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1221 /* SEC_FLAG_SYSTEM_SECURITY, */
1224 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1225 if (sid == NULL) {
1226 return false;
1229 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1230 return false;
1233 /* OWNER */
1235 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1237 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1239 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1240 key,
1241 "OWNER",
1242 sd_owner_good_access_masks[a],
1243 sec_info_owner_tests[i].sec_info,
1244 sec_info_owner_tests[i].sd,
1245 sec_info_owner_tests[i].set_werr,
1246 sec_info_owner_tests[i].sid_present,
1247 sec_info_owner_tests[i].fn,
1248 sid))
1250 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1251 ret = false;
1252 goto out;
1257 /* GROUP */
1259 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1261 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1263 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1264 key,
1265 "GROUP",
1266 sd_group_good_access_masks[a],
1267 sec_info_group_tests[i].sec_info,
1268 sec_info_group_tests[i].sd,
1269 sec_info_group_tests[i].set_werr,
1270 sec_info_group_tests[i].sid_present,
1271 sec_info_group_tests[i].fn,
1272 sid))
1274 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1275 ret = false;
1276 goto out;
1281 /* DACL */
1283 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1285 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1287 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1288 key,
1289 "DACL",
1290 sd_dacl_good_access_masks[a],
1291 sec_info_dacl_tests[i].sec_info,
1292 sec_info_dacl_tests[i].sd,
1293 sec_info_dacl_tests[i].set_werr,
1294 sec_info_dacl_tests[i].sid_present,
1295 sec_info_dacl_tests[i].fn,
1296 sid))
1298 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1299 ret = false;
1300 goto out;
1305 /* SACL */
1307 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1309 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1311 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1312 key,
1313 "SACL",
1314 sd_sacl_good_access_masks[a],
1315 sec_info_sacl_tests[i].sec_info,
1316 sec_info_sacl_tests[i].sd,
1317 sec_info_sacl_tests[i].set_werr,
1318 sec_info_sacl_tests[i].sid_present,
1319 sec_info_sacl_tests[i].fn,
1320 sid))
1322 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1323 ret = false;
1324 goto out;
1329 out:
1330 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1332 return ret;
1335 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1336 struct torture_context *tctx,
1337 struct policy_handle *handle,
1338 const char *key)
1340 bool ret = true;
1342 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1343 printf("test_SecurityDescriptor failed\n");
1344 ret = false;
1347 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1348 printf("test_SecurityDescriptorInheritance failed\n");
1349 ret = false;
1352 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1353 printf("test_SecurityDescriptorBlockInheritance failed\n");
1354 ret = false;
1357 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1358 printf("test_SecurityDescriptorsSecInfo failed\n");
1359 ret = false;
1362 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1363 printf("test_SecurityDescriptorsMasks failed\n");
1364 ret = false;
1367 return ret;
1370 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1371 struct policy_handle *handle, const char *key)
1373 NTSTATUS status;
1374 struct winreg_DeleteKey r;
1376 r.in.handle = handle;
1377 init_winreg_String(&r.in.key, key);
1379 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1381 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1382 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1384 return true;
1387 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1388 struct torture_context *tctx,
1389 struct policy_handle *handle, char *class)
1391 struct winreg_QueryInfoKey r;
1392 uint32_t num_subkeys, max_subkeylen, max_subkeysize,
1393 num_values, max_valnamelen, max_valbufsize,
1394 secdescsize;
1395 NTTIME last_changed_time;
1397 ZERO_STRUCT(r);
1398 r.in.handle = handle;
1399 r.out.num_subkeys = &num_subkeys;
1400 r.out.max_subkeylen = &max_subkeylen;
1401 r.out.max_subkeysize = &max_subkeysize;
1402 r.out.num_values = &num_values;
1403 r.out.max_valnamelen = &max_valnamelen;
1404 r.out.max_valbufsize = &max_valbufsize;
1405 r.out.secdescsize = &secdescsize;
1406 r.out.last_changed_time = &last_changed_time;
1408 r.out.classname = talloc(tctx, struct winreg_String);
1410 r.in.classname = talloc(tctx, struct winreg_String);
1411 init_winreg_String(r.in.classname, class);
1413 torture_assert_ntstatus_ok(tctx,
1414 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1415 "QueryInfoKey failed");
1417 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1419 return true;
1422 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1423 struct policy_handle *handle, int depth,
1424 bool test_security);
1426 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1427 struct policy_handle *handle, int depth,
1428 bool test_security)
1430 struct winreg_EnumKey r;
1431 struct winreg_StringBuf class, name;
1432 NTSTATUS status;
1433 NTTIME t = 0;
1435 class.name = "";
1436 class.size = 1024;
1438 r.in.handle = handle;
1439 r.in.enum_index = 0;
1440 r.in.name = &name;
1441 r.in.keyclass = &class;
1442 r.out.name = &name;
1443 r.in.last_changed_time = &t;
1445 do {
1446 name.name = NULL;
1447 name.size = 1024;
1449 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1451 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1452 struct policy_handle key_handle;
1454 torture_comment(tctx, "EnumKey: %d: %s\n",
1455 r.in.enum_index,
1456 r.out.name->name);
1458 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1459 &key_handle)) {
1460 } else {
1461 test_key(p, tctx, &key_handle,
1462 depth + 1, test_security);
1466 r.in.enum_index++;
1468 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1470 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1472 if (!W_ERROR_IS_OK(r.out.result) &&
1473 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1474 torture_fail(tctx, "EnumKey failed");
1477 return true;
1480 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1481 struct torture_context *tctx,
1482 struct policy_handle *handle,
1483 const char *valuename)
1485 struct winreg_QueryMultipleValues r;
1486 NTSTATUS status;
1487 uint32_t bufsize=0;
1489 r.in.key_handle = handle;
1490 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1491 r.in.values[0].name = talloc(tctx, struct winreg_String);
1492 r.in.values[0].name->name = valuename;
1493 r.in.values[0].offset = 0;
1494 r.in.values[0].length = 0;
1495 r.in.values[0].type = 0;
1497 r.in.num_values = 1;
1498 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1499 *r.in.buffer_size = bufsize;
1500 do {
1501 *r.in.buffer_size = bufsize;
1502 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1503 *r.in.buffer_size);
1505 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1507 if(NT_STATUS_IS_ERR(status))
1508 torture_fail(tctx, "QueryMultipleValues failed");
1510 talloc_free(r.in.buffer);
1511 bufsize += 0x20;
1512 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1514 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1516 return true;
1519 static bool test_QueryValue(struct dcerpc_pipe *p,
1520 struct torture_context *tctx,
1521 struct policy_handle *handle,
1522 const char *valuename)
1524 struct winreg_QueryValue r;
1525 NTSTATUS status;
1526 enum winreg_Type zero_type = 0;
1527 uint32_t offered = 0xfff;
1528 uint32_t zero = 0;
1530 r.in.handle = handle;
1531 r.in.data = NULL;
1532 r.in.value_name.name = valuename;
1533 r.in.type = &zero_type;
1534 r.in.size = &offered;
1535 r.in.length = &zero;
1537 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1538 if (NT_STATUS_IS_ERR(status)) {
1539 torture_fail(tctx, "QueryValue failed");
1542 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1544 return true;
1547 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1548 struct policy_handle *handle, int max_valnamelen,
1549 int max_valbufsize)
1551 struct winreg_EnumValue r;
1552 enum winreg_Type type = 0;
1553 uint32_t size = max_valbufsize, zero = 0;
1554 bool ret = true;
1555 uint8_t buf8;
1556 struct winreg_StringBuf name;
1558 name.name = "";
1559 name.size = 1024;
1561 r.in.handle = handle;
1562 r.in.enum_index = 0;
1563 r.in.name = &name;
1564 r.out.name = &name;
1565 r.in.type = &type;
1566 r.in.value = &buf8;
1567 r.in.length = &zero;
1568 r.in.size = &size;
1570 do {
1571 torture_assert_ntstatus_ok(tctx,
1572 dcerpc_winreg_EnumValue(p, tctx, &r),
1573 "EnumValue failed");
1575 if (W_ERROR_IS_OK(r.out.result)) {
1576 ret &= test_QueryValue(p, tctx, handle,
1577 r.out.name->name);
1578 ret &= test_QueryMultipleValues(p, tctx, handle,
1579 r.out.name->name);
1582 r.in.enum_index++;
1583 } while (W_ERROR_IS_OK(r.out.result));
1585 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1586 "EnumValue failed");
1588 return ret;
1591 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1592 struct torture_context *tctx)
1594 struct winreg_AbortSystemShutdown r;
1595 uint16_t server = 0x0;
1597 r.in.server = &server;
1599 torture_assert_ntstatus_ok(tctx,
1600 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1601 "AbortSystemShutdown failed");
1603 torture_assert_werr_ok(tctx, r.out.result,
1604 "AbortSystemShutdown failed");
1606 return true;
1609 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1610 struct dcerpc_pipe *p)
1612 struct winreg_InitiateSystemShutdown r;
1613 uint16_t hostname = 0x0;
1615 r.in.hostname = &hostname;
1616 r.in.message = talloc(tctx, struct lsa_StringLarge);
1617 init_lsa_StringLarge(r.in.message, "spottyfood");
1618 r.in.force_apps = 1;
1619 r.in.timeout = 30;
1620 r.in.reboot = 1;
1622 torture_assert_ntstatus_ok(tctx,
1623 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1624 "InitiateSystemShutdown failed");
1626 torture_assert_werr_ok(tctx, r.out.result,
1627 "InitiateSystemShutdown failed");
1629 return test_AbortSystemShutdown(p, tctx);
1633 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1634 struct dcerpc_pipe *p)
1636 struct winreg_InitiateSystemShutdownEx r;
1637 uint16_t hostname = 0x0;
1639 r.in.hostname = &hostname;
1640 r.in.message = talloc(tctx, struct lsa_StringLarge);
1641 init_lsa_StringLarge(r.in.message, "spottyfood");
1642 r.in.force_apps = 1;
1643 r.in.timeout = 30;
1644 r.in.reboot = 1;
1645 r.in.reason = 0;
1647 torture_assert_ntstatus_ok(tctx,
1648 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1649 "InitiateSystemShutdownEx failed");
1651 torture_assert_werr_ok(tctx, r.out.result,
1652 "InitiateSystemShutdownEx failed");
1654 return test_AbortSystemShutdown(p, tctx);
1656 #define MAX_DEPTH 2 /* Only go this far down the tree */
1658 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1659 struct policy_handle *handle, int depth,
1660 bool test_security)
1662 if (depth == MAX_DEPTH)
1663 return true;
1665 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1668 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1671 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1674 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1677 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1680 test_CloseKey(p, tctx, handle);
1682 return true;
1685 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1687 static bool test_Open_Security(struct torture_context *tctx,
1688 struct dcerpc_pipe *p, void *userdata)
1690 struct policy_handle handle, newhandle;
1691 bool ret = true, created2 = false;
1692 bool created4 = false;
1693 struct winreg_OpenHKLM r;
1695 winreg_open_fn open_fn = userdata;
1697 r.in.system_name = 0;
1698 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1699 r.out.handle = &handle;
1701 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1702 "open");
1704 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1706 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1707 torture_comment(tctx,
1708 "CreateKey (TEST_KEY_BASE) failed\n");
1711 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1712 NULL, &newhandle)) {
1713 created2 = true;
1716 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1717 printf("CloseKey failed\n");
1718 ret = false;
1721 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1722 created4 = true;
1725 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1726 printf("CloseKey failed\n");
1727 ret = false;
1730 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1731 ret = false;
1734 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1735 printf("DeleteKey failed\n");
1736 ret = false;
1739 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1740 printf("DeleteKey failed\n");
1741 ret = false;
1744 /* The HKCR hive has a very large fanout */
1745 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1746 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1747 ret = false;
1749 } else {
1750 if (!test_key(p, tctx, &handle, 0, true)) {
1751 ret = false;
1755 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1757 return ret;
1760 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1761 void *userdata)
1763 struct policy_handle handle, newhandle;
1764 bool ret = true, created = false, deleted = false;
1765 bool created3 = false, created_subkey = false;
1766 struct winreg_OpenHKLM r;
1768 winreg_open_fn open_fn = userdata;
1770 r.in.system_name = 0;
1771 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1772 r.out.handle = &handle;
1774 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1775 "open");
1777 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1779 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1780 torture_comment(tctx,
1781 "CreateKey (TEST_KEY_BASE) failed\n");
1784 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1785 torture_comment(tctx,
1786 "CreateKey failed - not considering a failure\n");
1787 } else {
1788 created = true;
1791 if (created && !test_FlushKey(p, tctx, &handle)) {
1792 torture_comment(tctx, "FlushKey failed\n");
1793 ret = false;
1796 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1797 torture_fail(tctx,
1798 "CreateKey failed (OpenKey after Create didn't work)\n");
1800 if (created && !test_CloseKey(p, tctx, &newhandle))
1801 torture_fail(tctx,
1802 "CreateKey failed (CloseKey after Open didn't work)\n");
1804 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1805 torture_comment(tctx, "DeleteKey failed\n");
1806 ret = false;
1807 } else {
1808 deleted = true;
1811 if (created && !test_FlushKey(p, tctx, &handle)) {
1812 torture_comment(tctx, "FlushKey failed\n");
1813 ret = false;
1816 if (created && deleted &&
1817 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1818 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1819 WERR_BADFILE, NULL)) {
1820 torture_comment(tctx,
1821 "DeleteKey failed (OpenKey after Delete "
1822 "did not return WERR_BADFILE)\n");
1823 ret = false;
1826 if (!test_GetVersion(p, tctx, &handle)) {
1827 torture_comment(tctx, "GetVersion failed\n");
1828 ret = false;
1831 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1832 created3 = true;
1835 if (created3 &&
1836 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1837 created_subkey = true;
1840 if (created_subkey &&
1841 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1842 printf("DeleteKey failed\n");
1843 ret = false;
1846 /* The HKCR hive has a very large fanout */
1847 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1848 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1849 ret = false;
1851 } else {
1852 if (!test_key(p, tctx, &handle, 0, false)) {
1853 ret = false;
1857 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1859 return ret;
1862 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1864 struct torture_rpc_tcase *tcase;
1865 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1866 struct torture_test *test;
1868 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1869 &ndr_table_winreg);
1871 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1872 test_InitiateSystemShutdown);
1873 test->dangerous = true;
1875 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1876 test_InitiateSystemShutdownEx);
1877 test->dangerous = true;
1879 /* Basic tests without security descriptors */
1880 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1881 test_Open,
1882 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1883 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1884 test_Open,
1885 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1886 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1887 test_Open,
1888 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1889 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1890 test_Open,
1891 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1893 /* Security descriptor tests */
1894 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1895 test_Open_Security,
1896 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1897 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1898 test_Open_Security,
1899 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1900 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1901 test_Open_Security,
1902 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1903 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1904 test_Open_Security,
1905 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1907 return suite;