s3-docs: Adapt version in man ldbrename.
[Samba.git] / source4 / torture / rpc / winreg.c
blobb85dac7bf1091f4ee93fda622fe2b4ce9fcda7b7
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 ZERO_STRUCT(r);
84 r.in.handle = handle;
85 r.in.watch_subtree = true;
86 r.in.notify_filter = 0;
87 r.in.unknown = r.in.unknown2 = 0;
88 init_winreg_String(&r.in.string1, NULL);
89 init_winreg_String(&r.in.string2, NULL);
91 torture_assert_ntstatus_ok(tctx,
92 dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
93 "NotifyChangeKeyValue failed");
95 if (!W_ERROR_IS_OK(r.out.result)) {
96 torture_comment(tctx,
97 "NotifyChangeKeyValue failed - %s - not considering\n",
98 win_errstr(r.out.result));
99 return true;
102 return true;
105 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
106 struct policy_handle *handle, const char *name,
107 const char *kclass)
109 struct winreg_CreateKey r;
110 struct policy_handle newhandle;
111 enum winreg_CreateAction action_taken = 0;
113 ZERO_STRUCT(r);
114 r.in.handle = handle;
115 r.out.new_handle = &newhandle;
116 init_winreg_String(&r.in.name, name);
117 init_winreg_String(&r.in.keyclass, kclass);
118 r.in.options = 0x0;
119 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120 r.in.action_taken = r.out.action_taken = &action_taken;
121 r.in.secdesc = NULL;
123 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
124 "CreateKey failed");
126 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
128 return true;
133 createkey testing with a SD
135 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
136 struct torture_context *tctx,
137 struct policy_handle *handle, const char *name,
138 const char *kclass,
139 struct policy_handle *newhandle)
141 struct winreg_CreateKey r;
142 enum winreg_CreateAction action_taken = 0;
143 struct security_descriptor *sd;
144 DATA_BLOB sdblob;
145 struct winreg_SecBuf secbuf;
147 sd = security_descriptor_dacl_create(tctx,
149 NULL, NULL,
150 SID_NT_AUTHENTICATED_USERS,
151 SEC_ACE_TYPE_ACCESS_ALLOWED,
152 SEC_GENERIC_ALL,
153 SEC_ACE_FLAG_OBJECT_INHERIT |
154 SEC_ACE_FLAG_CONTAINER_INHERIT,
155 NULL);
157 torture_assert_ndr_success(tctx,
158 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
159 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
160 "Failed to push security_descriptor ?!\n");
162 secbuf.sd.data = sdblob.data;
163 secbuf.sd.len = sdblob.length;
164 secbuf.sd.size = sdblob.length;
165 secbuf.length = sdblob.length-10;
166 secbuf.inherit = 0;
168 ZERO_STRUCT(r);
169 r.in.handle = handle;
170 r.out.new_handle = newhandle;
171 init_winreg_String(&r.in.name, name);
172 init_winreg_String(&r.in.keyclass, kclass);
173 r.in.options = 0x0;
174 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
175 r.in.action_taken = r.out.action_taken = &action_taken;
176 r.in.secdesc = &secbuf;
178 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
179 "CreateKey with sd failed");
181 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
183 return true;
186 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
187 struct torture_context *tctx,
188 struct policy_handle *handle,
189 uint32_t *sec_info_ptr,
190 WERROR get_werr,
191 struct security_descriptor **sd_out)
193 struct winreg_GetKeySecurity r;
194 struct security_descriptor *sd = NULL;
195 uint32_t sec_info;
196 DATA_BLOB sdblob;
198 if (sec_info_ptr) {
199 sec_info = *sec_info_ptr;
200 } else {
201 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
204 ZERO_STRUCT(r);
206 r.in.handle = handle;
207 r.in.sec_info = sec_info;
208 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
209 r.in.sd->size = 0x1000;
211 torture_assert_ntstatus_ok(tctx,
212 dcerpc_winreg_GetKeySecurity(p, tctx, &r),
213 "GetKeySecurity failed");
215 torture_assert_werr_equal(tctx, r.out.result, get_werr,
216 "GetKeySecurity failed");
218 sdblob.data = r.out.sd->data;
219 sdblob.length = r.out.sd->len;
221 sd = talloc_zero(tctx, struct security_descriptor);
223 torture_assert_ndr_success(tctx,
224 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
225 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
226 "pull_security_descriptor failed");
228 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
229 NDR_PRINT_DEBUG(security_descriptor, sd);
232 if (sd_out) {
233 *sd_out = sd;
234 } else {
235 talloc_free(sd);
238 return true;
241 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
242 struct torture_context *tctx,
243 struct policy_handle *handle,
244 struct security_descriptor **sd_out)
246 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
249 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
250 struct torture_context *tctx,
251 struct policy_handle *handle,
252 uint32_t *sec_info_ptr,
253 struct security_descriptor *sd,
254 WERROR werr)
256 struct winreg_SetKeySecurity r;
257 struct KeySecurityData *sdata = NULL;
258 DATA_BLOB sdblob;
259 uint32_t sec_info;
261 ZERO_STRUCT(r);
263 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
264 NDR_PRINT_DEBUG(security_descriptor, sd);
267 torture_assert_ndr_success(tctx,
268 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
269 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
270 "push_security_descriptor failed");
272 sdata = talloc_zero(tctx, struct KeySecurityData);
273 sdata->data = sdblob.data;
274 sdata->size = sdblob.length;
275 sdata->len = sdblob.length;
277 if (sec_info_ptr) {
278 sec_info = *sec_info_ptr;
279 } else {
280 sec_info = SECINFO_UNPROTECTED_SACL |
281 SECINFO_UNPROTECTED_DACL;
282 if (sd->owner_sid) {
283 sec_info |= SECINFO_OWNER;
285 if (sd->group_sid) {
286 sec_info |= SECINFO_GROUP;
288 if (sd->sacl) {
289 sec_info |= SECINFO_SACL;
291 if (sd->dacl) {
292 sec_info |= SECINFO_DACL;
296 r.in.handle = handle;
297 r.in.sec_info = sec_info;
298 r.in.sd = sdata;
300 torture_assert_ntstatus_ok(tctx,
301 dcerpc_winreg_SetKeySecurity(p, tctx, &r),
302 "SetKeySecurity failed");
304 torture_assert_werr_equal(tctx, r.out.result, werr,
305 "SetKeySecurity failed");
307 return true;
310 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
311 struct torture_context *tctx,
312 struct policy_handle *handle,
313 struct security_descriptor *sd)
315 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
318 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
319 struct policy_handle *handle)
321 struct winreg_CloseKey r;
323 ZERO_STRUCT(r);
324 r.in.handle = r.out.handle = handle;
326 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
327 "CloseKey failed");
329 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
331 return true;
334 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
335 struct policy_handle *handle)
337 struct winreg_FlushKey r;
339 ZERO_STRUCT(r);
340 r.in.handle = handle;
342 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
343 "FlushKey failed");
345 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
347 return true;
350 static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
351 struct policy_handle *hive_handle,
352 const char *keyname, uint32_t access_mask,
353 struct policy_handle *key_handle,
354 WERROR open_werr,
355 bool *success)
357 struct winreg_OpenKey r;
359 ZERO_STRUCT(r);
360 r.in.parent_handle = hive_handle;
361 init_winreg_String(&r.in.keyname, keyname);
362 r.in.unknown = 0x00000000;
363 r.in.access_mask = access_mask;
364 r.out.handle = key_handle;
366 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
367 "OpenKey failed");
369 torture_assert_werr_equal(tctx, r.out.result, open_werr,
370 "OpenKey failed");
372 if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
373 *success = true;
376 return true;
379 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
380 struct policy_handle *hive_handle,
381 const char *keyname, struct policy_handle *key_handle)
383 return _test_OpenKey(p, tctx, hive_handle, keyname,
384 SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
385 WERR_OK, NULL);
388 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
389 struct policy_handle *handle, const char *key)
391 struct winreg_DeleteKey r;
393 ZERO_STRUCT(r);
394 r.in.handle = handle;
396 init_winreg_String(&r.in.key, key);
397 dcerpc_winreg_DeleteKey(p, tctx, &r);
399 return true;
402 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
403 struct torture_context *tctx,
404 struct policy_handle *handle,
405 WERROR get_werr,
406 WERROR set_werr)
408 struct security_descriptor *sd = NULL;
410 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
411 return false;
414 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
415 return false;
418 return true;
421 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
422 struct torture_context *tctx,
423 struct policy_handle *handle,
424 const char *key)
426 struct policy_handle new_handle;
427 bool ret = true;
429 torture_comment(tctx, "SecurityDescriptor get & set\n");
431 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
432 return false;
435 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
436 WERR_OK, WERR_OK)) {
437 ret = false;
440 if (!test_CloseKey(p, tctx, &new_handle)) {
441 return false;
444 return ret;
447 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
448 struct torture_context *tctx,
449 struct policy_handle *handle,
450 uint32_t access_mask,
451 const char *key,
452 WERROR open_werr,
453 WERROR get_werr,
454 WERROR set_werr)
456 struct policy_handle new_handle;
457 bool ret = true;
458 bool got_key = false;
460 if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
461 open_werr, &got_key)) {
462 return false;
465 if (!got_key) {
466 return true;
469 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
470 get_werr, set_werr)) {
471 ret = false;
474 if (!test_CloseKey(p, tctx, &new_handle)) {
475 return false;
478 return ret;
481 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
482 struct torture_context *tctx,
483 struct policy_handle *handle,
484 const struct dom_sid *sid)
486 struct security_descriptor *sd = NULL;
487 int i;
489 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
490 return false;
493 if (!sd || !sd->dacl) {
494 return false;
497 for (i = 0; i < sd->dacl->num_aces; i++) {
498 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
499 return true;
503 return false;
506 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
507 struct torture_context *tctx,
508 struct policy_handle *handle,
509 const char *key,
510 const struct dom_sid *sid)
512 struct policy_handle new_handle;
513 bool ret = true;
515 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
516 return false;
519 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
521 test_CloseKey(p, tctx, &new_handle);
523 return ret;
526 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
527 struct torture_context *tctx,
528 struct policy_handle *handle,
529 const struct dom_sid *sid)
531 struct security_descriptor *sd = NULL;
532 int i;
533 uint32_t sec_info = SECINFO_SACL;
535 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
536 return false;
539 if (!sd || !sd->sacl) {
540 return false;
543 for (i = 0; i < sd->sacl->num_aces; i++) {
544 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
545 return true;
549 return false;
552 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
553 struct torture_context *tctx,
554 struct policy_handle *handle,
555 const char *key,
556 const struct dom_sid *sid)
558 struct policy_handle new_handle;
559 bool ret = true;
561 if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
562 &new_handle, WERR_OK, NULL)) {
563 return false;
566 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
568 test_CloseKey(p, tctx, &new_handle);
570 return ret;
573 static bool test_owner_present(struct dcerpc_pipe *p,
574 struct torture_context *tctx,
575 struct policy_handle *handle,
576 const struct dom_sid *sid)
578 struct security_descriptor *sd = NULL;
579 uint32_t sec_info = SECINFO_OWNER;
581 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
582 return false;
585 if (!sd || !sd->owner_sid) {
586 return false;
589 return dom_sid_equal(sd->owner_sid, sid);
592 static bool _test_owner_present(struct dcerpc_pipe *p,
593 struct torture_context *tctx,
594 struct policy_handle *handle,
595 const char *key,
596 const struct dom_sid *sid)
598 struct policy_handle new_handle;
599 bool ret = true;
601 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
602 return false;
605 ret = test_owner_present(p, tctx, &new_handle, sid);
607 test_CloseKey(p, tctx, &new_handle);
609 return ret;
612 static bool test_group_present(struct dcerpc_pipe *p,
613 struct torture_context *tctx,
614 struct policy_handle *handle,
615 const struct dom_sid *sid)
617 struct security_descriptor *sd = NULL;
618 uint32_t sec_info = SECINFO_GROUP;
620 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
621 return false;
624 if (!sd || !sd->group_sid) {
625 return false;
628 return dom_sid_equal(sd->group_sid, sid);
631 static bool _test_group_present(struct dcerpc_pipe *p,
632 struct torture_context *tctx,
633 struct policy_handle *handle,
634 const char *key,
635 const struct dom_sid *sid)
637 struct policy_handle new_handle;
638 bool ret = true;
640 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
641 return false;
644 ret = test_group_present(p, tctx, &new_handle, sid);
646 test_CloseKey(p, tctx, &new_handle);
648 return ret;
651 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
652 struct torture_context *tctx,
653 struct policy_handle *handle,
654 const struct dom_sid *sid,
655 uint8_t flags)
657 struct security_descriptor *sd = NULL;
658 int i;
660 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
661 return false;
664 if (!sd || !sd->dacl) {
665 return false;
668 for (i = 0; i < sd->dacl->num_aces; i++) {
669 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
670 (sd->dacl->aces[i].flags == flags)) {
671 return true;
675 return false;
678 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
679 struct torture_context *tctx,
680 struct policy_handle *handle,
681 const struct security_ace *ace)
683 struct security_descriptor *sd = NULL;
684 int i;
686 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
687 return false;
690 if (!sd || !sd->dacl) {
691 return false;
694 for (i = 0; i < sd->dacl->num_aces; i++) {
695 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
696 return true;
700 return false;
703 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
704 struct torture_context *tctx,
705 struct policy_handle *handle,
706 const char *key,
707 struct security_descriptor *sd)
709 struct policy_handle new_handle;
710 bool ret = true;
712 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
713 return false;
716 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
717 ret = false;
720 if (!test_CloseKey(p, tctx, &new_handle)) {
721 ret = false;
724 return ret;
727 static bool test_BackupSecurity(struct dcerpc_pipe *p,
728 struct torture_context *tctx,
729 struct policy_handle *handle,
730 const char *key,
731 struct security_descriptor **sd)
733 struct policy_handle new_handle;
734 bool ret = true;
736 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
737 return false;
740 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
741 ret = false;
744 if (!test_CloseKey(p, tctx, &new_handle)) {
745 ret = false;
748 return ret;
751 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
752 struct torture_context *tctx,
753 struct policy_handle *handle,
754 const char *key)
756 /* get sd
757 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
758 set sd
759 get sd
760 check ace
761 add subkey
762 get sd
763 check ace
764 add subsubkey
765 get sd
766 check ace
767 del subsubkey
768 del subkey
769 reset sd
772 struct security_descriptor *sd = NULL;
773 struct security_descriptor *sd_orig = NULL;
774 struct security_ace *ace = NULL;
775 struct policy_handle new_handle;
776 NTSTATUS status;
777 bool ret = true;
779 torture_comment(tctx, "SecurityDescriptor inheritance\n");
781 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
782 return false;
785 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
786 return false;
789 sd_orig = security_descriptor_copy(tctx, sd);
790 if (sd_orig == NULL) {
791 return false;
794 ace = security_ace_create(tctx,
795 TEST_SID,
796 SEC_ACE_TYPE_ACCESS_ALLOWED,
797 SEC_STD_REQUIRED,
798 SEC_ACE_FLAG_CONTAINER_INHERIT);
800 status = security_descriptor_dacl_add(sd, ace);
801 if (!NT_STATUS_IS_OK(status)) {
802 printf("failed to add ace: %s\n", nt_errstr(status));
803 return false;
806 /* FIXME: add further tests for these flags */
807 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
808 SEC_DESC_SACL_AUTO_INHERITED;
810 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
811 return false;
814 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
815 printf("new ACE not present!\n");
816 return false;
819 if (!test_CloseKey(p, tctx, &new_handle)) {
820 return false;
823 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
824 ret = false;
825 goto out;
828 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
829 ret = false;
830 goto out;
833 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
834 printf("inherited ACE not present!\n");
835 ret = false;
836 goto out;
839 test_CloseKey(p, tctx, &new_handle);
840 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
841 ret = false;
842 goto out;
845 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
846 ret = false;
847 goto out;
850 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
851 printf("inherited ACE not present!\n");
852 ret = false;
853 goto out;
856 out:
857 test_CloseKey(p, tctx, &new_handle);
858 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
859 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
861 return true;
864 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
865 struct torture_context *tctx,
866 struct policy_handle *handle,
867 const char *key)
869 /* get sd
870 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
871 set sd
872 add subkey/subkey
873 get sd
874 check ace
875 get sd from subkey
876 check ace
877 del subkey/subkey
878 del subkey
879 reset sd
882 struct security_descriptor *sd = NULL;
883 struct security_descriptor *sd_orig = NULL;
884 struct security_ace *ace = NULL;
885 struct policy_handle new_handle;
886 struct dom_sid *sid = NULL;
887 NTSTATUS status;
888 bool ret = true;
889 uint8_t ace_flags = 0x0;
891 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
893 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
894 return false;
897 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
898 return false;
901 sd_orig = security_descriptor_copy(tctx, sd);
902 if (sd_orig == NULL) {
903 return false;
906 ace = security_ace_create(tctx,
907 TEST_SID,
908 SEC_ACE_TYPE_ACCESS_ALLOWED,
909 SEC_STD_REQUIRED,
910 SEC_ACE_FLAG_CONTAINER_INHERIT |
911 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
913 status = security_descriptor_dacl_add(sd, ace);
914 if (!NT_STATUS_IS_OK(status)) {
915 printf("failed to add ace: %s\n", nt_errstr(status));
916 return false;
919 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
920 return false;
923 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
924 printf("new ACE not present!\n");
925 return false;
928 if (!test_CloseKey(p, tctx, &new_handle)) {
929 return false;
932 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
933 return false;
936 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
937 ret = false;
938 goto out;
941 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
942 printf("inherited ACE present but should not!\n");
943 ret = false;
944 goto out;
947 sid = dom_sid_parse_talloc(tctx, TEST_SID);
948 if (sid == NULL) {
949 return false;
952 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
953 printf("inherited trustee SID present but should not!\n");
954 ret = false;
955 goto out;
958 test_CloseKey(p, tctx, &new_handle);
960 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
961 ret = false;
962 goto out;
965 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
966 printf("inherited ACE present but should not!\n");
967 ret = false;
968 goto out;
971 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
972 printf("inherited trustee SID with flags 0x%02x not present!\n",
973 ace_flags);
974 ret = false;
975 goto out;
978 out:
979 test_CloseKey(p, tctx, &new_handle);
980 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
981 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
983 return ret;
986 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
987 struct torture_context *tctx,
988 struct policy_handle *handle,
989 const char *key)
991 bool ret = true;
992 int i;
994 struct winreg_mask_result_table {
995 uint32_t access_mask;
996 WERROR open_werr;
997 WERROR get_werr;
998 WERROR set_werr;
999 } sd_mask_tests[] = {
1000 { 0,
1001 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1002 { SEC_FLAG_MAXIMUM_ALLOWED,
1003 WERR_OK, WERR_OK, WERR_OK },
1004 { SEC_STD_WRITE_DAC,
1005 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1006 { SEC_FLAG_SYSTEM_SECURITY,
1007 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1010 /* FIXME: before this test can ever run successfully we need a way to
1011 * correctly read a NULL security_descritpor in ndr, get the required
1012 * length, requery, etc.
1015 return true;
1017 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1019 torture_comment(tctx,
1020 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1021 sd_mask_tests[i].access_mask);
1022 torture_comment(tctx,
1023 "expecting: open %s, get: %s, set: %s\n",
1024 win_errstr(sd_mask_tests[i].open_werr),
1025 win_errstr(sd_mask_tests[i].get_werr),
1026 win_errstr(sd_mask_tests[i].set_werr));
1028 if (_test_SecurityDescriptor(p, tctx, handle,
1029 sd_mask_tests[i].access_mask, key,
1030 sd_mask_tests[i].open_werr,
1031 sd_mask_tests[i].get_werr,
1032 sd_mask_tests[i].set_werr)) {
1033 ret = false;
1037 return ret;
1040 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1041 struct torture_context *,
1042 struct policy_handle *,
1043 const char *,
1044 const struct dom_sid *);
1046 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1047 struct torture_context *tctx,
1048 struct policy_handle *handle,
1049 const char *key,
1050 const char *test,
1051 uint32_t access_mask,
1052 uint32_t sec_info,
1053 struct security_descriptor *sd,
1054 WERROR set_werr,
1055 bool expect_present,
1056 bool (*fn) (struct dcerpc_pipe *,
1057 struct torture_context *,
1058 struct policy_handle *,
1059 const char *,
1060 const struct dom_sid *),
1061 const struct dom_sid *sid)
1063 struct policy_handle new_handle;
1064 bool open_success = false;
1066 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1067 "0x%08x, access_mask: 0x%08x\n",
1068 test, sec_info, access_mask);
1070 if (!_test_OpenKey(p, tctx, handle, key,
1071 access_mask,
1072 &new_handle,
1073 WERR_OK,
1074 &open_success)) {
1075 return false;
1078 if (!open_success) {
1079 printf("key did not open\n");
1080 test_CloseKey(p, tctx, &new_handle);
1081 return false;
1084 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1086 set_werr)) {
1087 torture_warning(tctx,
1088 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1089 sec_info);
1090 smb_panic("");
1091 test_CloseKey(p, tctx, &new_handle);
1092 return false;
1095 test_CloseKey(p, tctx, &new_handle);
1097 if (W_ERROR_IS_OK(set_werr)) {
1098 bool present;
1099 present = fn(p, tctx, handle, key, sid);
1100 if ((expect_present) && (!present)) {
1101 torture_warning(tctx,
1102 "%s sid is not present!\n",
1103 test);
1104 return false;
1106 if ((!expect_present) && (present)) {
1107 torture_warning(tctx,
1108 "%s sid is present but not expected!\n",
1109 test);
1110 return false;
1114 return true;
1117 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1118 struct torture_context *tctx,
1119 struct policy_handle *handle,
1120 const char *key)
1122 struct security_descriptor *sd_orig = NULL;
1123 struct dom_sid *sid = NULL;
1124 bool ret = true;
1125 int i, a;
1127 struct security_descriptor *sd_owner =
1128 security_descriptor_dacl_create(tctx,
1130 TEST_SID, NULL, NULL);
1132 struct security_descriptor *sd_group =
1133 security_descriptor_dacl_create(tctx,
1135 NULL, TEST_SID, NULL);
1137 struct security_descriptor *sd_dacl =
1138 security_descriptor_dacl_create(tctx,
1140 NULL, NULL,
1141 TEST_SID,
1142 SEC_ACE_TYPE_ACCESS_ALLOWED,
1143 SEC_GENERIC_ALL,
1145 SID_NT_AUTHENTICATED_USERS,
1146 SEC_ACE_TYPE_ACCESS_ALLOWED,
1147 SEC_GENERIC_ALL,
1149 NULL);
1151 struct security_descriptor *sd_sacl =
1152 security_descriptor_sacl_create(tctx,
1154 NULL, NULL,
1155 TEST_SID,
1156 SEC_ACE_TYPE_SYSTEM_AUDIT,
1157 SEC_GENERIC_ALL,
1158 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1159 NULL);
1161 struct winreg_secinfo_table {
1162 struct security_descriptor *sd;
1163 uint32_t sec_info;
1164 WERROR set_werr;
1165 bool sid_present;
1166 secinfo_verify_fn fn;
1169 struct winreg_secinfo_table sec_info_owner_tests[] = {
1170 { sd_owner, 0, WERR_OK,
1171 false, (secinfo_verify_fn)_test_owner_present },
1172 { sd_owner, SECINFO_OWNER, WERR_OK,
1173 true, (secinfo_verify_fn)_test_owner_present },
1174 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1175 { sd_owner, SECINFO_DACL, WERR_OK,
1176 true, (secinfo_verify_fn)_test_owner_present },
1177 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1180 uint32_t sd_owner_good_access_masks[] = {
1181 SEC_FLAG_MAXIMUM_ALLOWED,
1182 /* SEC_STD_WRITE_OWNER, */
1185 struct winreg_secinfo_table sec_info_group_tests[] = {
1186 { sd_group, 0, WERR_OK,
1187 false, (secinfo_verify_fn)_test_group_present },
1188 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1189 { sd_group, SECINFO_GROUP, WERR_OK,
1190 true, (secinfo_verify_fn)_test_group_present },
1191 { sd_group, SECINFO_DACL, WERR_OK,
1192 true, (secinfo_verify_fn)_test_group_present },
1193 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1196 uint32_t sd_group_good_access_masks[] = {
1197 SEC_FLAG_MAXIMUM_ALLOWED,
1200 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1201 { sd_dacl, 0, WERR_OK,
1202 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1203 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1204 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1205 { sd_dacl, SECINFO_DACL, WERR_OK,
1206 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1207 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1210 uint32_t sd_dacl_good_access_masks[] = {
1211 SEC_FLAG_MAXIMUM_ALLOWED,
1212 SEC_STD_WRITE_DAC,
1215 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1216 { sd_sacl, 0, WERR_OK,
1217 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1218 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1219 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1220 { sd_sacl, SECINFO_DACL, WERR_OK,
1221 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1222 { sd_sacl, SECINFO_SACL, WERR_OK,
1223 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1226 uint32_t sd_sacl_good_access_masks[] = {
1227 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1228 /* SEC_FLAG_SYSTEM_SECURITY, */
1231 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1232 if (sid == NULL) {
1233 return false;
1236 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1237 return false;
1240 /* OWNER */
1242 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1244 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1246 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1247 key,
1248 "OWNER",
1249 sd_owner_good_access_masks[a],
1250 sec_info_owner_tests[i].sec_info,
1251 sec_info_owner_tests[i].sd,
1252 sec_info_owner_tests[i].set_werr,
1253 sec_info_owner_tests[i].sid_present,
1254 sec_info_owner_tests[i].fn,
1255 sid))
1257 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1258 ret = false;
1259 goto out;
1264 /* GROUP */
1266 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1268 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1270 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1271 key,
1272 "GROUP",
1273 sd_group_good_access_masks[a],
1274 sec_info_group_tests[i].sec_info,
1275 sec_info_group_tests[i].sd,
1276 sec_info_group_tests[i].set_werr,
1277 sec_info_group_tests[i].sid_present,
1278 sec_info_group_tests[i].fn,
1279 sid))
1281 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1282 ret = false;
1283 goto out;
1288 /* DACL */
1290 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1292 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1294 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1295 key,
1296 "DACL",
1297 sd_dacl_good_access_masks[a],
1298 sec_info_dacl_tests[i].sec_info,
1299 sec_info_dacl_tests[i].sd,
1300 sec_info_dacl_tests[i].set_werr,
1301 sec_info_dacl_tests[i].sid_present,
1302 sec_info_dacl_tests[i].fn,
1303 sid))
1305 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1306 ret = false;
1307 goto out;
1312 /* SACL */
1314 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1316 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1318 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1319 key,
1320 "SACL",
1321 sd_sacl_good_access_masks[a],
1322 sec_info_sacl_tests[i].sec_info,
1323 sec_info_sacl_tests[i].sd,
1324 sec_info_sacl_tests[i].set_werr,
1325 sec_info_sacl_tests[i].sid_present,
1326 sec_info_sacl_tests[i].fn,
1327 sid))
1329 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1330 ret = false;
1331 goto out;
1336 out:
1337 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1339 return ret;
1342 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1343 struct torture_context *tctx,
1344 struct policy_handle *handle,
1345 const char *key)
1347 bool ret = true;
1349 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1350 printf("test_SecurityDescriptor failed\n");
1351 ret = false;
1354 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1355 printf("test_SecurityDescriptorInheritance failed\n");
1356 ret = false;
1359 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1360 printf("test_SecurityDescriptorBlockInheritance failed\n");
1361 ret = false;
1364 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1365 printf("test_SecurityDescriptorsSecInfo failed\n");
1366 ret = false;
1369 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1370 printf("test_SecurityDescriptorsMasks failed\n");
1371 ret = false;
1374 return ret;
1377 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1378 struct policy_handle *handle, const char *key)
1380 NTSTATUS status;
1381 struct winreg_DeleteKey r;
1383 r.in.handle = handle;
1384 init_winreg_String(&r.in.key, key);
1386 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1388 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1389 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1391 return true;
1394 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1395 struct torture_context *tctx,
1396 struct policy_handle *handle, char *kclass)
1398 struct winreg_QueryInfoKey r;
1399 uint32_t num_subkeys, max_subkeylen, max_classlen,
1400 num_values, max_valnamelen, max_valbufsize,
1401 secdescsize;
1402 NTTIME last_changed_time;
1404 ZERO_STRUCT(r);
1405 r.in.handle = handle;
1406 r.out.num_subkeys = &num_subkeys;
1407 r.out.max_subkeylen = &max_subkeylen;
1408 r.out.max_classlen = &max_classlen;
1409 r.out.num_values = &num_values;
1410 r.out.max_valnamelen = &max_valnamelen;
1411 r.out.max_valbufsize = &max_valbufsize;
1412 r.out.secdescsize = &secdescsize;
1413 r.out.last_changed_time = &last_changed_time;
1415 r.out.classname = talloc(tctx, struct winreg_String);
1417 r.in.classname = talloc(tctx, struct winreg_String);
1418 init_winreg_String(r.in.classname, kclass);
1420 torture_assert_ntstatus_ok(tctx,
1421 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1422 "QueryInfoKey failed");
1424 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1426 return true;
1429 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1430 struct policy_handle *handle, int depth,
1431 bool test_security);
1433 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1434 struct policy_handle *handle, int depth,
1435 bool test_security)
1437 struct winreg_EnumKey r;
1438 struct winreg_StringBuf kclass, name;
1439 NTSTATUS status;
1440 NTTIME t = 0;
1442 kclass.name = "";
1443 kclass.size = 1024;
1445 ZERO_STRUCT(r);
1446 r.in.handle = handle;
1447 r.in.enum_index = 0;
1448 r.in.name = &name;
1449 r.in.keyclass = &kclass;
1450 r.out.name = &name;
1451 r.in.last_changed_time = &t;
1453 do {
1454 name.name = NULL;
1455 name.size = 1024;
1457 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1459 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1460 struct policy_handle key_handle;
1462 torture_comment(tctx, "EnumKey: %d: %s\n",
1463 r.in.enum_index,
1464 r.out.name->name);
1466 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1467 &key_handle)) {
1468 } else {
1469 test_key(p, tctx, &key_handle,
1470 depth + 1, test_security);
1474 r.in.enum_index++;
1476 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1478 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1480 if (!W_ERROR_IS_OK(r.out.result) &&
1481 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1482 torture_fail(tctx, "EnumKey failed");
1485 return true;
1488 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1489 struct torture_context *tctx,
1490 struct policy_handle *handle,
1491 const char *valuename)
1493 struct winreg_QueryMultipleValues r;
1494 NTSTATUS status;
1495 uint32_t bufsize=0;
1497 ZERO_STRUCT(r);
1498 r.in.key_handle = handle;
1499 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1500 r.in.values[0].name = talloc(tctx, struct winreg_String);
1501 r.in.values[0].name->name = valuename;
1502 r.in.values[0].offset = 0;
1503 r.in.values[0].length = 0;
1504 r.in.values[0].type = 0;
1506 r.in.num_values = 1;
1507 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1508 *r.in.buffer_size = bufsize;
1509 do {
1510 *r.in.buffer_size = bufsize;
1511 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1512 *r.in.buffer_size);
1514 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1516 if(NT_STATUS_IS_ERR(status))
1517 torture_fail(tctx, "QueryMultipleValues failed");
1519 talloc_free(r.in.buffer);
1520 bufsize += 0x20;
1521 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1523 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1525 return true;
1528 static bool test_QueryValue(struct dcerpc_pipe *p,
1529 struct torture_context *tctx,
1530 struct policy_handle *handle,
1531 const char *valuename)
1533 struct winreg_QueryValue r;
1534 NTSTATUS status;
1535 enum winreg_Type zero_type = 0;
1536 uint32_t offered = 0xfff;
1537 uint32_t zero = 0;
1539 ZERO_STRUCT(r);
1540 r.in.handle = handle;
1541 r.in.data = NULL;
1542 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1543 r.in.value_name->name = valuename;
1544 r.in.type = &zero_type;
1545 r.in.data_size = &offered;
1546 r.in.data_length = &zero;
1548 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1549 if (NT_STATUS_IS_ERR(status)) {
1550 torture_fail(tctx, "QueryValue failed");
1553 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1555 return true;
1558 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1559 struct policy_handle *handle, int max_valnamelen,
1560 int max_valbufsize)
1562 struct winreg_EnumValue r;
1563 enum winreg_Type type = 0;
1564 uint32_t size = max_valbufsize, zero = 0;
1565 bool ret = true;
1566 uint8_t buf8;
1567 struct winreg_ValNameBuf name;
1569 name.name = "";
1570 name.size = 1024;
1572 ZERO_STRUCT(r);
1573 r.in.handle = handle;
1574 r.in.enum_index = 0;
1575 r.in.name = &name;
1576 r.out.name = &name;
1577 r.in.type = &type;
1578 r.in.value = &buf8;
1579 r.in.length = &zero;
1580 r.in.size = &size;
1582 do {
1583 torture_assert_ntstatus_ok(tctx,
1584 dcerpc_winreg_EnumValue(p, tctx, &r),
1585 "EnumValue failed");
1587 if (W_ERROR_IS_OK(r.out.result)) {
1588 ret &= test_QueryValue(p, tctx, handle,
1589 r.out.name->name);
1590 ret &= test_QueryMultipleValues(p, tctx, handle,
1591 r.out.name->name);
1594 r.in.enum_index++;
1595 } while (W_ERROR_IS_OK(r.out.result));
1597 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1598 "EnumValue failed");
1600 return ret;
1603 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1604 struct torture_context *tctx)
1606 struct winreg_AbortSystemShutdown r;
1607 uint16_t server = 0x0;
1609 ZERO_STRUCT(r);
1610 r.in.server = &server;
1612 torture_assert_ntstatus_ok(tctx,
1613 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1614 "AbortSystemShutdown failed");
1616 torture_assert_werr_ok(tctx, r.out.result,
1617 "AbortSystemShutdown failed");
1619 return true;
1622 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1623 struct dcerpc_pipe *p)
1625 struct winreg_InitiateSystemShutdown r;
1626 uint16_t hostname = 0x0;
1628 ZERO_STRUCT(r);
1629 r.in.hostname = &hostname;
1630 r.in.message = talloc(tctx, struct lsa_StringLarge);
1631 init_lsa_StringLarge(r.in.message, "spottyfood");
1632 r.in.force_apps = 1;
1633 r.in.timeout = 30;
1634 r.in.do_reboot = 1;
1636 torture_assert_ntstatus_ok(tctx,
1637 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1638 "InitiateSystemShutdown failed");
1640 torture_assert_werr_ok(tctx, r.out.result,
1641 "InitiateSystemShutdown failed");
1643 return test_AbortSystemShutdown(p, tctx);
1647 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1648 struct dcerpc_pipe *p)
1650 struct winreg_InitiateSystemShutdownEx r;
1651 uint16_t hostname = 0x0;
1653 ZERO_STRUCT(r);
1654 r.in.hostname = &hostname;
1655 r.in.message = talloc(tctx, struct lsa_StringLarge);
1656 init_lsa_StringLarge(r.in.message, "spottyfood");
1657 r.in.force_apps = 1;
1658 r.in.timeout = 30;
1659 r.in.do_reboot = 1;
1660 r.in.reason = 0;
1662 torture_assert_ntstatus_ok(tctx,
1663 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1664 "InitiateSystemShutdownEx failed");
1666 torture_assert_werr_ok(tctx, r.out.result,
1667 "InitiateSystemShutdownEx failed");
1669 return test_AbortSystemShutdown(p, tctx);
1671 #define MAX_DEPTH 2 /* Only go this far down the tree */
1673 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1674 struct policy_handle *handle, int depth,
1675 bool test_security)
1677 if (depth == MAX_DEPTH)
1678 return true;
1680 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1683 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1686 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1689 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1692 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1695 test_CloseKey(p, tctx, handle);
1697 return true;
1700 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1702 static bool test_Open_Security(struct torture_context *tctx,
1703 struct dcerpc_pipe *p, void *userdata)
1705 struct policy_handle handle, newhandle;
1706 bool ret = true, created2 = false;
1707 bool created4 = false;
1708 struct winreg_OpenHKLM r;
1710 winreg_open_fn open_fn = userdata;
1712 ZERO_STRUCT(r);
1713 r.in.system_name = 0;
1714 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1715 r.out.handle = &handle;
1717 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1718 "open");
1720 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1722 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1723 torture_comment(tctx,
1724 "CreateKey (TEST_KEY_BASE) failed\n");
1727 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1728 NULL, &newhandle)) {
1729 created2 = true;
1732 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1733 printf("CloseKey failed\n");
1734 ret = false;
1737 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1738 created4 = true;
1741 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1742 printf("CloseKey failed\n");
1743 ret = false;
1746 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1747 ret = false;
1750 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1751 printf("DeleteKey failed\n");
1752 ret = false;
1755 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1756 printf("DeleteKey failed\n");
1757 ret = false;
1760 /* The HKCR hive has a very large fanout */
1761 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1762 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1763 ret = false;
1765 } else {
1766 if (!test_key(p, tctx, &handle, 0, true)) {
1767 ret = false;
1771 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1773 return ret;
1776 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1777 void *userdata)
1779 struct policy_handle handle, newhandle;
1780 bool ret = true, created = false, deleted = false;
1781 bool created3 = false, created_subkey = false;
1782 struct winreg_OpenHKLM r;
1784 winreg_open_fn open_fn = userdata;
1786 ZERO_STRUCT(r);
1787 r.in.system_name = 0;
1788 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1789 r.out.handle = &handle;
1791 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1792 "open");
1794 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1796 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1797 torture_comment(tctx,
1798 "CreateKey (TEST_KEY_BASE) failed\n");
1801 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1802 torture_comment(tctx,
1803 "CreateKey failed - not considering a failure\n");
1804 } else {
1805 created = true;
1808 if (created && !test_FlushKey(p, tctx, &handle)) {
1809 torture_comment(tctx, "FlushKey failed\n");
1810 ret = false;
1813 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1814 torture_fail(tctx,
1815 "CreateKey failed (OpenKey after Create didn't work)\n");
1817 if (created && !test_CloseKey(p, tctx, &newhandle))
1818 torture_fail(tctx,
1819 "CreateKey failed (CloseKey after Open didn't work)\n");
1821 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1822 torture_comment(tctx, "DeleteKey failed\n");
1823 ret = false;
1824 } else {
1825 deleted = true;
1828 if (created && !test_FlushKey(p, tctx, &handle)) {
1829 torture_comment(tctx, "FlushKey failed\n");
1830 ret = false;
1833 if (created && deleted &&
1834 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1835 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1836 WERR_BADFILE, NULL)) {
1837 torture_comment(tctx,
1838 "DeleteKey failed (OpenKey after Delete "
1839 "did not return WERR_BADFILE)\n");
1840 ret = false;
1843 if (!test_GetVersion(p, tctx, &handle)) {
1844 torture_comment(tctx, "GetVersion failed\n");
1845 ret = false;
1848 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1849 created3 = true;
1852 if (created3 &&
1853 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1854 created_subkey = true;
1857 if (created_subkey &&
1858 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1859 printf("DeleteKey failed\n");
1860 ret = false;
1863 /* The HKCR hive has a very large fanout */
1864 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1865 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1866 ret = false;
1868 } else {
1869 if (!test_key(p, tctx, &handle, 0, false)) {
1870 ret = false;
1874 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1876 return ret;
1879 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1881 struct torture_rpc_tcase *tcase;
1882 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1883 struct torture_test *test;
1885 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1886 &ndr_table_winreg);
1888 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1889 test_InitiateSystemShutdown);
1890 test->dangerous = true;
1892 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1893 test_InitiateSystemShutdownEx);
1894 test->dangerous = true;
1896 /* Basic tests without security descriptors */
1897 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1898 test_Open,
1899 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1900 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1901 test_Open,
1902 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1903 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1904 test_Open,
1905 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1906 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1907 test_Open,
1908 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1910 /* Security descriptor tests */
1911 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1912 test_Open_Security,
1913 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1914 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1915 test_Open_Security,
1916 (winreg_open_fn)dcerpc_winreg_OpenHKU);
1917 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1918 test_Open_Security,
1919 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1920 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1921 test_Open_Security,
1922 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1924 return suite;