s4-smbtorture: skip NotifyChangeKeyValue test against s3 for now.
[Samba/cd1.git] / source4 / torture / rpc / winreg.c
blob5f1a66b985b4511372f53c332ee93a3c70300cc5
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 "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/rpc.h"
29 #define TEST_KEY_BASE "smbtorture test"
30 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
31 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
32 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
33 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
34 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
35 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
36 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
38 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
40 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
42 name->string = s;
45 static void init_winreg_String(struct winreg_String *name, const char *s)
47 name->name = s;
48 if (s) {
49 name->name_len = 2 * (strlen_m(s) + 1);
50 name->name_size = name->name_len;
51 } else {
52 name->name_len = 0;
53 name->name_size = 0;
57 static bool test_GetVersion(struct dcerpc_pipe *p,
58 struct torture_context *tctx,
59 struct policy_handle *handle)
61 struct winreg_GetVersion r;
62 uint32_t v;
64 ZERO_STRUCT(r);
65 r.in.handle = handle;
66 r.out.version = &v;
68 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
69 "GetVersion failed");
71 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
73 return true;
76 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
77 struct torture_context *tctx,
78 struct policy_handle *handle)
80 struct winreg_NotifyChangeKeyValue r;
82 ZERO_STRUCT(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 if (torture_setting_bool(tctx, "samba3", false)) {
91 torture_skip(tctx, "skipping NotifyChangeKeyValue test against Samba 3");
94 torture_assert_ntstatus_ok(tctx,
95 dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
96 "NotifyChangeKeyValue failed");
98 if (!W_ERROR_IS_OK(r.out.result)) {
99 torture_comment(tctx,
100 "NotifyChangeKeyValue failed - %s - not considering\n",
101 win_errstr(r.out.result));
102 return true;
105 return true;
108 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
109 struct policy_handle *handle, const char *name,
110 const char *kclass)
112 struct winreg_CreateKey r;
113 struct policy_handle newhandle;
114 enum winreg_CreateAction action_taken = 0;
116 ZERO_STRUCT(r);
117 r.in.handle = handle;
118 r.out.new_handle = &newhandle;
119 init_winreg_String(&r.in.name, name);
120 init_winreg_String(&r.in.keyclass, kclass);
121 r.in.options = 0x0;
122 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
123 r.in.action_taken = r.out.action_taken = &action_taken;
124 r.in.secdesc = NULL;
126 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
127 "CreateKey failed");
129 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
131 return true;
136 createkey testing with a SD
138 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
139 struct torture_context *tctx,
140 struct policy_handle *handle, const char *name,
141 const char *kclass,
142 struct policy_handle *newhandle)
144 struct winreg_CreateKey r;
145 enum winreg_CreateAction action_taken = 0;
146 struct security_descriptor *sd;
147 DATA_BLOB sdblob;
148 struct winreg_SecBuf secbuf;
150 sd = security_descriptor_dacl_create(tctx,
152 NULL, NULL,
153 SID_NT_AUTHENTICATED_USERS,
154 SEC_ACE_TYPE_ACCESS_ALLOWED,
155 SEC_GENERIC_ALL,
156 SEC_ACE_FLAG_OBJECT_INHERIT |
157 SEC_ACE_FLAG_CONTAINER_INHERIT,
158 NULL);
160 torture_assert_ndr_success(tctx,
161 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
162 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
163 "Failed to push security_descriptor ?!\n");
165 secbuf.sd.data = sdblob.data;
166 secbuf.sd.len = sdblob.length;
167 secbuf.sd.size = sdblob.length;
168 secbuf.length = sdblob.length-10;
169 secbuf.inherit = 0;
171 ZERO_STRUCT(r);
172 r.in.handle = handle;
173 r.out.new_handle = newhandle;
174 init_winreg_String(&r.in.name, name);
175 init_winreg_String(&r.in.keyclass, kclass);
176 r.in.options = 0x0;
177 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
178 r.in.action_taken = r.out.action_taken = &action_taken;
179 r.in.secdesc = &secbuf;
181 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
182 "CreateKey with sd failed");
184 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
186 return true;
189 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
190 struct torture_context *tctx,
191 struct policy_handle *handle,
192 uint32_t *sec_info_ptr,
193 WERROR get_werr,
194 struct security_descriptor **sd_out)
196 struct winreg_GetKeySecurity r;
197 struct security_descriptor *sd = NULL;
198 uint32_t sec_info;
199 DATA_BLOB sdblob;
201 if (sec_info_ptr) {
202 sec_info = *sec_info_ptr;
203 } else {
204 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
207 ZERO_STRUCT(r);
209 r.in.handle = handle;
210 r.in.sec_info = sec_info;
211 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
212 r.in.sd->size = 0x1000;
214 torture_assert_ntstatus_ok(tctx,
215 dcerpc_winreg_GetKeySecurity(p, tctx, &r),
216 "GetKeySecurity failed");
218 torture_assert_werr_equal(tctx, r.out.result, get_werr,
219 "GetKeySecurity failed");
221 sdblob.data = r.out.sd->data;
222 sdblob.length = r.out.sd->len;
224 sd = talloc_zero(tctx, struct security_descriptor);
226 torture_assert_ndr_success(tctx,
227 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
228 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
229 "pull_security_descriptor failed");
231 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
232 NDR_PRINT_DEBUG(security_descriptor, sd);
235 if (sd_out) {
236 *sd_out = sd;
237 } else {
238 talloc_free(sd);
241 return true;
244 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
245 struct torture_context *tctx,
246 struct policy_handle *handle,
247 struct security_descriptor **sd_out)
249 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
252 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
253 struct torture_context *tctx,
254 struct policy_handle *handle,
255 uint32_t *sec_info_ptr,
256 struct security_descriptor *sd,
257 WERROR werr)
259 struct winreg_SetKeySecurity r;
260 struct KeySecurityData *sdata = NULL;
261 DATA_BLOB sdblob;
262 uint32_t sec_info;
264 ZERO_STRUCT(r);
266 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
267 NDR_PRINT_DEBUG(security_descriptor, sd);
270 torture_assert_ndr_success(tctx,
271 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
272 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
273 "push_security_descriptor failed");
275 sdata = talloc_zero(tctx, struct KeySecurityData);
276 sdata->data = sdblob.data;
277 sdata->size = sdblob.length;
278 sdata->len = sdblob.length;
280 if (sec_info_ptr) {
281 sec_info = *sec_info_ptr;
282 } else {
283 sec_info = SECINFO_UNPROTECTED_SACL |
284 SECINFO_UNPROTECTED_DACL;
285 if (sd->owner_sid) {
286 sec_info |= SECINFO_OWNER;
288 if (sd->group_sid) {
289 sec_info |= SECINFO_GROUP;
291 if (sd->sacl) {
292 sec_info |= SECINFO_SACL;
294 if (sd->dacl) {
295 sec_info |= SECINFO_DACL;
299 r.in.handle = handle;
300 r.in.sec_info = sec_info;
301 r.in.sd = sdata;
303 torture_assert_ntstatus_ok(tctx,
304 dcerpc_winreg_SetKeySecurity(p, tctx, &r),
305 "SetKeySecurity failed");
307 torture_assert_werr_equal(tctx, r.out.result, werr,
308 "SetKeySecurity failed");
310 return true;
313 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
314 struct torture_context *tctx,
315 struct policy_handle *handle,
316 struct security_descriptor *sd)
318 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
321 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
322 struct policy_handle *handle)
324 struct winreg_CloseKey r;
326 ZERO_STRUCT(r);
327 r.in.handle = r.out.handle = handle;
329 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
330 "CloseKey failed");
332 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
334 return true;
337 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
338 struct policy_handle *handle)
340 struct winreg_FlushKey r;
342 ZERO_STRUCT(r);
343 r.in.handle = handle;
345 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
346 "FlushKey failed");
348 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
350 return true;
353 static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
354 struct policy_handle *hive_handle,
355 const char *keyname, uint32_t access_mask,
356 struct policy_handle *key_handle,
357 WERROR open_werr,
358 bool *success)
360 struct winreg_OpenKey r;
362 ZERO_STRUCT(r);
363 r.in.parent_handle = hive_handle;
364 init_winreg_String(&r.in.keyname, keyname);
365 r.in.unknown = 0x00000000;
366 r.in.access_mask = access_mask;
367 r.out.handle = key_handle;
369 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
370 "OpenKey failed");
372 torture_assert_werr_equal(tctx, r.out.result, open_werr,
373 "OpenKey failed");
375 if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
376 *success = true;
379 return true;
382 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
383 struct policy_handle *hive_handle,
384 const char *keyname, struct policy_handle *key_handle)
386 return _test_OpenKey(p, tctx, hive_handle, keyname,
387 SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
388 WERR_OK, NULL);
391 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
392 struct policy_handle *handle, const char *key)
394 struct winreg_DeleteKey r;
396 ZERO_STRUCT(r);
397 r.in.handle = handle;
399 init_winreg_String(&r.in.key, key);
400 dcerpc_winreg_DeleteKey(p, tctx, &r);
402 return true;
405 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
406 struct torture_context *tctx,
407 struct policy_handle *handle,
408 WERROR get_werr,
409 WERROR set_werr)
411 struct security_descriptor *sd = NULL;
413 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
414 return false;
417 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
418 return false;
421 return true;
424 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
425 struct torture_context *tctx,
426 struct policy_handle *handle,
427 const char *key)
429 struct policy_handle new_handle;
430 bool ret = true;
432 torture_comment(tctx, "SecurityDescriptor get & set\n");
434 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
435 return false;
438 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
439 WERR_OK, WERR_OK)) {
440 ret = false;
443 if (!test_CloseKey(p, tctx, &new_handle)) {
444 return false;
447 return ret;
450 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
451 struct torture_context *tctx,
452 struct policy_handle *handle,
453 uint32_t access_mask,
454 const char *key,
455 WERROR open_werr,
456 WERROR get_werr,
457 WERROR set_werr)
459 struct policy_handle new_handle;
460 bool ret = true;
461 bool got_key = false;
463 if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
464 open_werr, &got_key)) {
465 return false;
468 if (!got_key) {
469 return true;
472 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
473 get_werr, set_werr)) {
474 ret = false;
477 if (!test_CloseKey(p, tctx, &new_handle)) {
478 return false;
481 return ret;
484 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
485 struct torture_context *tctx,
486 struct policy_handle *handle,
487 const struct dom_sid *sid)
489 struct security_descriptor *sd = NULL;
490 int i;
492 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
493 return false;
496 if (!sd || !sd->dacl) {
497 return false;
500 for (i = 0; i < sd->dacl->num_aces; i++) {
501 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
502 return true;
506 return false;
509 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
510 struct torture_context *tctx,
511 struct policy_handle *handle,
512 const char *key,
513 const struct dom_sid *sid)
515 struct policy_handle new_handle;
516 bool ret = true;
518 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
519 return false;
522 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
524 test_CloseKey(p, tctx, &new_handle);
526 return ret;
529 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
530 struct torture_context *tctx,
531 struct policy_handle *handle,
532 const struct dom_sid *sid)
534 struct security_descriptor *sd = NULL;
535 int i;
536 uint32_t sec_info = SECINFO_SACL;
538 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
539 return false;
542 if (!sd || !sd->sacl) {
543 return false;
546 for (i = 0; i < sd->sacl->num_aces; i++) {
547 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
548 return true;
552 return false;
555 static bool _test_sacl_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)
561 struct policy_handle new_handle;
562 bool ret = true;
564 if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
565 &new_handle, WERR_OK, NULL)) {
566 return false;
569 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
571 test_CloseKey(p, tctx, &new_handle);
573 return ret;
576 static bool test_owner_present(struct dcerpc_pipe *p,
577 struct torture_context *tctx,
578 struct policy_handle *handle,
579 const struct dom_sid *sid)
581 struct security_descriptor *sd = NULL;
582 uint32_t sec_info = SECINFO_OWNER;
584 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
585 return false;
588 if (!sd || !sd->owner_sid) {
589 return false;
592 return dom_sid_equal(sd->owner_sid, sid);
595 static bool _test_owner_present(struct dcerpc_pipe *p,
596 struct torture_context *tctx,
597 struct policy_handle *handle,
598 const char *key,
599 const struct dom_sid *sid)
601 struct policy_handle new_handle;
602 bool ret = true;
604 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
605 return false;
608 ret = test_owner_present(p, tctx, &new_handle, sid);
610 test_CloseKey(p, tctx, &new_handle);
612 return ret;
615 static bool test_group_present(struct dcerpc_pipe *p,
616 struct torture_context *tctx,
617 struct policy_handle *handle,
618 const struct dom_sid *sid)
620 struct security_descriptor *sd = NULL;
621 uint32_t sec_info = SECINFO_GROUP;
623 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
624 return false;
627 if (!sd || !sd->group_sid) {
628 return false;
631 return dom_sid_equal(sd->group_sid, sid);
634 static bool _test_group_present(struct dcerpc_pipe *p,
635 struct torture_context *tctx,
636 struct policy_handle *handle,
637 const char *key,
638 const struct dom_sid *sid)
640 struct policy_handle new_handle;
641 bool ret = true;
643 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
644 return false;
647 ret = test_group_present(p, tctx, &new_handle, sid);
649 test_CloseKey(p, tctx, &new_handle);
651 return ret;
654 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
655 struct torture_context *tctx,
656 struct policy_handle *handle,
657 const struct dom_sid *sid,
658 uint8_t flags)
660 struct security_descriptor *sd = NULL;
661 int i;
663 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
664 return false;
667 if (!sd || !sd->dacl) {
668 return false;
671 for (i = 0; i < sd->dacl->num_aces; i++) {
672 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
673 (sd->dacl->aces[i].flags == flags)) {
674 return true;
678 return false;
681 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
682 struct torture_context *tctx,
683 struct policy_handle *handle,
684 const struct security_ace *ace)
686 struct security_descriptor *sd = NULL;
687 int i;
689 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
690 return false;
693 if (!sd || !sd->dacl) {
694 return false;
697 for (i = 0; i < sd->dacl->num_aces; i++) {
698 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
699 return true;
703 return false;
706 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
707 struct torture_context *tctx,
708 struct policy_handle *handle,
709 const char *key,
710 struct security_descriptor *sd)
712 struct policy_handle new_handle;
713 bool ret = true;
715 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
716 return false;
719 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
720 ret = false;
723 if (!test_CloseKey(p, tctx, &new_handle)) {
724 ret = false;
727 return ret;
730 static bool test_BackupSecurity(struct dcerpc_pipe *p,
731 struct torture_context *tctx,
732 struct policy_handle *handle,
733 const char *key,
734 struct security_descriptor **sd)
736 struct policy_handle new_handle;
737 bool ret = true;
739 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
740 return false;
743 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
744 ret = false;
747 if (!test_CloseKey(p, tctx, &new_handle)) {
748 ret = false;
751 return ret;
754 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
755 struct torture_context *tctx,
756 struct policy_handle *handle,
757 const char *key)
759 /* get sd
760 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
761 set sd
762 get sd
763 check ace
764 add subkey
765 get sd
766 check ace
767 add subsubkey
768 get sd
769 check ace
770 del subsubkey
771 del subkey
772 reset sd
775 struct security_descriptor *sd = NULL;
776 struct security_descriptor *sd_orig = NULL;
777 struct security_ace *ace = NULL;
778 struct policy_handle new_handle;
779 NTSTATUS status;
780 bool ret = true;
782 torture_comment(tctx, "SecurityDescriptor inheritance\n");
784 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
785 return false;
788 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
789 return false;
792 sd_orig = security_descriptor_copy(tctx, sd);
793 if (sd_orig == NULL) {
794 return false;
797 ace = security_ace_create(tctx,
798 TEST_SID,
799 SEC_ACE_TYPE_ACCESS_ALLOWED,
800 SEC_STD_REQUIRED,
801 SEC_ACE_FLAG_CONTAINER_INHERIT);
803 status = security_descriptor_dacl_add(sd, ace);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("failed to add ace: %s\n", nt_errstr(status));
806 return false;
809 /* FIXME: add further tests for these flags */
810 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
811 SEC_DESC_SACL_AUTO_INHERITED;
813 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
814 return false;
817 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
818 printf("new ACE not present!\n");
819 return false;
822 if (!test_CloseKey(p, tctx, &new_handle)) {
823 return false;
826 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
827 ret = false;
828 goto out;
831 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
832 ret = false;
833 goto out;
836 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
837 printf("inherited ACE not present!\n");
838 ret = false;
839 goto out;
842 test_CloseKey(p, tctx, &new_handle);
843 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
844 ret = false;
845 goto out;
848 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
849 ret = false;
850 goto out;
853 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
854 printf("inherited ACE not present!\n");
855 ret = false;
856 goto out;
859 out:
860 test_CloseKey(p, tctx, &new_handle);
861 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
862 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
864 return true;
867 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
868 struct torture_context *tctx,
869 struct policy_handle *handle,
870 const char *key)
872 /* get sd
873 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
874 set sd
875 add subkey/subkey
876 get sd
877 check ace
878 get sd from subkey
879 check ace
880 del subkey/subkey
881 del subkey
882 reset sd
885 struct security_descriptor *sd = NULL;
886 struct security_descriptor *sd_orig = NULL;
887 struct security_ace *ace = NULL;
888 struct policy_handle new_handle;
889 struct dom_sid *sid = NULL;
890 NTSTATUS status;
891 bool ret = true;
892 uint8_t ace_flags = 0x0;
894 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
896 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
897 return false;
900 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
901 return false;
904 sd_orig = security_descriptor_copy(tctx, sd);
905 if (sd_orig == NULL) {
906 return false;
909 ace = security_ace_create(tctx,
910 TEST_SID,
911 SEC_ACE_TYPE_ACCESS_ALLOWED,
912 SEC_STD_REQUIRED,
913 SEC_ACE_FLAG_CONTAINER_INHERIT |
914 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
916 status = security_descriptor_dacl_add(sd, ace);
917 if (!NT_STATUS_IS_OK(status)) {
918 printf("failed to add ace: %s\n", nt_errstr(status));
919 return false;
922 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
923 return false;
926 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
927 printf("new ACE not present!\n");
928 return false;
931 if (!test_CloseKey(p, tctx, &new_handle)) {
932 return false;
935 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
936 return false;
939 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
940 ret = false;
941 goto out;
944 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
945 printf("inherited ACE present but should not!\n");
946 ret = false;
947 goto out;
950 sid = dom_sid_parse_talloc(tctx, TEST_SID);
951 if (sid == NULL) {
952 return false;
955 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
956 printf("inherited trustee SID present but should not!\n");
957 ret = false;
958 goto out;
961 test_CloseKey(p, tctx, &new_handle);
963 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
964 ret = false;
965 goto out;
968 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
969 printf("inherited ACE present but should not!\n");
970 ret = false;
971 goto out;
974 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
975 printf("inherited trustee SID with flags 0x%02x not present!\n",
976 ace_flags);
977 ret = false;
978 goto out;
981 out:
982 test_CloseKey(p, tctx, &new_handle);
983 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
984 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
986 return ret;
989 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
990 struct torture_context *tctx,
991 struct policy_handle *handle,
992 const char *key)
994 bool ret = true;
995 int i;
997 struct winreg_mask_result_table {
998 uint32_t access_mask;
999 WERROR open_werr;
1000 WERROR get_werr;
1001 WERROR set_werr;
1002 } sd_mask_tests[] = {
1003 { 0,
1004 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1005 { SEC_FLAG_MAXIMUM_ALLOWED,
1006 WERR_OK, WERR_OK, WERR_OK },
1007 { SEC_STD_WRITE_DAC,
1008 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1009 { SEC_FLAG_SYSTEM_SECURITY,
1010 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1013 /* FIXME: before this test can ever run successfully we need a way to
1014 * correctly read a NULL security_descritpor in ndr, get the required
1015 * length, requery, etc.
1018 return true;
1020 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1022 torture_comment(tctx,
1023 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1024 sd_mask_tests[i].access_mask);
1025 torture_comment(tctx,
1026 "expecting: open %s, get: %s, set: %s\n",
1027 win_errstr(sd_mask_tests[i].open_werr),
1028 win_errstr(sd_mask_tests[i].get_werr),
1029 win_errstr(sd_mask_tests[i].set_werr));
1031 if (_test_SecurityDescriptor(p, tctx, handle,
1032 sd_mask_tests[i].access_mask, key,
1033 sd_mask_tests[i].open_werr,
1034 sd_mask_tests[i].get_werr,
1035 sd_mask_tests[i].set_werr)) {
1036 ret = false;
1040 return ret;
1043 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1044 struct torture_context *,
1045 struct policy_handle *,
1046 const char *,
1047 const struct dom_sid *);
1049 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1050 struct torture_context *tctx,
1051 struct policy_handle *handle,
1052 const char *key,
1053 const char *test,
1054 uint32_t access_mask,
1055 uint32_t sec_info,
1056 struct security_descriptor *sd,
1057 WERROR set_werr,
1058 bool expect_present,
1059 bool (*fn) (struct dcerpc_pipe *,
1060 struct torture_context *,
1061 struct policy_handle *,
1062 const char *,
1063 const struct dom_sid *),
1064 const struct dom_sid *sid)
1066 struct policy_handle new_handle;
1067 bool open_success = false;
1069 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1070 "0x%08x, access_mask: 0x%08x\n",
1071 test, sec_info, access_mask);
1073 if (!_test_OpenKey(p, tctx, handle, key,
1074 access_mask,
1075 &new_handle,
1076 WERR_OK,
1077 &open_success)) {
1078 return false;
1081 if (!open_success) {
1082 printf("key did not open\n");
1083 test_CloseKey(p, tctx, &new_handle);
1084 return false;
1087 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1089 set_werr)) {
1090 torture_warning(tctx,
1091 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1092 sec_info);
1093 smb_panic("");
1094 test_CloseKey(p, tctx, &new_handle);
1095 return false;
1098 test_CloseKey(p, tctx, &new_handle);
1100 if (W_ERROR_IS_OK(set_werr)) {
1101 bool present;
1102 present = fn(p, tctx, handle, key, sid);
1103 if ((expect_present) && (!present)) {
1104 torture_warning(tctx,
1105 "%s sid is not present!\n",
1106 test);
1107 return false;
1109 if ((!expect_present) && (present)) {
1110 torture_warning(tctx,
1111 "%s sid is present but not expected!\n",
1112 test);
1113 return false;
1117 return true;
1120 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1121 struct torture_context *tctx,
1122 struct policy_handle *handle,
1123 const char *key)
1125 struct security_descriptor *sd_orig = NULL;
1126 struct dom_sid *sid = NULL;
1127 bool ret = true;
1128 int i, a;
1130 struct security_descriptor *sd_owner =
1131 security_descriptor_dacl_create(tctx,
1133 TEST_SID, NULL, NULL);
1135 struct security_descriptor *sd_group =
1136 security_descriptor_dacl_create(tctx,
1138 NULL, TEST_SID, NULL);
1140 struct security_descriptor *sd_dacl =
1141 security_descriptor_dacl_create(tctx,
1143 NULL, NULL,
1144 TEST_SID,
1145 SEC_ACE_TYPE_ACCESS_ALLOWED,
1146 SEC_GENERIC_ALL,
1148 SID_NT_AUTHENTICATED_USERS,
1149 SEC_ACE_TYPE_ACCESS_ALLOWED,
1150 SEC_GENERIC_ALL,
1152 NULL);
1154 struct security_descriptor *sd_sacl =
1155 security_descriptor_sacl_create(tctx,
1157 NULL, NULL,
1158 TEST_SID,
1159 SEC_ACE_TYPE_SYSTEM_AUDIT,
1160 SEC_GENERIC_ALL,
1161 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1162 NULL);
1164 struct winreg_secinfo_table {
1165 struct security_descriptor *sd;
1166 uint32_t sec_info;
1167 WERROR set_werr;
1168 bool sid_present;
1169 secinfo_verify_fn fn;
1172 struct winreg_secinfo_table sec_info_owner_tests[] = {
1173 { sd_owner, 0, WERR_OK,
1174 false, (secinfo_verify_fn)_test_owner_present },
1175 { sd_owner, SECINFO_OWNER, WERR_OK,
1176 true, (secinfo_verify_fn)_test_owner_present },
1177 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1178 { sd_owner, SECINFO_DACL, WERR_OK,
1179 true, (secinfo_verify_fn)_test_owner_present },
1180 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1183 uint32_t sd_owner_good_access_masks[] = {
1184 SEC_FLAG_MAXIMUM_ALLOWED,
1185 /* SEC_STD_WRITE_OWNER, */
1188 struct winreg_secinfo_table sec_info_group_tests[] = {
1189 { sd_group, 0, WERR_OK,
1190 false, (secinfo_verify_fn)_test_group_present },
1191 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1192 { sd_group, SECINFO_GROUP, WERR_OK,
1193 true, (secinfo_verify_fn)_test_group_present },
1194 { sd_group, SECINFO_DACL, WERR_OK,
1195 true, (secinfo_verify_fn)_test_group_present },
1196 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1199 uint32_t sd_group_good_access_masks[] = {
1200 SEC_FLAG_MAXIMUM_ALLOWED,
1203 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1204 { sd_dacl, 0, WERR_OK,
1205 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1206 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1207 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1208 { sd_dacl, SECINFO_DACL, WERR_OK,
1209 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1210 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1213 uint32_t sd_dacl_good_access_masks[] = {
1214 SEC_FLAG_MAXIMUM_ALLOWED,
1215 SEC_STD_WRITE_DAC,
1218 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1219 { sd_sacl, 0, WERR_OK,
1220 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1221 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1222 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1223 { sd_sacl, SECINFO_DACL, WERR_OK,
1224 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1225 { sd_sacl, SECINFO_SACL, WERR_OK,
1226 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1229 uint32_t sd_sacl_good_access_masks[] = {
1230 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1231 /* SEC_FLAG_SYSTEM_SECURITY, */
1234 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1235 if (sid == NULL) {
1236 return false;
1239 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1240 return false;
1243 /* OWNER */
1245 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1247 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1249 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1250 key,
1251 "OWNER",
1252 sd_owner_good_access_masks[a],
1253 sec_info_owner_tests[i].sec_info,
1254 sec_info_owner_tests[i].sd,
1255 sec_info_owner_tests[i].set_werr,
1256 sec_info_owner_tests[i].sid_present,
1257 sec_info_owner_tests[i].fn,
1258 sid))
1260 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1261 ret = false;
1262 goto out;
1267 /* GROUP */
1269 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1271 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1273 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1274 key,
1275 "GROUP",
1276 sd_group_good_access_masks[a],
1277 sec_info_group_tests[i].sec_info,
1278 sec_info_group_tests[i].sd,
1279 sec_info_group_tests[i].set_werr,
1280 sec_info_group_tests[i].sid_present,
1281 sec_info_group_tests[i].fn,
1282 sid))
1284 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1285 ret = false;
1286 goto out;
1291 /* DACL */
1293 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1295 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1297 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1298 key,
1299 "DACL",
1300 sd_dacl_good_access_masks[a],
1301 sec_info_dacl_tests[i].sec_info,
1302 sec_info_dacl_tests[i].sd,
1303 sec_info_dacl_tests[i].set_werr,
1304 sec_info_dacl_tests[i].sid_present,
1305 sec_info_dacl_tests[i].fn,
1306 sid))
1308 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1309 ret = false;
1310 goto out;
1315 /* SACL */
1317 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1319 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1321 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1322 key,
1323 "SACL",
1324 sd_sacl_good_access_masks[a],
1325 sec_info_sacl_tests[i].sec_info,
1326 sec_info_sacl_tests[i].sd,
1327 sec_info_sacl_tests[i].set_werr,
1328 sec_info_sacl_tests[i].sid_present,
1329 sec_info_sacl_tests[i].fn,
1330 sid))
1332 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1333 ret = false;
1334 goto out;
1339 out:
1340 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1342 return ret;
1345 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1346 struct torture_context *tctx,
1347 struct policy_handle *handle,
1348 const char *key)
1350 bool ret = true;
1352 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1353 printf("test_SecurityDescriptor failed\n");
1354 ret = false;
1357 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1358 printf("test_SecurityDescriptorInheritance failed\n");
1359 ret = false;
1362 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1363 printf("test_SecurityDescriptorBlockInheritance failed\n");
1364 ret = false;
1367 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1368 printf("test_SecurityDescriptorsSecInfo failed\n");
1369 ret = false;
1372 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1373 printf("test_SecurityDescriptorsMasks failed\n");
1374 ret = false;
1377 return ret;
1380 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1381 struct policy_handle *handle, const char *key)
1383 NTSTATUS status;
1384 struct winreg_DeleteKey r;
1386 r.in.handle = handle;
1387 init_winreg_String(&r.in.key, key);
1389 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1391 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1392 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1394 return true;
1397 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1398 struct torture_context *tctx,
1399 struct policy_handle *handle, char *kclass)
1401 struct winreg_QueryInfoKey r;
1402 uint32_t num_subkeys, max_subkeylen, max_classlen,
1403 num_values, max_valnamelen, max_valbufsize,
1404 secdescsize;
1405 NTTIME last_changed_time;
1407 ZERO_STRUCT(r);
1408 r.in.handle = handle;
1409 r.out.num_subkeys = &num_subkeys;
1410 r.out.max_subkeylen = &max_subkeylen;
1411 r.out.max_classlen = &max_classlen;
1412 r.out.num_values = &num_values;
1413 r.out.max_valnamelen = &max_valnamelen;
1414 r.out.max_valbufsize = &max_valbufsize;
1415 r.out.secdescsize = &secdescsize;
1416 r.out.last_changed_time = &last_changed_time;
1418 r.out.classname = talloc(tctx, struct winreg_String);
1420 r.in.classname = talloc(tctx, struct winreg_String);
1421 init_winreg_String(r.in.classname, kclass);
1423 torture_assert_ntstatus_ok(tctx,
1424 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1425 "QueryInfoKey failed");
1427 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1429 return true;
1432 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1433 struct policy_handle *handle, int depth,
1434 bool test_security);
1436 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1437 struct policy_handle *handle, int depth,
1438 bool test_security)
1440 struct winreg_EnumKey r;
1441 struct winreg_StringBuf kclass, name;
1442 NTSTATUS status;
1443 NTTIME t = 0;
1445 kclass.name = "";
1446 kclass.size = 1024;
1448 ZERO_STRUCT(r);
1449 r.in.handle = handle;
1450 r.in.enum_index = 0;
1451 r.in.name = &name;
1452 r.in.keyclass = &kclass;
1453 r.out.name = &name;
1454 r.in.last_changed_time = &t;
1456 do {
1457 name.name = NULL;
1458 name.size = 1024;
1460 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1462 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1463 struct policy_handle key_handle;
1465 torture_comment(tctx, "EnumKey: %d: %s\n",
1466 r.in.enum_index,
1467 r.out.name->name);
1469 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1470 &key_handle)) {
1471 } else {
1472 test_key(p, tctx, &key_handle,
1473 depth + 1, test_security);
1477 r.in.enum_index++;
1479 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1481 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1483 if (!W_ERROR_IS_OK(r.out.result) &&
1484 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1485 torture_fail(tctx, "EnumKey failed");
1488 return true;
1491 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1492 struct torture_context *tctx,
1493 struct policy_handle *handle,
1494 const char *valuename)
1496 struct winreg_QueryMultipleValues r;
1497 NTSTATUS status;
1498 uint32_t bufsize=0;
1500 ZERO_STRUCT(r);
1501 r.in.key_handle = handle;
1502 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1503 r.in.values[0].name = talloc(tctx, struct winreg_String);
1504 r.in.values[0].name->name = valuename;
1505 r.in.values[0].offset = 0;
1506 r.in.values[0].length = 0;
1507 r.in.values[0].type = 0;
1509 r.in.num_values = 1;
1510 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1511 *r.in.buffer_size = bufsize;
1512 do {
1513 *r.in.buffer_size = bufsize;
1514 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1515 *r.in.buffer_size);
1517 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1519 if(NT_STATUS_IS_ERR(status))
1520 torture_fail(tctx, "QueryMultipleValues failed");
1522 talloc_free(r.in.buffer);
1523 bufsize += 0x20;
1524 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1526 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1528 return true;
1531 static bool test_QueryValue(struct dcerpc_pipe *p,
1532 struct torture_context *tctx,
1533 struct policy_handle *handle,
1534 const char *valuename)
1536 struct winreg_QueryValue r;
1537 NTSTATUS status;
1538 enum winreg_Type zero_type = 0;
1539 uint32_t offered = 0xfff;
1540 uint32_t zero = 0;
1542 ZERO_STRUCT(r);
1543 r.in.handle = handle;
1544 r.in.data = NULL;
1545 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1546 r.in.value_name->name = valuename;
1547 r.in.type = &zero_type;
1548 r.in.data_size = &offered;
1549 r.in.data_length = &zero;
1551 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1552 if (NT_STATUS_IS_ERR(status)) {
1553 torture_fail(tctx, "QueryValue failed");
1556 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1558 return true;
1561 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1562 struct policy_handle *handle, int max_valnamelen,
1563 int max_valbufsize)
1565 struct winreg_EnumValue r;
1566 enum winreg_Type type = 0;
1567 uint32_t size = max_valbufsize, zero = 0;
1568 bool ret = true;
1569 uint8_t buf8;
1570 struct winreg_ValNameBuf name;
1572 name.name = "";
1573 name.size = 1024;
1575 ZERO_STRUCT(r);
1576 r.in.handle = handle;
1577 r.in.enum_index = 0;
1578 r.in.name = &name;
1579 r.out.name = &name;
1580 r.in.type = &type;
1581 r.in.value = &buf8;
1582 r.in.length = &zero;
1583 r.in.size = &size;
1585 do {
1586 torture_assert_ntstatus_ok(tctx,
1587 dcerpc_winreg_EnumValue(p, tctx, &r),
1588 "EnumValue failed");
1590 if (W_ERROR_IS_OK(r.out.result)) {
1591 ret &= test_QueryValue(p, tctx, handle,
1592 r.out.name->name);
1593 ret &= test_QueryMultipleValues(p, tctx, handle,
1594 r.out.name->name);
1597 r.in.enum_index++;
1598 } while (W_ERROR_IS_OK(r.out.result));
1600 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1601 "EnumValue failed");
1603 return ret;
1606 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1607 struct torture_context *tctx)
1609 struct winreg_AbortSystemShutdown r;
1610 uint16_t server = 0x0;
1612 ZERO_STRUCT(r);
1613 r.in.server = &server;
1615 torture_assert_ntstatus_ok(tctx,
1616 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1617 "AbortSystemShutdown failed");
1619 torture_assert_werr_ok(tctx, r.out.result,
1620 "AbortSystemShutdown failed");
1622 return true;
1625 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1626 struct dcerpc_pipe *p)
1628 struct winreg_InitiateSystemShutdown r;
1629 uint16_t hostname = 0x0;
1631 ZERO_STRUCT(r);
1632 r.in.hostname = &hostname;
1633 r.in.message = talloc(tctx, struct lsa_StringLarge);
1634 init_lsa_StringLarge(r.in.message, "spottyfood");
1635 r.in.force_apps = 1;
1636 r.in.timeout = 30;
1637 r.in.do_reboot = 1;
1639 torture_assert_ntstatus_ok(tctx,
1640 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1641 "InitiateSystemShutdown failed");
1643 torture_assert_werr_ok(tctx, r.out.result,
1644 "InitiateSystemShutdown failed");
1646 return test_AbortSystemShutdown(p, tctx);
1650 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1651 struct dcerpc_pipe *p)
1653 struct winreg_InitiateSystemShutdownEx r;
1654 uint16_t hostname = 0x0;
1656 ZERO_STRUCT(r);
1657 r.in.hostname = &hostname;
1658 r.in.message = talloc(tctx, struct lsa_StringLarge);
1659 init_lsa_StringLarge(r.in.message, "spottyfood");
1660 r.in.force_apps = 1;
1661 r.in.timeout = 30;
1662 r.in.do_reboot = 1;
1663 r.in.reason = 0;
1665 torture_assert_ntstatus_ok(tctx,
1666 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1667 "InitiateSystemShutdownEx failed");
1669 torture_assert_werr_ok(tctx, r.out.result,
1670 "InitiateSystemShutdownEx failed");
1672 return test_AbortSystemShutdown(p, tctx);
1674 #define MAX_DEPTH 2 /* Only go this far down the tree */
1676 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1677 struct policy_handle *handle, int depth,
1678 bool test_security)
1680 if (depth == MAX_DEPTH)
1681 return true;
1683 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1686 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1689 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1692 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1695 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1698 test_CloseKey(p, tctx, handle);
1700 return true;
1703 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1705 static bool test_Open_Security(struct torture_context *tctx,
1706 struct dcerpc_pipe *p, void *userdata)
1708 struct policy_handle handle, newhandle;
1709 bool ret = true, created2 = false;
1710 bool created4 = false;
1711 struct winreg_OpenHKLM r;
1713 winreg_open_fn open_fn = userdata;
1715 ZERO_STRUCT(r);
1716 r.in.system_name = 0;
1717 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1718 r.out.handle = &handle;
1720 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1721 "open");
1723 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1725 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1726 torture_comment(tctx,
1727 "CreateKey (TEST_KEY_BASE) failed\n");
1730 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1731 NULL, &newhandle)) {
1732 created2 = true;
1735 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1736 printf("CloseKey failed\n");
1737 ret = false;
1740 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1741 created4 = true;
1744 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1745 printf("CloseKey failed\n");
1746 ret = false;
1749 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1750 ret = false;
1753 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1754 printf("DeleteKey failed\n");
1755 ret = false;
1758 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1759 printf("DeleteKey failed\n");
1760 ret = false;
1763 /* The HKCR hive has a very large fanout */
1764 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1765 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1766 ret = false;
1768 } else {
1769 if (!test_key(p, tctx, &handle, 0, true)) {
1770 ret = false;
1774 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1776 return ret;
1779 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1780 void *userdata)
1782 struct policy_handle handle, newhandle;
1783 bool ret = true, created = false, deleted = false;
1784 bool created3 = false, created_subkey = false;
1785 struct winreg_OpenHKLM r;
1787 winreg_open_fn open_fn = userdata;
1789 ZERO_STRUCT(r);
1790 r.in.system_name = 0;
1791 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1792 r.out.handle = &handle;
1794 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1795 "open");
1797 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1799 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1800 torture_comment(tctx,
1801 "CreateKey (TEST_KEY_BASE) failed\n");
1804 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1805 torture_comment(tctx,
1806 "CreateKey failed - not considering a failure\n");
1807 } else {
1808 created = true;
1811 if (created && !test_FlushKey(p, tctx, &handle)) {
1812 torture_comment(tctx, "FlushKey failed\n");
1813 ret = false;
1816 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1817 torture_fail(tctx,
1818 "CreateKey failed (OpenKey after Create didn't work)\n");
1820 if (created && !test_CloseKey(p, tctx, &newhandle))
1821 torture_fail(tctx,
1822 "CreateKey failed (CloseKey after Open didn't work)\n");
1824 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1825 torture_comment(tctx, "DeleteKey failed\n");
1826 ret = false;
1827 } else {
1828 deleted = true;
1831 if (created && !test_FlushKey(p, tctx, &handle)) {
1832 torture_comment(tctx, "FlushKey failed\n");
1833 ret = false;
1836 if (created && deleted &&
1837 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1838 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1839 WERR_BADFILE, NULL)) {
1840 torture_comment(tctx,
1841 "DeleteKey failed (OpenKey after Delete "
1842 "did not return WERR_BADFILE)\n");
1843 ret = false;
1846 if (!test_GetVersion(p, tctx, &handle)) {
1847 torture_comment(tctx, "GetVersion failed\n");
1848 ret = false;
1851 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1852 created3 = true;
1855 if (created3 &&
1856 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1857 created_subkey = true;
1860 if (created_subkey &&
1861 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1862 printf("DeleteKey failed\n");
1863 ret = false;
1866 /* The HKCR hive has a very large fanout */
1867 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1868 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1869 ret = false;
1871 } else {
1872 if (!test_key(p, tctx, &handle, 0, false)) {
1873 ret = false;
1877 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1879 return ret;
1882 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1884 struct torture_rpc_tcase *tcase;
1885 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1886 struct torture_test *test;
1888 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1889 &ndr_table_winreg);
1891 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1892 test_InitiateSystemShutdown);
1893 test->dangerous = true;
1895 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1896 test_InitiateSystemShutdownEx);
1897 test->dangerous = true;
1899 /* Basic tests without security descriptors */
1900 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1901 test_Open,
1902 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1903 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1904 test_Open,
1905 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1906 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1907 test_Open,
1908 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1909 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1910 test_Open,
1911 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1913 /* Security descriptor tests */
1914 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1915 test_Open_Security,
1916 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1917 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1918 test_Open_Security,
1919 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1920 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1921 test_Open_Security,
1922 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1923 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1924 test_Open_Security,
1925 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1927 return suite;