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;
785 torture_comment(tctx, "SecurityDescriptor inheritance\n");
787 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
791 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
795 sd_orig = security_descriptor_copy(tctx, sd);
796 if (sd_orig == NULL) {
800 ace = security_ace_create(tctx,
802 SEC_ACE_TYPE_ACCESS_ALLOWED,
804 SEC_ACE_FLAG_CONTAINER_INHERIT);
806 status = security_descriptor_dacl_add(sd, ace);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("failed to add ace: %s\n", nt_errstr(status));
812 /* FIXME: add further tests for these flags */
813 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
814 SEC_DESC_SACL_AUTO_INHERITED;
816 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
820 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
821 printf("new ACE not present!\n");
825 if (!test_CloseKey(p, tctx, &new_handle)) {
829 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
834 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
839 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
840 printf("inherited ACE not present!\n");
845 test_CloseKey(p, tctx, &new_handle);
846 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
851 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
856 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
857 printf("inherited ACE not present!\n");
863 test_CloseKey(p, tctx, &new_handle);
864 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
865 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
870 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
871 struct torture_context *tctx,
872 struct policy_handle *handle,
876 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
888 struct security_descriptor *sd = NULL;
889 struct security_descriptor *sd_orig = NULL;
890 struct security_ace *ace = NULL;
891 struct policy_handle new_handle;
892 struct dom_sid *sid = NULL;
895 uint8_t ace_flags = 0x0;
897 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
899 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
903 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
907 sd_orig = security_descriptor_copy(tctx, sd);
908 if (sd_orig == NULL) {
912 ace = security_ace_create(tctx,
914 SEC_ACE_TYPE_ACCESS_ALLOWED,
916 SEC_ACE_FLAG_CONTAINER_INHERIT |
917 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
919 status = security_descriptor_dacl_add(sd, ace);
920 if (!NT_STATUS_IS_OK(status)) {
921 printf("failed to add ace: %s\n", nt_errstr(status));
925 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
929 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
930 printf("new ACE not present!\n");
934 if (!test_CloseKey(p, tctx, &new_handle)) {
938 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
942 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
947 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
948 printf("inherited ACE present but should not!\n");
953 sid = dom_sid_parse_talloc(tctx, TEST_SID);
958 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
959 printf("inherited trustee SID present but should not!\n");
964 test_CloseKey(p, tctx, &new_handle);
966 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
971 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
972 printf("inherited ACE present but should not!\n");
977 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
978 printf("inherited trustee SID with flags 0x%02x not present!\n",
985 test_CloseKey(p, tctx, &new_handle);
986 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
987 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
992 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
993 struct torture_context *tctx,
994 struct policy_handle *handle,
1000 struct winreg_mask_result_table {
1001 uint32_t access_mask;
1005 } sd_mask_tests[] = {
1007 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1008 { SEC_FLAG_MAXIMUM_ALLOWED,
1009 WERR_OK, WERR_OK, WERR_OK },
1010 { SEC_STD_WRITE_DAC,
1011 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1012 { SEC_FLAG_SYSTEM_SECURITY,
1013 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1016 /* FIXME: before this test can ever run successfully we need a way to
1017 * correctly read a NULL security_descritpor in ndr, get the required
1018 * length, requery, etc.
1023 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1025 torture_comment(tctx,
1026 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1027 sd_mask_tests[i].access_mask);
1028 torture_comment(tctx,
1029 "expecting: open %s, get: %s, set: %s\n",
1030 win_errstr(sd_mask_tests[i].open_werr),
1031 win_errstr(sd_mask_tests[i].get_werr),
1032 win_errstr(sd_mask_tests[i].set_werr));
1034 if (_test_SecurityDescriptor(p, tctx, handle,
1035 sd_mask_tests[i].access_mask, key,
1036 sd_mask_tests[i].open_werr,
1037 sd_mask_tests[i].get_werr,
1038 sd_mask_tests[i].set_werr)) {
1046 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1047 struct torture_context *,
1048 struct policy_handle *,
1050 const struct dom_sid *);
1052 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1053 struct torture_context *tctx,
1054 struct policy_handle *handle,
1057 uint32_t access_mask,
1059 struct security_descriptor *sd,
1061 bool expect_present,
1062 bool (*fn) (struct dcerpc_pipe *,
1063 struct torture_context *,
1064 struct policy_handle *,
1066 const struct dom_sid *),
1067 const struct dom_sid *sid)
1069 struct policy_handle new_handle;
1070 bool open_success = false;
1072 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1073 "0x%08x, access_mask: 0x%08x\n",
1074 test, sec_info, access_mask);
1076 if (!_test_OpenKey(p, tctx, handle, key,
1084 if (!open_success) {
1085 printf("key did not open\n");
1086 test_CloseKey(p, tctx, &new_handle);
1090 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1093 torture_warning(tctx,
1094 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1097 test_CloseKey(p, tctx, &new_handle);
1101 test_CloseKey(p, tctx, &new_handle);
1103 if (W_ERROR_IS_OK(set_werr)) {
1105 present = fn(p, tctx, handle, key, sid);
1106 if ((expect_present) && (!present)) {
1107 torture_warning(tctx,
1108 "%s sid is not present!\n",
1112 if ((!expect_present) && (present)) {
1113 torture_warning(tctx,
1114 "%s sid is present but not expected!\n",
1123 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1124 struct torture_context *tctx,
1125 struct policy_handle *handle,
1128 struct security_descriptor *sd_orig = NULL;
1129 struct dom_sid *sid = NULL;
1133 struct security_descriptor *sd_owner =
1134 security_descriptor_dacl_create(tctx,
1136 TEST_SID, NULL, NULL);
1138 struct security_descriptor *sd_group =
1139 security_descriptor_dacl_create(tctx,
1141 NULL, TEST_SID, NULL);
1143 struct security_descriptor *sd_dacl =
1144 security_descriptor_dacl_create(tctx,
1148 SEC_ACE_TYPE_ACCESS_ALLOWED,
1151 SID_NT_AUTHENTICATED_USERS,
1152 SEC_ACE_TYPE_ACCESS_ALLOWED,
1157 struct security_descriptor *sd_sacl =
1158 security_descriptor_sacl_create(tctx,
1162 SEC_ACE_TYPE_SYSTEM_AUDIT,
1164 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1167 struct winreg_secinfo_table {
1168 struct security_descriptor *sd;
1172 secinfo_verify_fn fn;
1175 struct winreg_secinfo_table sec_info_owner_tests[] = {
1176 { sd_owner, 0, WERR_OK,
1177 false, (secinfo_verify_fn)_test_owner_present },
1178 { sd_owner, SECINFO_OWNER, WERR_OK,
1179 true, (secinfo_verify_fn)_test_owner_present },
1180 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1181 { sd_owner, SECINFO_DACL, WERR_OK,
1182 true, (secinfo_verify_fn)_test_owner_present },
1183 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1186 uint32_t sd_owner_good_access_masks[] = {
1187 SEC_FLAG_MAXIMUM_ALLOWED,
1188 /* SEC_STD_WRITE_OWNER, */
1191 struct winreg_secinfo_table sec_info_group_tests[] = {
1192 { sd_group, 0, WERR_OK,
1193 false, (secinfo_verify_fn)_test_group_present },
1194 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1195 { sd_group, SECINFO_GROUP, WERR_OK,
1196 true, (secinfo_verify_fn)_test_group_present },
1197 { sd_group, SECINFO_DACL, WERR_OK,
1198 true, (secinfo_verify_fn)_test_group_present },
1199 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1202 uint32_t sd_group_good_access_masks[] = {
1203 SEC_FLAG_MAXIMUM_ALLOWED,
1206 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1207 { sd_dacl, 0, WERR_OK,
1208 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1209 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1210 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1211 { sd_dacl, SECINFO_DACL, WERR_OK,
1212 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1213 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1216 uint32_t sd_dacl_good_access_masks[] = {
1217 SEC_FLAG_MAXIMUM_ALLOWED,
1221 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1222 { sd_sacl, 0, WERR_OK,
1223 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1224 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1225 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1226 { sd_sacl, SECINFO_DACL, WERR_OK,
1227 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1228 { sd_sacl, SECINFO_SACL, WERR_OK,
1229 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1232 uint32_t sd_sacl_good_access_masks[] = {
1233 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1234 /* SEC_FLAG_SYSTEM_SECURITY, */
1237 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1242 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1248 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1250 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1252 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1255 sd_owner_good_access_masks[a],
1256 sec_info_owner_tests[i].sec_info,
1257 sec_info_owner_tests[i].sd,
1258 sec_info_owner_tests[i].set_werr,
1259 sec_info_owner_tests[i].sid_present,
1260 sec_info_owner_tests[i].fn,
1263 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1272 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1274 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1276 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1279 sd_group_good_access_masks[a],
1280 sec_info_group_tests[i].sec_info,
1281 sec_info_group_tests[i].sd,
1282 sec_info_group_tests[i].set_werr,
1283 sec_info_group_tests[i].sid_present,
1284 sec_info_group_tests[i].fn,
1287 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1296 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1298 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1300 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1303 sd_dacl_good_access_masks[a],
1304 sec_info_dacl_tests[i].sec_info,
1305 sec_info_dacl_tests[i].sd,
1306 sec_info_dacl_tests[i].set_werr,
1307 sec_info_dacl_tests[i].sid_present,
1308 sec_info_dacl_tests[i].fn,
1311 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1320 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1322 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1324 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1327 sd_sacl_good_access_masks[a],
1328 sec_info_sacl_tests[i].sec_info,
1329 sec_info_sacl_tests[i].sd,
1330 sec_info_sacl_tests[i].set_werr,
1331 sec_info_sacl_tests[i].sid_present,
1332 sec_info_sacl_tests[i].fn,
1335 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1343 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1348 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1349 struct torture_context *tctx,
1350 struct policy_handle *handle,
1355 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1356 printf("test_SecurityDescriptor failed\n");
1360 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1361 printf("test_SecurityDescriptorInheritance failed\n");
1365 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1366 printf("test_SecurityDescriptorBlockInheritance failed\n");
1370 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1371 printf("test_SecurityDescriptorsSecInfo failed\n");
1375 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1376 printf("test_SecurityDescriptorsMasks failed\n");
1383 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1384 struct policy_handle *handle, const char *key)
1387 struct winreg_DeleteKey r;
1389 r.in.handle = handle;
1390 init_winreg_String(&r.in.key, key);
1392 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1394 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1395 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1400 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1401 struct torture_context *tctx,
1402 struct policy_handle *handle, char *kclass)
1404 struct winreg_QueryInfoKey r;
1405 uint32_t num_subkeys, max_subkeylen, max_classlen,
1406 num_values, max_valnamelen, max_valbufsize,
1408 NTTIME last_changed_time;
1411 r.in.handle = handle;
1412 r.out.num_subkeys = &num_subkeys;
1413 r.out.max_subkeylen = &max_subkeylen;
1414 r.out.max_classlen = &max_classlen;
1415 r.out.num_values = &num_values;
1416 r.out.max_valnamelen = &max_valnamelen;
1417 r.out.max_valbufsize = &max_valbufsize;
1418 r.out.secdescsize = &secdescsize;
1419 r.out.last_changed_time = &last_changed_time;
1421 r.out.classname = talloc(tctx, struct winreg_String);
1423 r.in.classname = talloc(tctx, struct winreg_String);
1424 init_winreg_String(r.in.classname, kclass);
1426 torture_assert_ntstatus_ok(tctx,
1427 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1428 "QueryInfoKey failed");
1430 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1435 static bool test_SetValue(struct dcerpc_pipe *p,
1436 struct torture_context *tctx,
1437 struct policy_handle *handle,
1438 const char *value_name,
1439 enum winreg_Type type,
1443 struct winreg_SetValue r;
1444 struct winreg_String name;
1446 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1447 value_name, str_regtype(type), size);
1449 init_winreg_String(&name, value_name);
1451 r.in.handle = handle;
1457 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue(p, tctx, &r),
1458 "winreg_SetValue failed");
1459 torture_assert_werr_ok(tctx, r.out.result,
1460 "winreg_SetValue failed");
1465 static bool test_DeleteValue(struct dcerpc_pipe *p,
1466 struct torture_context *tctx,
1467 struct policy_handle *handle,
1468 const char *value_name)
1470 struct winreg_DeleteValue r;
1471 struct winreg_String value;
1473 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1475 init_winreg_String(&value, value_name);
1477 r.in.handle = handle;
1480 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue(p, tctx, &r),
1481 "winreg_DeleteValue failed");
1482 torture_assert_werr_ok(tctx, r.out.result,
1483 "winreg_DeleteValue failed");
1488 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1489 struct policy_handle *handle, int depth,
1490 bool test_security);
1492 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1493 struct policy_handle *handle, int depth,
1496 struct winreg_EnumKey r;
1497 struct winreg_StringBuf kclass, name;
1505 r.in.handle = handle;
1506 r.in.enum_index = 0;
1508 r.in.keyclass = &kclass;
1510 r.in.last_changed_time = &t;
1516 status = dcerpc_winreg_EnumKey(p, tctx, &r);
1518 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1519 struct policy_handle key_handle;
1521 torture_comment(tctx, "EnumKey: %d: %s\n",
1525 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1528 test_key(p, tctx, &key_handle,
1529 depth + 1, test_security);
1535 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1537 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1539 if (!W_ERROR_IS_OK(r.out.result) &&
1540 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1541 torture_fail(tctx, "EnumKey failed");
1547 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1548 struct torture_context *tctx,
1549 struct policy_handle *handle,
1550 const char *valuename)
1552 struct winreg_QueryMultipleValues r;
1557 r.in.key_handle = handle;
1558 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1559 r.in.values[0].name = talloc(tctx, struct winreg_String);
1560 r.in.values[0].name->name = valuename;
1561 r.in.values[0].offset = 0;
1562 r.in.values[0].length = 0;
1563 r.in.values[0].type = 0;
1565 r.in.num_values = 1;
1566 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1567 *r.in.buffer_size = bufsize;
1569 *r.in.buffer_size = bufsize;
1570 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1573 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1575 if(NT_STATUS_IS_ERR(status))
1576 torture_fail(tctx, "QueryMultipleValues failed");
1578 talloc_free(r.in.buffer);
1580 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1582 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1587 static bool test_QueryValue(struct dcerpc_pipe *p,
1588 struct torture_context *tctx,
1589 struct policy_handle *handle,
1590 const char *valuename)
1592 struct winreg_QueryValue r;
1594 enum winreg_Type zero_type = 0;
1595 uint32_t offered = 0xfff;
1599 r.in.handle = handle;
1601 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1602 r.in.value_name->name = valuename;
1603 r.in.type = &zero_type;
1604 r.in.data_size = &offered;
1605 r.in.data_length = &zero;
1607 status = dcerpc_winreg_QueryValue(p, tctx, &r);
1608 if (NT_STATUS_IS_ERR(status)) {
1609 torture_fail(tctx, "QueryValue failed");
1612 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1617 static bool test_QueryValue_full(struct dcerpc_pipe *p,
1618 struct torture_context *tctx,
1619 struct policy_handle *handle,
1620 const char *valuename,
1621 bool existing_value)
1623 struct winreg_QueryValue r;
1624 struct winreg_String value_name;
1625 enum winreg_Type type = REG_NONE;
1626 uint32_t data_size = 0;
1627 uint32_t real_data_size = 0;
1628 uint32_t data_length = 0;
1629 uint8_t *data = NULL;
1630 WERROR expected_error = WERR_BADFILE;
1632 if (valuename == NULL) {
1633 expected_error = WERR_INVALID_PARAM;
1638 init_winreg_String(&value_name, NULL);
1640 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1642 r.in.handle = handle;
1643 r.in.value_name = &value_name;
1645 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r), "QueryValue failed");
1646 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1647 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1649 init_winreg_String(&value_name, valuename);
1650 r.in.value_name = &value_name;
1652 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1653 "QueryValue failed");
1654 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1655 "QueryValue failed");
1659 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1660 "QueryValue failed");
1661 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1662 "QueryValue failed");
1664 r.in.data_length = &data_length;
1665 r.out.data_length = &data_length;
1666 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1667 "QueryValue failed");
1668 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1669 "QueryValue failed");
1671 r.in.data_size = &data_size;
1672 r.out.data_size = &data_size;
1673 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1674 "QueryValue failed");
1675 if (existing_value) {
1676 torture_assert_werr_ok(tctx, r.out.result,
1677 "QueryValue failed");
1679 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1680 "QueryValue failed");
1683 real_data_size = *r.out.data_size;
1685 data = talloc_zero_array(tctx, uint8_t, 0);
1688 *r.in.data_size = 0;
1689 *r.out.data_size = 0;
1690 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1691 "QueryValue failed");
1692 if (existing_value) {
1693 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1694 "QueryValue failed");
1696 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1697 "QueryValue failed");
1700 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1703 r.in.data_size = &real_data_size;
1704 r.out.data_size = &real_data_size;
1705 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue(p, tctx, &r),
1706 "QueryValue failed");
1707 if (existing_value) {
1708 torture_assert_werr_ok(tctx, r.out.result,
1709 "QueryValue failed");
1711 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1712 "QueryValue failed");
1718 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1719 struct policy_handle *handle, int max_valnamelen,
1722 struct winreg_EnumValue r;
1723 enum winreg_Type type = 0;
1724 uint32_t size = max_valbufsize, zero = 0;
1727 struct winreg_ValNameBuf name;
1733 r.in.handle = handle;
1734 r.in.enum_index = 0;
1739 r.in.length = &zero;
1743 torture_assert_ntstatus_ok(tctx,
1744 dcerpc_winreg_EnumValue(p, tctx, &r),
1745 "EnumValue failed");
1747 if (W_ERROR_IS_OK(r.out.result)) {
1748 ret &= test_QueryValue(p, tctx, handle,
1750 ret &= test_QueryMultipleValues(p, tctx, handle,
1755 } while (W_ERROR_IS_OK(r.out.result));
1757 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1758 "EnumValue failed");
1763 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1764 struct torture_context *tctx)
1766 struct winreg_AbortSystemShutdown r;
1767 uint16_t server = 0x0;
1770 r.in.server = &server;
1772 torture_assert_ntstatus_ok(tctx,
1773 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1774 "AbortSystemShutdown failed");
1776 torture_assert_werr_ok(tctx, r.out.result,
1777 "AbortSystemShutdown failed");
1782 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1783 struct dcerpc_pipe *p)
1785 struct winreg_InitiateSystemShutdown r;
1786 uint16_t hostname = 0x0;
1789 r.in.hostname = &hostname;
1790 r.in.message = talloc(tctx, struct lsa_StringLarge);
1791 init_lsa_StringLarge(r.in.message, "spottyfood");
1792 r.in.force_apps = 1;
1796 torture_assert_ntstatus_ok(tctx,
1797 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1798 "InitiateSystemShutdown failed");
1800 torture_assert_werr_ok(tctx, r.out.result,
1801 "InitiateSystemShutdown failed");
1803 return test_AbortSystemShutdown(p, tctx);
1807 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1808 struct dcerpc_pipe *p)
1810 struct winreg_InitiateSystemShutdownEx r;
1811 uint16_t hostname = 0x0;
1814 r.in.hostname = &hostname;
1815 r.in.message = talloc(tctx, struct lsa_StringLarge);
1816 init_lsa_StringLarge(r.in.message, "spottyfood");
1817 r.in.force_apps = 1;
1822 torture_assert_ntstatus_ok(tctx,
1823 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1824 "InitiateSystemShutdownEx failed");
1826 torture_assert_werr_ok(tctx, r.out.result,
1827 "InitiateSystemShutdownEx failed");
1829 return test_AbortSystemShutdown(p, tctx);
1831 #define MAX_DEPTH 2 /* Only go this far down the tree */
1833 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1834 struct policy_handle *handle, int depth,
1837 if (depth == MAX_DEPTH)
1840 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1843 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1846 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1849 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1852 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1855 test_CloseKey(p, tctx, handle);
1860 static bool test_SetValue_simple(struct dcerpc_pipe *p,
1861 struct torture_context *tctx,
1862 struct policy_handle *handle)
1864 const char *value_name = TEST_VALUE;
1865 uint32_t value = 0x12345678;
1866 const char *string = "torture";
1868 enum winreg_Type types[] = {
1876 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1878 for (t=0; t < ARRAY_SIZE(types); t++) {
1880 enum winreg_Type w_type;
1881 uint32_t w_size, w_length;
1886 blob = data_blob_talloc_zero(tctx, 4);
1887 SIVAL(blob.data, 0, value);
1890 blob = data_blob_string_const("binary_blob");
1893 torture_assert(tctx,
1894 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1898 (void **)&blob.data,
1903 torture_assert(tctx,
1904 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1908 (void **)&blob.data,
1911 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1912 memset(&blob.data[blob.length - 2], '\0', 2);
1918 torture_assert(tctx,
1919 test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
1920 "test_SetValue failed");
1921 torture_assert(tctx,
1922 test_QueryValue_full(p, tctx, handle, value_name, true),
1923 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1924 torture_assert(tctx,
1925 test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1926 "test_winreg_QueryValue failed");
1927 torture_assert(tctx,
1928 test_DeleteValue(p, tctx, handle, value_name),
1929 "test_DeleteValue failed");
1931 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1932 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1933 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1934 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1937 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
1942 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1944 static bool test_Open_Security(struct torture_context *tctx,
1945 struct dcerpc_pipe *p, void *userdata)
1947 struct policy_handle handle, newhandle;
1948 bool ret = true, created2 = false;
1949 bool created4 = false;
1950 struct winreg_OpenHKLM r;
1952 winreg_open_fn open_fn = userdata;
1955 r.in.system_name = 0;
1956 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1957 r.out.handle = &handle;
1959 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1962 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1964 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1965 torture_comment(tctx,
1966 "CreateKey (TEST_KEY_BASE) failed\n");
1969 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1970 NULL, &newhandle)) {
1974 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1975 printf("CloseKey failed\n");
1979 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1983 if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1984 printf("CloseKey failed\n");
1988 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1992 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1993 printf("DeleteKey failed\n");
1997 if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1998 printf("DeleteKey failed\n");
2002 /* The HKCR hive has a very large fanout */
2003 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2004 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
2008 if (!test_key(p, tctx, &handle, 0, true)) {
2013 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2018 static bool test_SetValue_extended(struct dcerpc_pipe *p,
2019 struct torture_context *tctx,
2020 struct policy_handle *handle)
2022 const char *value_name = TEST_VALUE;
2023 enum winreg_Type types[] = {
2029 REG_DWORD_BIG_ENDIAN,
2033 REG_FULL_RESOURCE_DESCRIPTOR,
2034 REG_RESOURCE_REQUIREMENTS_LIST,
2043 const char *str = "abcdefghijklmnopqrstuvwxzy";
2046 if (torture_setting_bool(tctx, "samba3", false) ||
2047 torture_setting_bool(tctx, "samba4", false)) {
2048 torture_skip(tctx, "skipping extended SetValue test against Samba");
2051 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2053 for (t=0; t < ARRAY_SIZE(types); t++) {
2054 for (s=0; s < strlen(str); s++) {
2056 enum winreg_Type w_type;
2057 uint32_t w_size, w_length;
2060 const char *string = talloc_strndup(tctx, str, s);
2061 DATA_BLOB blob = data_blob_string_const(string);
2063 torture_assert(tctx,
2064 test_SetValue(p, tctx, handle, value_name, types[t], blob.data, blob.length),
2065 "test_SetValue failed");
2067 torture_assert(tctx,
2068 test_winreg_QueryValue(tctx, p, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2069 "test_winreg_QueryValue failed");
2071 torture_assert(tctx,
2072 test_DeleteValue(p, tctx, handle, value_name),
2073 "test_DeleteValue failed");
2075 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2076 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2077 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2078 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2082 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2087 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2088 #define VALUE_CURRENT_VERSION "CurrentVersion"
2090 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2093 struct policy_handle handle, newhandle;
2094 bool ret = true, created = false, deleted = false;
2095 bool created3 = false, created_subkey = false;
2096 struct winreg_OpenHKLM r;
2098 winreg_open_fn open_fn = userdata;
2101 r.in.system_name = 0;
2102 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2103 r.out.handle = &handle;
2105 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
2108 if (open_fn == (void *)dcerpc_winreg_OpenHKLM) {
2110 torture_assert(tctx, test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, &newhandle),
2111 "failed to open current version key");
2113 torture_assert(tctx, _test_OpenKey(p, tctx, &handle, KEY_CURRENT_VERSION, KEY_QUERY_VALUE, &newhandle, WERR_OK, NULL),
2114 "failed to open current version key");
2116 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2117 "failed to query current version");
2118 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "IDoNotExist", false),
2119 "failed to query current version");
2120 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, NULL, false),
2121 "test_QueryValue_full for NULL value failed");
2122 torture_assert(tctx, test_QueryValue_full(p, tctx, &newhandle, "", false),
2123 "test_QueryValue_full for \"\" value failed");
2125 torture_assert(tctx, test_CloseKey(p, tctx, &newhandle),
2126 "failed to close current version key");
2129 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2131 if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
2132 torture_comment(tctx,
2133 "CreateKey (TEST_KEY_BASE) failed\n");
2136 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
2137 torture_comment(tctx,
2138 "CreateKey failed - not considering a failure\n");
2143 if (created && !test_FlushKey(p, tctx, &handle)) {
2144 torture_comment(tctx, "FlushKey failed\n");
2148 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
2150 "CreateKey failed (OpenKey after Create didn't work)\n");
2153 torture_assert(tctx, test_SetValue_simple(p, tctx, &newhandle),
2154 "simple SetValue test failed");
2155 torture_assert(tctx, test_SetValue_extended(p, tctx, &newhandle),
2156 "extended SetValue test failed");
2159 if (created && !test_CloseKey(p, tctx, &newhandle))
2161 "CreateKey failed (CloseKey after Open didn't work)\n");
2163 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
2164 torture_comment(tctx, "DeleteKey failed\n");
2170 if (created && !test_FlushKey(p, tctx, &handle)) {
2171 torture_comment(tctx, "FlushKey failed\n");
2175 if (created && deleted &&
2176 !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
2177 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
2178 WERR_BADFILE, NULL)) {
2179 torture_comment(tctx,
2180 "DeleteKey failed (OpenKey after Delete "
2181 "did not return WERR_BADFILE)\n");
2185 if (!test_GetVersion(p, tctx, &handle)) {
2186 torture_comment(tctx, "GetVersion failed\n");
2190 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
2195 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
2196 created_subkey = true;
2199 if (created_subkey &&
2200 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
2201 printf("DeleteKey failed\n");
2205 /* The HKCR hive has a very large fanout */
2206 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
2207 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2211 if (!test_key(p, tctx, &handle, 0, false)) {
2216 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
2221 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2223 struct torture_rpc_tcase *tcase;
2224 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2225 struct torture_test *test;
2227 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2230 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2231 test_InitiateSystemShutdown);
2232 test->dangerous = true;
2234 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2235 test_InitiateSystemShutdownEx);
2236 test->dangerous = true;
2238 /* Basic tests without security descriptors */
2239 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
2241 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2242 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
2244 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2245 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
2247 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2248 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
2250 (winreg_open_fn)dcerpc_winreg_OpenHKCU);
2252 /* Security descriptor tests */
2253 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
2255 (winreg_open_fn)dcerpc_winreg_OpenHKLM);
2256 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
2258 (winreg_open_fn)dcerpc_winreg_OpenHKU);
2259 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
2261 (winreg_open_fn)dcerpc_winreg_OpenHKCR);
2262 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
2264 (winreg_open_fn)dcerpc_winreg_OpenHKCU);