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/>.
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"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "smbtorture test"
32 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
33 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
34 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
35 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
36 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
37 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
38 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
41 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
43 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 static void init_winreg_String(struct winreg_String *name, const char *s)
52 name->name_len = 2 * (strlen_m(s) + 1);
53 name->name_size = name->name_len;
60 static bool test_GetVersion(struct dcerpc_pipe *p,
61 struct torture_context *tctx,
62 struct policy_handle *handle)
64 struct winreg_GetVersion r;
71 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
74 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
79 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
80 struct torture_context *tctx,
81 struct policy_handle *handle)
83 struct winreg_NotifyChangeKeyValue r;
87 r.in.watch_subtree = true;
88 r.in.notify_filter = 0;
89 r.in.unknown = r.in.unknown2 = 0;
90 init_winreg_String(&r.in.string1, NULL);
91 init_winreg_String(&r.in.string2, NULL);
93 if (torture_setting_bool(tctx, "samba3", false)) {
94 torture_skip(tctx, "skipping NotifyChangeKeyValue test against Samba 3");
97 torture_assert_ntstatus_ok(tctx,
98 dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
99 "NotifyChangeKeyValue failed");
101 if (!W_ERROR_IS_OK(r.out.result)) {
102 torture_comment(tctx,
103 "NotifyChangeKeyValue failed - %s - not considering\n",
104 win_errstr(r.out.result));
111 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
112 struct policy_handle *handle, const char *name,
115 struct winreg_CreateKey r;
116 struct policy_handle newhandle;
117 enum winreg_CreateAction action_taken = 0;
120 r.in.handle = handle;
121 r.out.new_handle = &newhandle;
122 init_winreg_String(&r.in.name, name);
123 init_winreg_String(&r.in.keyclass, kclass);
125 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
126 r.in.action_taken = r.out.action_taken = &action_taken;
129 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
132 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
139 createkey testing with a SD
141 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
142 struct torture_context *tctx,
143 struct policy_handle *handle, const char *name,
145 struct policy_handle *newhandle)
147 struct winreg_CreateKey r;
148 enum winreg_CreateAction action_taken = 0;
149 struct security_descriptor *sd;
151 struct winreg_SecBuf secbuf;
153 sd = security_descriptor_dacl_create(tctx,
156 SID_NT_AUTHENTICATED_USERS,
157 SEC_ACE_TYPE_ACCESS_ALLOWED,
159 SEC_ACE_FLAG_OBJECT_INHERIT |
160 SEC_ACE_FLAG_CONTAINER_INHERIT,
163 torture_assert_ndr_success(tctx,
164 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
165 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
166 "Failed to push security_descriptor ?!\n");
168 secbuf.sd.data = sdblob.data;
169 secbuf.sd.len = sdblob.length;
170 secbuf.sd.size = sdblob.length;
171 secbuf.length = sdblob.length-10;
175 r.in.handle = handle;
176 r.out.new_handle = newhandle;
177 init_winreg_String(&r.in.name, name);
178 init_winreg_String(&r.in.keyclass, kclass);
180 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
181 r.in.action_taken = r.out.action_taken = &action_taken;
182 r.in.secdesc = &secbuf;
184 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
185 "CreateKey with sd failed");
187 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
192 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
193 struct torture_context *tctx,
194 struct policy_handle *handle,
195 uint32_t *sec_info_ptr,
197 struct security_descriptor **sd_out)
199 struct winreg_GetKeySecurity r;
200 struct security_descriptor *sd = NULL;
205 sec_info = *sec_info_ptr;
207 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
212 r.in.handle = handle;
213 r.in.sec_info = sec_info;
214 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
215 r.in.sd->size = 0x1000;
217 torture_assert_ntstatus_ok(tctx,
218 dcerpc_winreg_GetKeySecurity(p, tctx, &r),
219 "GetKeySecurity failed");
221 torture_assert_werr_equal(tctx, r.out.result, get_werr,
222 "GetKeySecurity failed");
224 sdblob.data = r.out.sd->data;
225 sdblob.length = r.out.sd->len;
227 sd = talloc_zero(tctx, struct security_descriptor);
229 torture_assert_ndr_success(tctx,
230 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
231 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
232 "pull_security_descriptor failed");
234 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
235 NDR_PRINT_DEBUG(security_descriptor, sd);
247 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
248 struct torture_context *tctx,
249 struct policy_handle *handle,
250 struct security_descriptor **sd_out)
252 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
255 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
256 struct torture_context *tctx,
257 struct policy_handle *handle,
258 uint32_t *sec_info_ptr,
259 struct security_descriptor *sd,
262 struct winreg_SetKeySecurity r;
263 struct KeySecurityData *sdata = NULL;
269 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
270 NDR_PRINT_DEBUG(security_descriptor, sd);
273 torture_assert_ndr_success(tctx,
274 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
275 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
276 "push_security_descriptor failed");
278 sdata = talloc_zero(tctx, struct KeySecurityData);
279 sdata->data = sdblob.data;
280 sdata->size = sdblob.length;
281 sdata->len = sdblob.length;
284 sec_info = *sec_info_ptr;
286 sec_info = SECINFO_UNPROTECTED_SACL |
287 SECINFO_UNPROTECTED_DACL;
289 sec_info |= SECINFO_OWNER;
292 sec_info |= SECINFO_GROUP;
295 sec_info |= SECINFO_SACL;
298 sec_info |= SECINFO_DACL;
302 r.in.handle = handle;
303 r.in.sec_info = sec_info;
306 torture_assert_ntstatus_ok(tctx,
307 dcerpc_winreg_SetKeySecurity(p, tctx, &r),
308 "SetKeySecurity failed");
310 torture_assert_werr_equal(tctx, r.out.result, werr,
311 "SetKeySecurity failed");
316 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
317 struct torture_context *tctx,
318 struct policy_handle *handle,
319 struct security_descriptor *sd)
321 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
324 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
325 struct policy_handle *handle)
327 struct winreg_CloseKey r;
330 r.in.handle = r.out.handle = handle;
332 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
335 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
340 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
341 struct policy_handle *handle)
343 struct winreg_FlushKey r;
346 r.in.handle = handle;
348 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
351 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
356 static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
357 struct policy_handle *hive_handle,
358 const char *keyname, uint32_t access_mask,
359 struct policy_handle *key_handle,
363 struct winreg_OpenKey r;
366 r.in.parent_handle = hive_handle;
367 init_winreg_String(&r.in.keyname, keyname);
368 r.in.options = REG_KEYTYPE_NON_VOLATILE;
369 r.in.access_mask = access_mask;
370 r.out.handle = key_handle;
372 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
375 torture_assert_werr_equal(tctx, r.out.result, open_werr,
378 if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
385 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
386 struct policy_handle *hive_handle,
387 const char *keyname, struct policy_handle *key_handle)
389 return _test_OpenKey(p, tctx, hive_handle, keyname,
390 SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
394 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
395 struct policy_handle *handle, const char *key)
397 struct winreg_DeleteKey r;
400 r.in.handle = handle;
402 init_winreg_String(&r.in.key, key);
403 dcerpc_winreg_DeleteKey(p, tctx, &r);
408 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
409 struct torture_context *tctx,
410 struct policy_handle *handle,
414 struct security_descriptor *sd = NULL;
416 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
420 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
427 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
428 struct torture_context *tctx,
429 struct policy_handle *handle,
432 struct policy_handle new_handle;
435 torture_comment(tctx, "SecurityDescriptor get & set\n");
437 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
441 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
446 if (!test_CloseKey(p, tctx, &new_handle)) {
453 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
454 struct torture_context *tctx,
455 struct policy_handle *handle,
456 uint32_t access_mask,
462 struct policy_handle new_handle;
464 bool got_key = false;
466 if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
467 open_werr, &got_key)) {
475 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
476 get_werr, set_werr)) {
480 if (!test_CloseKey(p, tctx, &new_handle)) {
487 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
488 struct torture_context *tctx,
489 struct policy_handle *handle,
490 const struct dom_sid *sid)
492 struct security_descriptor *sd = NULL;
495 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
499 if (!sd || !sd->dacl) {
503 for (i = 0; i < sd->dacl->num_aces; i++) {
504 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
512 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
513 struct torture_context *tctx,
514 struct policy_handle *handle,
516 const struct dom_sid *sid)
518 struct policy_handle new_handle;
521 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
525 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
527 test_CloseKey(p, tctx, &new_handle);
532 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
533 struct torture_context *tctx,
534 struct policy_handle *handle,
535 const struct dom_sid *sid)
537 struct security_descriptor *sd = NULL;
539 uint32_t sec_info = SECINFO_SACL;
541 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
545 if (!sd || !sd->sacl) {
549 for (i = 0; i < sd->sacl->num_aces; i++) {
550 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
558 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
559 struct torture_context *tctx,
560 struct policy_handle *handle,
562 const struct dom_sid *sid)
564 struct policy_handle new_handle;
567 if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
568 &new_handle, WERR_OK, NULL)) {
572 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
574 test_CloseKey(p, tctx, &new_handle);
579 static bool test_owner_present(struct dcerpc_pipe *p,
580 struct torture_context *tctx,
581 struct policy_handle *handle,
582 const struct dom_sid *sid)
584 struct security_descriptor *sd = NULL;
585 uint32_t sec_info = SECINFO_OWNER;
587 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
591 if (!sd || !sd->owner_sid) {
595 return dom_sid_equal(sd->owner_sid, sid);
598 static bool _test_owner_present(struct dcerpc_pipe *p,
599 struct torture_context *tctx,
600 struct policy_handle *handle,
602 const struct dom_sid *sid)
604 struct policy_handle new_handle;
607 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
611 ret = test_owner_present(p, tctx, &new_handle, sid);
613 test_CloseKey(p, tctx, &new_handle);
618 static bool test_group_present(struct dcerpc_pipe *p,
619 struct torture_context *tctx,
620 struct policy_handle *handle,
621 const struct dom_sid *sid)
623 struct security_descriptor *sd = NULL;
624 uint32_t sec_info = SECINFO_GROUP;
626 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
630 if (!sd || !sd->group_sid) {
634 return dom_sid_equal(sd->group_sid, sid);
637 static bool _test_group_present(struct dcerpc_pipe *p,
638 struct torture_context *tctx,
639 struct policy_handle *handle,
641 const struct dom_sid *sid)
643 struct policy_handle new_handle;
646 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
650 ret = test_group_present(p, tctx, &new_handle, sid);
652 test_CloseKey(p, tctx, &new_handle);
657 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
658 struct torture_context *tctx,
659 struct policy_handle *handle,
660 const struct dom_sid *sid,
663 struct security_descriptor *sd = NULL;
666 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
670 if (!sd || !sd->dacl) {
674 for (i = 0; i < sd->dacl->num_aces; i++) {
675 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
676 (sd->dacl->aces[i].flags == flags)) {
684 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
685 struct torture_context *tctx,
686 struct policy_handle *handle,
687 const struct security_ace *ace)
689 struct security_descriptor *sd = NULL;
692 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
696 if (!sd || !sd->dacl) {
700 for (i = 0; i < sd->dacl->num_aces; i++) {
701 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
709 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
710 struct torture_context *tctx,
711 struct policy_handle *handle,
713 struct security_descriptor *sd)
715 struct policy_handle new_handle;
718 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
722 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
726 if (!test_CloseKey(p, tctx, &new_handle)) {
733 static bool test_BackupSecurity(struct dcerpc_pipe *p,
734 struct torture_context *tctx,
735 struct policy_handle *handle,
737 struct security_descriptor **sd)
739 struct policy_handle new_handle;
742 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
746 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
750 if (!test_CloseKey(p, tctx, &new_handle)) {
757 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
758 struct torture_context *tctx,
759 struct policy_handle *handle,
763 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
778 struct security_descriptor *sd = NULL;
779 struct security_descriptor *sd_orig = NULL;
780 struct security_ace *ace = NULL;
781 struct policy_handle new_handle;
784 torture_comment(tctx, "SecurityDescriptor inheritance\n");
786 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
790 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
794 sd_orig = security_descriptor_copy(tctx, sd);
795 if (sd_orig == NULL) {
799 ace = security_ace_create(tctx,
801 SEC_ACE_TYPE_ACCESS_ALLOWED,
803 SEC_ACE_FLAG_CONTAINER_INHERIT);
805 torture_assert_ntstatus_ok(tctx,
806 security_descriptor_dacl_add(sd, ace),
807 "failed to add ace");
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)) {
818 test_dacl_ace_present(p, tctx, &new_handle, ace),
819 "new ACE not present!");
821 if (!test_CloseKey(p, tctx, &new_handle)) {
825 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
830 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
835 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
836 torture_comment(tctx, "inherited ACE not present!\n");
841 test_CloseKey(p, tctx, &new_handle);
842 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
847 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
852 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
853 torture_comment(tctx, "inherited ACE not present!\n");
859 test_CloseKey(p, tctx, &new_handle);
860 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
861 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
866 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
867 struct torture_context *tctx,
868 struct policy_handle *handle,
872 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
884 struct security_descriptor *sd = NULL;
885 struct security_descriptor *sd_orig = NULL;
886 struct security_ace *ace = NULL;
887 struct policy_handle new_handle;
888 struct dom_sid *sid = NULL;
890 uint8_t ace_flags = 0x0;
892 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
894 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
898 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
902 sd_orig = security_descriptor_copy(tctx, sd);
903 if (sd_orig == NULL) {
907 ace = security_ace_create(tctx,
909 SEC_ACE_TYPE_ACCESS_ALLOWED,
911 SEC_ACE_FLAG_CONTAINER_INHERIT |
912 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
914 torture_assert_ntstatus_ok(tctx,
915 security_descriptor_dacl_add(sd, ace),
916 "failed to add ace");
918 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
923 test_dacl_ace_present(p, tctx, &new_handle, ace),
924 "new ACE not present!");
926 if (!test_CloseKey(p, tctx, &new_handle)) {
930 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
934 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
939 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
940 torture_comment(tctx, "inherited ACE present but should not!\n");
945 sid = dom_sid_parse_talloc(tctx, TEST_SID);
950 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
951 torture_comment(tctx, "inherited trustee SID present but should not!\n");
956 test_CloseKey(p, tctx, &new_handle);
958 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
963 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
964 torture_comment(tctx, "inherited ACE present but should not!\n");
969 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
970 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
977 test_CloseKey(p, tctx, &new_handle);
978 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
979 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
984 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
985 struct torture_context *tctx,
986 struct policy_handle *handle,
992 struct winreg_mask_result_table {
993 uint32_t access_mask;
997 } sd_mask_tests[] = {
999 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1000 { SEC_FLAG_MAXIMUM_ALLOWED,
1001 WERR_OK, WERR_OK, WERR_OK },
1002 { SEC_STD_WRITE_DAC,
1003 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1004 { SEC_FLAG_SYSTEM_SECURITY,
1005 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1008 /* FIXME: before this test can ever run successfully we need a way to
1009 * correctly read a NULL security_descritpor in ndr, get the required
1010 * length, requery, etc.
1015 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1017 torture_comment(tctx,
1018 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1019 sd_mask_tests[i].access_mask);
1020 torture_comment(tctx,
1021 "expecting: open %s, get: %s, set: %s\n",
1022 win_errstr(sd_mask_tests[i].open_werr),
1023 win_errstr(sd_mask_tests[i].get_werr),
1024 win_errstr(sd_mask_tests[i].set_werr));
1026 if (_test_SecurityDescriptor(p, tctx, handle,
1027 sd_mask_tests[i].access_mask, key,
1028 sd_mask_tests[i].open_werr,
1029 sd_mask_tests[i].get_werr,
1030 sd_mask_tests[i].set_werr)) {
1038 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1039 struct torture_context *,
1040 struct policy_handle *,
1042 const struct dom_sid *);
1044 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1045 struct torture_context *tctx,
1046 struct policy_handle *handle,
1049 uint32_t access_mask,
1051 struct security_descriptor *sd,
1053 bool expect_present,
1054 bool (*fn) (struct dcerpc_pipe *,
1055 struct torture_context *,
1056 struct policy_handle *,
1058 const struct dom_sid *),
1059 const struct dom_sid *sid)
1061 struct policy_handle new_handle;
1062 bool open_success = false;
1064 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1065 "0x%08x, access_mask: 0x%08x\n",
1066 test, sec_info, access_mask);
1068 if (!_test_OpenKey(p, tctx, handle, key,
1076 if (!open_success) {
1077 torture_comment(tctx, "key did not open\n");
1078 test_CloseKey(p, tctx, &new_handle);
1082 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1085 torture_warning(tctx,
1086 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1089 test_CloseKey(p, tctx, &new_handle);
1093 test_CloseKey(p, tctx, &new_handle);
1095 if (W_ERROR_IS_OK(set_werr)) {
1097 present = fn(p, tctx, handle, key, sid);
1098 if ((expect_present) && (!present)) {
1099 torture_warning(tctx,
1100 "%s sid is not present!\n",
1104 if ((!expect_present) && (present)) {
1105 torture_warning(tctx,
1106 "%s sid is present but not expected!\n",
1115 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1116 struct torture_context *tctx,
1117 struct policy_handle *handle,
1120 struct security_descriptor *sd_orig = NULL;
1121 struct dom_sid *sid = NULL;
1125 struct security_descriptor *sd_owner =
1126 security_descriptor_dacl_create(tctx,
1128 TEST_SID, NULL, NULL);
1130 struct security_descriptor *sd_group =
1131 security_descriptor_dacl_create(tctx,
1133 NULL, TEST_SID, NULL);
1135 struct security_descriptor *sd_dacl =
1136 security_descriptor_dacl_create(tctx,
1140 SEC_ACE_TYPE_ACCESS_ALLOWED,
1143 SID_NT_AUTHENTICATED_USERS,
1144 SEC_ACE_TYPE_ACCESS_ALLOWED,
1149 struct security_descriptor *sd_sacl =
1150 security_descriptor_sacl_create(tctx,
1154 SEC_ACE_TYPE_SYSTEM_AUDIT,
1156 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1159 struct winreg_secinfo_table {
1160 struct security_descriptor *sd;
1164 secinfo_verify_fn fn;
1167 struct winreg_secinfo_table sec_info_owner_tests[] = {
1168 { sd_owner, 0, WERR_OK,
1169 false, (secinfo_verify_fn)_test_owner_present },
1170 { sd_owner, SECINFO_OWNER, WERR_OK,
1171 true, (secinfo_verify_fn)_test_owner_present },
1172 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1173 { sd_owner, SECINFO_DACL, WERR_OK,
1174 true, (secinfo_verify_fn)_test_owner_present },
1175 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1178 uint32_t sd_owner_good_access_masks[] = {
1179 SEC_FLAG_MAXIMUM_ALLOWED,
1180 /* SEC_STD_WRITE_OWNER, */
1183 struct winreg_secinfo_table sec_info_group_tests[] = {
1184 { sd_group, 0, WERR_OK,
1185 false, (secinfo_verify_fn)_test_group_present },
1186 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1187 { sd_group, SECINFO_GROUP, WERR_OK,
1188 true, (secinfo_verify_fn)_test_group_present },
1189 { sd_group, SECINFO_DACL, WERR_OK,
1190 true, (secinfo_verify_fn)_test_group_present },
1191 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1194 uint32_t sd_group_good_access_masks[] = {
1195 SEC_FLAG_MAXIMUM_ALLOWED,
1198 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1199 { sd_dacl, 0, WERR_OK,
1200 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1201 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1202 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1203 { sd_dacl, SECINFO_DACL, WERR_OK,
1204 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1205 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1208 uint32_t sd_dacl_good_access_masks[] = {
1209 SEC_FLAG_MAXIMUM_ALLOWED,
1213 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1214 { sd_sacl, 0, WERR_OK,
1215 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1216 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1217 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1218 { sd_sacl, SECINFO_DACL, WERR_OK,
1219 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1220 { sd_sacl, SECINFO_SACL, WERR_OK,
1221 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1224 uint32_t sd_sacl_good_access_masks[] = {
1225 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1226 /* SEC_FLAG_SYSTEM_SECURITY, */
1229 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1234 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1240 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1242 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1244 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1247 sd_owner_good_access_masks[a],
1248 sec_info_owner_tests[i].sec_info,
1249 sec_info_owner_tests[i].sd,
1250 sec_info_owner_tests[i].set_werr,
1251 sec_info_owner_tests[i].sid_present,
1252 sec_info_owner_tests[i].fn,
1255 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1264 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1266 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1268 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1271 sd_group_good_access_masks[a],
1272 sec_info_group_tests[i].sec_info,
1273 sec_info_group_tests[i].sd,
1274 sec_info_group_tests[i].set_werr,
1275 sec_info_group_tests[i].sid_present,
1276 sec_info_group_tests[i].fn,
1279 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1288 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1290 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1292 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1295 sd_dacl_good_access_masks[a],
1296 sec_info_dacl_tests[i].sec_info,
1297 sec_info_dacl_tests[i].sd,
1298 sec_info_dacl_tests[i].set_werr,
1299 sec_info_dacl_tests[i].sid_present,
1300 sec_info_dacl_tests[i].fn,
1303 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1312 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1314 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1316 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1319 sd_sacl_good_access_masks[a],
1320 sec_info_sacl_tests[i].sec_info,
1321 sec_info_sacl_tests[i].sd,
1322 sec_info_sacl_tests[i].set_werr,
1323 sec_info_sacl_tests[i].sid_present,
1324 sec_info_sacl_tests[i].fn,
1327 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1335 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1340 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1341 struct torture_context *tctx,
1342 struct policy_handle *handle,
1347 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1348 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1352 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1353 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1357 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1358 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1362 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1363 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1367 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1368 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1375 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1376 struct policy_handle *handle, const char *key)
1379 struct winreg_DeleteKey r;
1381 r.in.handle = handle;
1382 init_winreg_String(&r.in.key, key);
1384 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1386 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1387 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1392 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1393 struct torture_context *tctx,
1394 struct policy_handle *handle, char *kclass)
1396 struct winreg_QueryInfoKey r;
1397 uint32_t num_subkeys, max_subkeylen, max_classlen,
1398 num_values, max_valnamelen, max_valbufsize,
1400 NTTIME last_changed_time;
1403 r.in.handle = handle;
1404 r.out.num_subkeys = &num_subkeys;
1405 r.out.max_subkeylen = &max_subkeylen;
1406 r.out.max_classlen = &max_classlen;
1407 r.out.num_values = &num_values;
1408 r.out.max_valnamelen = &max_valnamelen;
1409 r.out.max_valbufsize = &max_valbufsize;
1410 r.out.secdescsize = &secdescsize;
1411 r.out.last_changed_time = &last_changed_time;
1413 r.out.classname = talloc(tctx, struct winreg_String);
1415 r.in.classname = talloc(tctx, struct winreg_String);
1416 init_winreg_String(r.in.classname, kclass);
1418 torture_assert_ntstatus_ok(tctx,
1419 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1420 "QueryInfoKey failed");
1422 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1427 static bool test_SetValue(struct dcerpc_pipe *p,
1428 struct torture_context *tctx,
1429 struct policy_handle *handle,
1430 const char *value_name,
1431 enum winreg_Type type,
1435 struct winreg_SetValue r;
1436 struct winreg_String name;
1438 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1439 value_name, str_regtype(type), size);
1441 init_winreg_String(&name, value_name);
1443 r.in.handle = handle;
1449 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue(p, tctx, &r),
1450 "winreg_SetValue failed");
1451 torture_assert_werr_ok(tctx, r.out.result,
1452 "winreg_SetValue failed");
1457 static bool test_DeleteValue(struct dcerpc_pipe *p,
1458 struct torture_context *tctx,
1459 struct policy_handle *handle,
1460 const char *value_name)
1462 struct winreg_DeleteValue r;
1463 struct winreg_String value;
1465 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1467 init_winreg_String(&value, value_name);
1469 r.in.handle = handle;
1472 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue(p, tctx, &r),
1473 "winreg_DeleteValue failed");
1474 torture_assert_werr_ok(tctx, r.out.result,
1475 "winreg_DeleteValue failed");
1480 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1481 struct policy_handle *handle, int depth,
1482 bool test_security);
1484 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1485 struct policy_handle *handle, int depth,
1488 struct winreg_EnumKey r;
1489 struct winreg_StringBuf kclass, name;
1497 r.in.handle = handle;
1498 r.in.enum_index = 0;
1500 r.in.keyclass = &kclass;
1502 r.in.last_changed_time = &t;
1508 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1510 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1511 struct policy_handle key_handle;
1513 torture_comment(tctx, "EnumKey: %d: %s\n",
1517 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1520 test_key(p, tctx, &key_handle,
1521 depth + 1, test_security);
1527 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1529 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1531 if (!W_ERROR_IS_OK(r.out.result) &&
1532 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1533 torture_fail(tctx, "EnumKey failed");
1539 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1540 struct torture_context *tctx,
1541 struct policy_handle *handle,
1542 const char *valuename)
1544 struct winreg_QueryMultipleValues r;
1549 r.in.key_handle = handle;
1550 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1551 r.in.values[0].name = talloc(tctx, struct winreg_String);
1552 r.in.values[0].name->name = valuename;
1553 r.in.values[0].offset = 0;
1554 r.in.values[0].length = 0;
1555 r.in.values[0].type = 0;
1557 r.in.num_values = 1;
1558 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1559 *r.in.buffer_size = bufsize;
1561 *r.in.buffer_size = bufsize;
1562 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1565 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1567 if(NT_STATUS_IS_ERR(status))
1568 torture_fail(tctx, "QueryMultipleValues failed");
1570 talloc_free(r.in.buffer);
1572 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1574 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1579 static bool test_QueryValue(struct dcerpc_pipe *p,
1580 struct torture_context *tctx,
1581 struct policy_handle *handle,
1582 const char *valuename)
1584 struct winreg_QueryValue r;
1586 enum winreg_Type zero_type = 0;
1587 uint32_t offered = 0xfff;
1591 r.in.handle = handle;
1593 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1594 r.in.value_name->name = valuename;
1595 r.in.type = &zero_type;
1596 r.in.data_size = &offered;
1597 r.in.data_length = &zero;
1599 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1600 if (NT_STATUS_IS_ERR(status)) {
1601 torture_fail(tctx, "QueryValue failed");
1604 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1609 static bool test_QueryValue_full(struct dcerpc_pipe *p,
1610 struct torture_context *tctx,
1611 struct policy_handle *handle,
1612 const char *valuename,
1613 bool existing_value)
1615 struct winreg_QueryValue r;
1616 struct winreg_String value_name;
1617 enum winreg_Type type = REG_NONE;
1618 uint32_t data_size = 0;
1619 uint32_t real_data_size = 0;
1620 uint32_t data_length = 0;
1621 uint8_t *data = NULL;
1622 WERROR expected_error = WERR_BADFILE;
1624 if (valuename == NULL) {
1625 expected_error = WERR_INVALID_PARAM;
1630 init_winreg_String(&value_name, NULL);
1632 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1634 r.in.handle = handle;
1635 r.in.value_name = &value_name;
1637 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r), "QueryValue failed");
1638 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1639 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1641 init_winreg_String(&value_name, valuename);
1642 r.in.value_name = &value_name;
1644 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1645 "QueryValue failed");
1646 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1647 "QueryValue failed");
1651 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1652 "QueryValue failed");
1653 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1654 "QueryValue failed");
1656 r.in.data_length = &data_length;
1657 r.out.data_length = &data_length;
1658 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1659 "QueryValue failed");
1660 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1661 "QueryValue failed");
1663 r.in.data_size = &data_size;
1664 r.out.data_size = &data_size;
1665 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1666 "QueryValue failed");
1667 if (existing_value) {
1668 torture_assert_werr_ok(tctx, r.out.result,
1669 "QueryValue failed");
1671 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1672 "QueryValue failed");
1675 real_data_size = *r.out.data_size;
1677 data = talloc_zero_array(tctx, uint8_t, 0);
1680 *r.in.data_size = 0;
1681 *r.out.data_size = 0;
1682 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1683 "QueryValue failed");
1684 if (existing_value) {
1685 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1686 "QueryValue failed");
1688 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1689 "QueryValue failed");
1692 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1695 r.in.data_size = &real_data_size;
1696 r.out.data_size = &real_data_size;
1697 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1698 "QueryValue failed");
1699 if (existing_value) {
1700 torture_assert_werr_ok(tctx, r.out.result,
1701 "QueryValue failed");
1703 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1704 "QueryValue failed");
1710 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1711 struct policy_handle *handle, int max_valnamelen,
1714 struct winreg_EnumValue r;
1715 enum winreg_Type type = 0;
1716 uint32_t size = max_valbufsize, zero = 0;
1719 struct winreg_ValNameBuf name;
1725 r.in.handle = handle;
1726 r.in.enum_index = 0;
1731 r.in.length = &zero;
1735 torture_assert_ntstatus_ok(tctx,
1736 dcerpc_winreg_EnumValue(p, tctx, &r),
1737 "EnumValue failed");
1739 if (W_ERROR_IS_OK(r.out.result)) {
1740 ret &= test_QueryValue(p, tctx, handle,
1742 ret &= test_QueryMultipleValues(p, tctx, handle,
1747 } while (W_ERROR_IS_OK(r.out.result));
1749 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1750 "EnumValue failed");
1755 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1756 struct torture_context *tctx)
1758 struct winreg_AbortSystemShutdown r;
1759 uint16_t server = 0x0;
1762 r.in.server = &server;
1764 torture_assert_ntstatus_ok(tctx,
1765 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1766 "AbortSystemShutdown failed");
1768 torture_assert_werr_ok(tctx, r.out.result,
1769 "AbortSystemShutdown failed");
1774 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1775 struct dcerpc_pipe *p)
1777 struct winreg_InitiateSystemShutdown r;
1778 uint16_t hostname = 0x0;
1781 r.in.hostname = &hostname;
1782 r.in.message = talloc(tctx, struct lsa_StringLarge);
1783 init_lsa_StringLarge(r.in.message, "spottyfood");
1784 r.in.force_apps = 1;
1788 torture_assert_ntstatus_ok(tctx,
1789 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1790 "InitiateSystemShutdown failed");
1792 torture_assert_werr_ok(tctx, r.out.result,
1793 "InitiateSystemShutdown failed");
1795 return test_AbortSystemShutdown(p, tctx);
1799 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1800 struct dcerpc_pipe *p)
1802 struct winreg_InitiateSystemShutdownEx r;
1803 uint16_t hostname = 0x0;
1806 r.in.hostname = &hostname;
1807 r.in.message = talloc(tctx, struct lsa_StringLarge);
1808 init_lsa_StringLarge(r.in.message, "spottyfood");
1809 r.in.force_apps = 1;
1814 torture_assert_ntstatus_ok(tctx,
1815 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1816 "InitiateSystemShutdownEx failed");
1818 torture_assert_werr_ok(tctx, r.out.result,
1819 "InitiateSystemShutdownEx failed");
1821 return test_AbortSystemShutdown(p, tctx);
1823 #define MAX_DEPTH 2 /* Only go this far down the tree */
1825 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1826 struct policy_handle *handle, int depth,
1829 if (depth == MAX_DEPTH)
1832 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1835 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1838 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1841 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1844 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1847 test_CloseKey(p, tctx, handle);
1852 static bool test_SetValue_simple(struct dcerpc_pipe *p,
1853 struct torture_context *tctx,
1854 struct policy_handle *handle)
1856 const char *value_name = TEST_VALUE;
1857 uint32_t value = 0x12345678;
1858 const char *string = "torture";
1860 enum winreg_Type types[] = {
1868 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1870 for (t=0; t < ARRAY_SIZE(types); t++) {
1872 enum winreg_Type w_type;
1873 uint32_t w_size, w_length;
1878 blob = data_blob_talloc_zero(tctx, 4);
1879 SIVAL(blob.data, 0, value);
1882 blob = data_blob_string_const("binary_blob");
1885 torture_assert(tctx,
1886 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1890 (void **)&blob.data,
1895 torture_assert(tctx,
1896 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1900 (void **)&blob.data,
1903 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1904 memset(&blob.data[blob.length - 2], '\0', 2);
1910 torture_assert(tctx,
1911 test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
1912 "test_SetValue failed");
1913 torture_assert(tctx,
1914 test_QueryValue_full(p, tctx, handle, value_name, true),
1915 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1916 torture_assert(tctx,
1917 test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1918 "test_winreg_QueryValue failed");
1919 torture_assert(tctx,
1920 test_DeleteValue(p, tctx, handle, value_name),
1921 "test_DeleteValue failed");
1923 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1924 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1925 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1926 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1929 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
1934 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1936 static bool test_Open_Security(struct torture_context *tctx,
1937 struct dcerpc_pipe *p, void *userdata)
1939 struct policy_handle handle, newhandle;
1940 bool ret = true, created2 = false;
1941 bool created4 = false;
1942 struct winreg_OpenHKLM r;
1944 winreg_open_fn open_fn = userdata;
1947 r.in.system_name = 0;
1948 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1949 r.out.handle = &handle;
1951 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1954 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1956 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1957 torture_comment(tctx,
1958 "CreateKey (TEST_KEY_BASE) failed\n");
1961 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1962 NULL, &newhandle)) {
1966 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1967 torture_comment(tctx, "CloseKey failed\n");
1971 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1975 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1976 torture_comment(tctx, "CloseKey failed\n");
1980 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1984 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1985 torture_comment(tctx, "DeleteKey failed\n");
1989 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1990 torture_comment(tctx, "DeleteKey failed\n");
1994 /* The HKCR hive has a very large fanout */
1995 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1996 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
2000 if (!test_key(p, tctx, &handle, 0, true)) {
2005 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2010 static bool test_SetValue_extended(struct dcerpc_pipe *p,
2011 struct torture_context *tctx,
2012 struct policy_handle *handle)
2014 const char *value_name = TEST_VALUE;
2015 enum winreg_Type types[] = {
2021 REG_DWORD_BIG_ENDIAN,
2025 REG_FULL_RESOURCE_DESCRIPTOR,
2026 REG_RESOURCE_REQUIREMENTS_LIST,
2038 if (torture_setting_bool(tctx, "samba3", false)) {
2039 torture_skip(tctx, "skipping extended SetValue test against Samba 3");
2042 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2044 for (t=0; t < ARRAY_SIZE(types); t++) {
2045 for (l=0; l < 32; l++) {
2047 enum winreg_Type w_type;
2048 uint32_t w_size, w_length;
2051 const char *string = generate_random_str(tctx, l);
2052 DATA_BLOB blob = data_blob_string_const(string);
2054 torture_assert(tctx,
2055 test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
2056 "test_SetValue failed");
2058 torture_assert(tctx,
2059 test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2060 "test_winreg_QueryValue failed");
2062 torture_assert(tctx,
2063 test_DeleteValue(p, tctx, handle, value_name),
2064 "test_DeleteValue failed");
2066 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2067 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2068 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2069 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2073 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2078 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2079 #define VALUE_CURRENT_VERSION "CurrentVersion"
2081 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2084 struct policy_handle handle, newhandle;
2085 bool ret = true, created = false, deleted = false;
2086 bool created3 = false, created_subkey = false;
2087 struct winreg_OpenHKLM r;
2089 winreg_open_fn open_fn = userdata;
2092 r.in.system_name = 0;
2093 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2094 r.out.handle = &handle;
2096 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
2099 if (open_fn == (void *)dcerpc_winreg_OpenHKLM) {
2101 torture_assert(tctx, test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, &newhandle),
2102 "failed to open current version key");
2104 torture_assert(tctx, _test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, KEY_QUERY_VALUE, &newhandle, WERR_OK, NULL),
2105 "failed to open current version key");
2107 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2108 "failed to query current version");
2109 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "IDoNotExist", false),
2110 "failed to query current version");
2111 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, NULL, false),
2112 "test_QueryValue_full for NULL value failed");
2113 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "", false),
2114 "test_QueryValue_full for \"\" value failed");
2116 torture_assert(tctx, test_CloseKey(p, tctx, &newhandle),
2117 "failed to close current version key");
2120 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2122 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
2123 torture_comment(tctx,
2124 "CreateKey (TEST_KEY_BASE) failed\n");
2127 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
2128 torture_comment(tctx,
2129 "CreateKey failed - not considering a failure\n");
2134 if (created && !test_FlushKey(p, tctx, &handle)) {
2135 torture_comment(tctx, "FlushKey failed\n");
2139 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
2141 "CreateKey failed (OpenKey after Create didn't work)\n");
2144 torture_assert(tctx, test_SetValue_simple(p, tctx, &newhandle),
2145 "simple SetValue test failed");
2146 if (!test_SetValue_extended(p, tctx, &newhandle)) {
2147 if (torture_setting_bool(tctx, "samba3", false)) {
2148 torture_warning(tctx, "extended SetValue test failed");
2150 torture_fail(tctx, "extended SetValue test failed");
2155 if (created && !test_CloseKey(p, tctx, &newhandle))
2157 "CreateKey failed (CloseKey after Open didn't work)\n");
2159 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
2160 torture_comment(tctx, "DeleteKey failed\n");
2166 if (created && !test_FlushKey(p, tctx, &handle)) {
2167 torture_comment(tctx, "FlushKey failed\n");
2171 if (created && deleted &&
2172 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
2173 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
2174 WERR_BADFILE, NULL)) {
2175 torture_comment(tctx,
2176 "DeleteKey failed (OpenKey after Delete "
2177 "did not return WERR_BADFILE)\n");
2181 if (!test_GetVersion(p, tctx, &handle)) {
2182 torture_comment(tctx, "GetVersion failed\n");
2186 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
2191 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
2192 created_subkey = true;
2195 if (created_subkey &&
2196 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
2197 torture_comment(tctx, "DeleteKey failed\n");
2201 /* The HKCR hive has a very large fanout */
2202 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2203 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2207 if (!test_key(p, tctx, &handle, 0, false)) {
2212 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2217 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2219 struct torture_rpc_tcase *tcase;
2220 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2221 struct torture_test *test;
2223 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2226 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2227 test_InitiateSystemShutdown);
2228 test->dangerous = true;
2230 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2231 test_InitiateSystemShutdownEx);
2232 test->dangerous = true;
2234 /* Basic tests without security descriptors */
2235 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
2237 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2238 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
2240 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2241 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
2243 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2244 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
2246 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2248 /* Security descriptor tests */
2249 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
2251 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2252 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
2254 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2255 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
2257 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2258 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
2260 (winreg_open_fn)dcerpc_winreg_OpenHKCU);