s4-smbtorture: disable winreg QueryValue test for today.
[Samba/nascimento.git] / source4 / torture / rpc / winreg.c
blob7368b2d12b79682af27fc536a8c4aa8b127c814a
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_SetValue(struct dcerpc_pipe *p,
1433 struct torture_context *tctx,
1434 struct policy_handle *handle,
1435 const char *value_name,
1436 enum winreg_Type type,
1437 uint8_t *data,
1438 uint32_t size)
1440 struct winreg_SetValue r;
1441 struct winreg_String name;
1443 torture_comment(tctx, "Testing SetValue(%s)\n", value_name);
1445 init_winreg_String(&name, value_name);
1447 r.in.handle = handle;
1448 r.in.name = name;
1449 r.in.type = type;
1450 r.in.data = data;
1451 r.in.size = size;
1453 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue(p, tctx, &r),
1454 "winreg_SetValue failed");
1455 torture_assert_werr_ok(tctx, r.out.result,
1456 "winreg_SetValue failed");
1458 return true;
1461 static bool test_DeleteValue(struct dcerpc_pipe *p,
1462 struct torture_context *tctx,
1463 struct policy_handle *handle,
1464 const char *value_name)
1466 struct winreg_DeleteValue r;
1467 struct winreg_String value;
1469 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1471 init_winreg_String(&value, value_name);
1473 r.in.handle = handle;
1474 r.in.value = value;
1476 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue(p, tctx, &r),
1477 "winreg_DeleteValue failed");
1478 torture_assert_werr_ok(tctx, r.out.result,
1479 "winreg_DeleteValue failed");
1481 return true;
1484 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1485 struct policy_handle *handle, int depth,
1486 bool test_security);
1488 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1489 struct policy_handle *handle, int depth,
1490 bool test_security)
1492 struct winreg_EnumKey r;
1493 struct winreg_StringBuf kclass, name;
1494 NTSTATUS status;
1495 NTTIME t = 0;
1497 kclass.name = "";
1498 kclass.size = 1024;
1500 ZERO_STRUCT(r);
1501 r.in.handle = handle;
1502 r.in.enum_index = 0;
1503 r.in.name = &name;
1504 r.in.keyclass = &kclass;
1505 r.out.name = &name;
1506 r.in.last_changed_time = &t;
1508 do {
1509 name.name = NULL;
1510 name.size = 1024;
1512 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1514 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1515 struct policy_handle key_handle;
1517 torture_comment(tctx, "EnumKey: %d: %s\n",
1518 r.in.enum_index,
1519 r.out.name->name);
1521 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1522 &key_handle)) {
1523 } else {
1524 test_key(p, tctx, &key_handle,
1525 depth + 1, test_security);
1529 r.in.enum_index++;
1531 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1533 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1535 if (!W_ERROR_IS_OK(r.out.result) &&
1536 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1537 torture_fail(tctx, "EnumKey failed");
1540 return true;
1543 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1544 struct torture_context *tctx,
1545 struct policy_handle *handle,
1546 const char *valuename)
1548 struct winreg_QueryMultipleValues r;
1549 NTSTATUS status;
1550 uint32_t bufsize=0;
1552 ZERO_STRUCT(r);
1553 r.in.key_handle = handle;
1554 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1555 r.in.values[0].name = talloc(tctx, struct winreg_String);
1556 r.in.values[0].name->name = valuename;
1557 r.in.values[0].offset = 0;
1558 r.in.values[0].length = 0;
1559 r.in.values[0].type = 0;
1561 r.in.num_values = 1;
1562 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1563 *r.in.buffer_size = bufsize;
1564 do {
1565 *r.in.buffer_size = bufsize;
1566 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1567 *r.in.buffer_size);
1569 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1571 if(NT_STATUS_IS_ERR(status))
1572 torture_fail(tctx, "QueryMultipleValues failed");
1574 talloc_free(r.in.buffer);
1575 bufsize += 0x20;
1576 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1578 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1580 return true;
1583 static bool test_QueryValue(struct dcerpc_pipe *p,
1584 struct torture_context *tctx,
1585 struct policy_handle *handle,
1586 const char *valuename)
1588 struct winreg_QueryValue r;
1589 NTSTATUS status;
1590 enum winreg_Type zero_type = 0;
1591 uint32_t offered = 0xfff;
1592 uint32_t zero = 0;
1594 ZERO_STRUCT(r);
1595 r.in.handle = handle;
1596 r.in.data = NULL;
1597 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1598 r.in.value_name->name = valuename;
1599 r.in.type = &zero_type;
1600 r.in.data_size = &offered;
1601 r.in.data_length = &zero;
1603 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1604 if (NT_STATUS_IS_ERR(status)) {
1605 torture_fail(tctx, "QueryValue failed");
1608 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1610 return true;
1613 static bool test_QueryValue_full(struct dcerpc_pipe *p,
1614 struct torture_context *tctx,
1615 struct policy_handle *handle,
1616 const char *valuename,
1617 bool existing_value)
1619 struct winreg_QueryValue r;
1620 struct winreg_String value_name;
1621 enum winreg_Type type = REG_NONE;
1622 uint32_t data_size = 0;
1623 uint32_t real_data_size = 0;
1624 uint32_t data_length = 0;
1625 uint8_t *data = NULL;
1626 WERROR expected_error = WERR_BADFILE;
1628 if (valuename == NULL) {
1629 expected_error = WERR_INVALID_PARAM;
1632 ZERO_STRUCT(r);
1634 init_winreg_String(&value_name, NULL);
1636 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1638 r.in.handle = handle;
1639 r.in.value_name = &value_name;
1641 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r), "QueryValue failed");
1642 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1643 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1645 init_winreg_String(&value_name, valuename);
1646 r.in.value_name = &value_name;
1648 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1649 "QueryValue failed");
1650 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1651 "QueryValue failed");
1653 r.in.type = &type;
1654 r.out.type = &type;
1655 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1656 "QueryValue failed");
1657 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1658 "QueryValue failed");
1660 r.in.data_length = &data_length;
1661 r.out.data_length = &data_length;
1662 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1663 "QueryValue failed");
1664 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1665 "QueryValue failed");
1667 r.in.data_size = &data_size;
1668 r.out.data_size = &data_size;
1669 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1670 "QueryValue failed");
1671 if (existing_value) {
1672 torture_assert_werr_ok(tctx, r.out.result,
1673 "QueryValue failed");
1674 } else {
1675 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1676 "QueryValue failed");
1679 real_data_size = *r.out.data_size;
1681 data = talloc_zero_array(tctx, uint8_t, 0);
1682 r.in.data = data;
1683 r.out.data = data;
1684 *r.in.data_size = 0;
1685 *r.out.data_size = 0;
1686 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1687 "QueryValue failed");
1688 if (existing_value) {
1689 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1690 "QueryValue failed");
1691 } else {
1692 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1693 "QueryValue failed");
1696 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1697 r.in.data = data;
1698 r.out.data = data;
1699 r.in.data_size = &real_data_size;
1700 r.out.data_size = &real_data_size;
1701 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1702 "QueryValue failed");
1703 if (existing_value) {
1704 torture_assert_werr_ok(tctx, r.out.result,
1705 "QueryValue failed");
1706 } else {
1707 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1708 "QueryValue failed");
1711 return true;
1714 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1715 struct policy_handle *handle, int max_valnamelen,
1716 int max_valbufsize)
1718 struct winreg_EnumValue r;
1719 enum winreg_Type type = 0;
1720 uint32_t size = max_valbufsize, zero = 0;
1721 bool ret = true;
1722 uint8_t buf8;
1723 struct winreg_ValNameBuf name;
1725 name.name = "";
1726 name.size = 1024;
1728 ZERO_STRUCT(r);
1729 r.in.handle = handle;
1730 r.in.enum_index = 0;
1731 r.in.name = &name;
1732 r.out.name = &name;
1733 r.in.type = &type;
1734 r.in.value = &buf8;
1735 r.in.length = &zero;
1736 r.in.size = &size;
1738 do {
1739 torture_assert_ntstatus_ok(tctx,
1740 dcerpc_winreg_EnumValue(p, tctx, &r),
1741 "EnumValue failed");
1743 if (W_ERROR_IS_OK(r.out.result)) {
1744 ret &= test_QueryValue(p, tctx, handle,
1745 r.out.name->name);
1746 ret &= test_QueryMultipleValues(p, tctx, handle,
1747 r.out.name->name);
1750 r.in.enum_index++;
1751 } while (W_ERROR_IS_OK(r.out.result));
1753 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1754 "EnumValue failed");
1756 return ret;
1759 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1760 struct torture_context *tctx)
1762 struct winreg_AbortSystemShutdown r;
1763 uint16_t server = 0x0;
1765 ZERO_STRUCT(r);
1766 r.in.server = &server;
1768 torture_assert_ntstatus_ok(tctx,
1769 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1770 "AbortSystemShutdown failed");
1772 torture_assert_werr_ok(tctx, r.out.result,
1773 "AbortSystemShutdown failed");
1775 return true;
1778 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1779 struct dcerpc_pipe *p)
1781 struct winreg_InitiateSystemShutdown r;
1782 uint16_t hostname = 0x0;
1784 ZERO_STRUCT(r);
1785 r.in.hostname = &hostname;
1786 r.in.message = talloc(tctx, struct lsa_StringLarge);
1787 init_lsa_StringLarge(r.in.message, "spottyfood");
1788 r.in.force_apps = 1;
1789 r.in.timeout = 30;
1790 r.in.do_reboot = 1;
1792 torture_assert_ntstatus_ok(tctx,
1793 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1794 "InitiateSystemShutdown failed");
1796 torture_assert_werr_ok(tctx, r.out.result,
1797 "InitiateSystemShutdown failed");
1799 return test_AbortSystemShutdown(p, tctx);
1803 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1804 struct dcerpc_pipe *p)
1806 struct winreg_InitiateSystemShutdownEx r;
1807 uint16_t hostname = 0x0;
1809 ZERO_STRUCT(r);
1810 r.in.hostname = &hostname;
1811 r.in.message = talloc(tctx, struct lsa_StringLarge);
1812 init_lsa_StringLarge(r.in.message, "spottyfood");
1813 r.in.force_apps = 1;
1814 r.in.timeout = 30;
1815 r.in.do_reboot = 1;
1816 r.in.reason = 0;
1818 torture_assert_ntstatus_ok(tctx,
1819 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1820 "InitiateSystemShutdownEx failed");
1822 torture_assert_werr_ok(tctx, r.out.result,
1823 "InitiateSystemShutdownEx failed");
1825 return test_AbortSystemShutdown(p, tctx);
1827 #define MAX_DEPTH 2 /* Only go this far down the tree */
1829 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1830 struct policy_handle *handle, int depth,
1831 bool test_security)
1833 if (depth == MAX_DEPTH)
1834 return true;
1836 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1839 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1842 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1845 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1848 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1851 test_CloseKey(p, tctx, handle);
1853 return true;
1856 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1858 static bool test_Open_Security(struct torture_context *tctx,
1859 struct dcerpc_pipe *p, void *userdata)
1861 struct policy_handle handle, newhandle;
1862 bool ret = true, created2 = false;
1863 bool created4 = false;
1864 struct winreg_OpenHKLM r;
1866 winreg_open_fn open_fn = userdata;
1868 ZERO_STRUCT(r);
1869 r.in.system_name = 0;
1870 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1871 r.out.handle = &handle;
1873 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1874 "open");
1876 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1878 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1879 torture_comment(tctx,
1880 "CreateKey (TEST_KEY_BASE) failed\n");
1883 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1884 NULL, &newhandle)) {
1885 created2 = true;
1888 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1889 printf("CloseKey failed\n");
1890 ret = false;
1893 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1894 created4 = true;
1897 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1898 printf("CloseKey failed\n");
1899 ret = false;
1902 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1903 ret = false;
1906 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1907 printf("DeleteKey failed\n");
1908 ret = false;
1911 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1912 printf("DeleteKey failed\n");
1913 ret = false;
1916 /* The HKCR hive has a very large fanout */
1917 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1918 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1919 ret = false;
1921 } else {
1922 if (!test_key(p, tctx, &handle, 0, true)) {
1923 ret = false;
1927 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1929 return ret;
1932 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
1933 #define VALUE_CURRENT_VERSION "CurrentVersion"
1935 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1936 void *userdata)
1938 struct policy_handle handle, newhandle;
1939 bool ret = true, created = false, deleted = false;
1940 bool created3 = false, created_subkey = false;
1941 struct winreg_OpenHKLM r;
1943 winreg_open_fn open_fn = userdata;
1945 ZERO_STRUCT(r);
1946 r.in.system_name = 0;
1947 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1948 r.out.handle = &handle;
1950 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1951 "open");
1952 #if 0 /* FIXME: s3 and s4 crash on QueryValue */
1953 if (open_fn == (void *)dcerpc_winreg_OpenHKLM) {
1954 #if 0
1955 torture_assert(tctx, test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, &newhandle),
1956 "failed to open current version key");
1957 #else
1958 torture_assert(tctx, _test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, KEY_QUERY_VALUE, &newhandle, WERR_OK, NULL),
1959 "failed to open current version key");
1960 #endif
1961 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
1962 "failed to query current version");
1963 torture_assert(tctx, test_CloseKey(p, tctx, &newhandle),
1964 "failed to close current version key");
1966 #endif /* FIXME */
1967 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1969 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1970 torture_comment(tctx,
1971 "CreateKey (TEST_KEY_BASE) failed\n");
1974 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1975 torture_comment(tctx,
1976 "CreateKey failed - not considering a failure\n");
1977 } else {
1978 created = true;
1981 if (created && !test_FlushKey(p, tctx, &handle)) {
1982 torture_comment(tctx, "FlushKey failed\n");
1983 ret = false;
1986 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1987 torture_fail(tctx,
1988 "CreateKey failed (OpenKey after Create didn't work)\n");
1990 if (created && !test_CloseKey(p, tctx, &newhandle))
1991 torture_fail(tctx,
1992 "CreateKey failed (CloseKey after Open didn't work)\n");
1994 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1995 torture_comment(tctx, "DeleteKey failed\n");
1996 ret = false;
1997 } else {
1998 deleted = true;
2001 if (created && !test_FlushKey(p, tctx, &handle)) {
2002 torture_comment(tctx, "FlushKey failed\n");
2003 ret = false;
2006 if (created && deleted &&
2007 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
2008 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
2009 WERR_BADFILE, NULL)) {
2010 torture_comment(tctx,
2011 "DeleteKey failed (OpenKey after Delete "
2012 "did not return WERR_BADFILE)\n");
2013 ret = false;
2016 if (!test_GetVersion(p, tctx, &handle)) {
2017 torture_comment(tctx, "GetVersion failed\n");
2018 ret = false;
2021 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
2022 created3 = true;
2025 if (created3 &&
2026 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
2027 created_subkey = true;
2030 if (created_subkey &&
2031 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
2032 printf("DeleteKey failed\n");
2033 ret = false;
2036 /* The HKCR hive has a very large fanout */
2037 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2038 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2039 ret = false;
2041 } else {
2042 if (!test_key(p, tctx, &handle, 0, false)) {
2043 ret = false;
2047 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2049 return ret;
2052 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2054 struct torture_rpc_tcase *tcase;
2055 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2056 struct torture_test *test;
2058 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2059 &ndr_table_winreg);
2061 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2062 test_InitiateSystemShutdown);
2063 test->dangerous = true;
2065 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2066 test_InitiateSystemShutdownEx);
2067 test->dangerous = true;
2069 /* Basic tests without security descriptors */
2070 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
2071 test_Open,
2072 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2073 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
2074 test_Open,
2075 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2076 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
2077 test_Open,
2078 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2079 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
2080 test_Open,
2081 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2083 /* Security descriptor tests */
2084 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
2085 test_Open_Security,
2086 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2087 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
2088 test_Open_Security,
2089 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2090 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
2091 test_Open_Security,
2092 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2093 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
2094 test_Open_Security,
2095 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2097 return suite;