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"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
44 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
51 static void init_winreg_String(struct winreg_String *name, const char *s)
55 name->name_len = 2 * (strlen_m(s) + 1);
56 name->name_size = name->name_len;
63 static bool test_GetVersion(struct dcerpc_binding_handle *b,
64 struct torture_context *tctx,
65 struct policy_handle *handle)
67 struct winreg_GetVersion r;
70 torture_comment(tctx, "Testing GetVersion\n");
76 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
79 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
84 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
85 struct torture_context *tctx,
86 struct policy_handle *handle)
88 struct winreg_NotifyChangeKeyValue r;
92 r.in.watch_subtree = true;
93 r.in.notify_filter = 0;
94 r.in.unknown = r.in.unknown2 = 0;
95 init_winreg_String(&r.in.string1, NULL);
96 init_winreg_String(&r.in.string2, NULL);
98 torture_assert_ntstatus_ok(tctx,
99 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
100 "NotifyChangeKeyValue failed");
102 if (!W_ERROR_IS_OK(r.out.result)) {
103 torture_comment(tctx,
104 "NotifyChangeKeyValue failed - %s - not considering\n",
105 win_errstr(r.out.result));
112 static bool test_CreateKey_opts(struct torture_context *tctx,
113 struct dcerpc_binding_handle *b,
114 struct policy_handle *handle,
118 uint32_t access_mask,
119 struct winreg_SecBuf *secdesc,
120 WERROR expected_result,
121 enum winreg_CreateAction *action_taken_p,
122 struct policy_handle *new_handle_p)
124 struct winreg_CreateKey r;
125 struct policy_handle newhandle;
126 enum winreg_CreateAction action_taken = 0;
128 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
131 r.in.handle = handle;
132 init_winreg_String(&r.in.name, name);
133 init_winreg_String(&r.in.keyclass, kclass);
134 r.in.options = options;
135 r.in.access_mask = access_mask;
136 r.in.action_taken = &action_taken;
137 r.in.secdesc = secdesc;
138 r.out.new_handle = &newhandle;
139 r.out.action_taken = &action_taken;
141 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
144 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
147 *new_handle_p = newhandle;
149 if (action_taken_p) {
150 *action_taken_p = *r.out.action_taken;
156 static bool test_CreateKey(struct dcerpc_binding_handle *b,
157 struct torture_context *tctx,
158 struct policy_handle *handle, const char *name,
161 return test_CreateKey_opts(tctx, b, handle, name, kclass,
162 REG_KEYTYPE_NON_VOLATILE,
163 SEC_FLAG_MAXIMUM_ALLOWED,
166 NULL, /* action_taken */
167 NULL /* new_handle */);
171 createkey testing with a SD
173 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
174 struct torture_context *tctx,
175 struct policy_handle *handle, const char *name,
177 struct policy_handle *newhandle)
179 struct winreg_CreateKey r;
180 enum winreg_CreateAction action_taken = 0;
181 struct security_descriptor *sd;
183 struct winreg_SecBuf secbuf;
185 sd = security_descriptor_dacl_create(tctx,
188 SID_NT_AUTHENTICATED_USERS,
189 SEC_ACE_TYPE_ACCESS_ALLOWED,
191 SEC_ACE_FLAG_OBJECT_INHERIT |
192 SEC_ACE_FLAG_CONTAINER_INHERIT,
195 torture_assert_ndr_success(tctx,
196 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
197 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
198 "Failed to push security_descriptor ?!\n");
200 secbuf.sd.data = sdblob.data;
201 secbuf.sd.len = sdblob.length;
202 secbuf.sd.size = sdblob.length;
203 secbuf.length = sdblob.length-10;
207 r.in.handle = handle;
208 r.out.new_handle = newhandle;
209 init_winreg_String(&r.in.name, name);
210 init_winreg_String(&r.in.keyclass, kclass);
212 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
213 r.in.action_taken = r.out.action_taken = &action_taken;
214 r.in.secdesc = &secbuf;
216 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
217 "CreateKey with sd failed");
219 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
224 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
225 struct torture_context *tctx,
226 struct policy_handle *handle,
227 uint32_t *sec_info_ptr,
229 struct security_descriptor **sd_out)
231 struct winreg_GetKeySecurity r;
232 struct security_descriptor *sd = NULL;
235 struct dcerpc_binding_handle *b = p->binding_handle;
238 sec_info = *sec_info_ptr;
240 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
245 r.in.handle = handle;
246 r.in.sec_info = sec_info;
247 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
248 r.in.sd->size = 0x1000;
250 torture_assert_ntstatus_ok(tctx,
251 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
252 "GetKeySecurity failed");
254 torture_assert_werr_equal(tctx, r.out.result, get_werr,
255 "GetKeySecurity failed");
257 sdblob.data = r.out.sd->data;
258 sdblob.length = r.out.sd->len;
260 sd = talloc_zero(tctx, struct security_descriptor);
262 torture_assert_ndr_success(tctx,
263 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
264 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
265 "pull_security_descriptor failed");
267 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
268 NDR_PRINT_DEBUG(security_descriptor, sd);
280 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
281 struct torture_context *tctx,
282 struct policy_handle *handle,
283 struct security_descriptor **sd_out)
285 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
288 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
289 struct torture_context *tctx,
290 struct policy_handle *handle,
291 uint32_t *sec_info_ptr,
292 struct security_descriptor *sd,
295 struct winreg_SetKeySecurity r;
296 struct KeySecurityData *sdata = NULL;
299 struct dcerpc_binding_handle *b = p->binding_handle;
303 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
304 NDR_PRINT_DEBUG(security_descriptor, sd);
307 torture_assert_ndr_success(tctx,
308 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
309 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
310 "push_security_descriptor failed");
312 sdata = talloc_zero(tctx, struct KeySecurityData);
313 sdata->data = sdblob.data;
314 sdata->size = sdblob.length;
315 sdata->len = sdblob.length;
318 sec_info = *sec_info_ptr;
320 sec_info = SECINFO_UNPROTECTED_SACL |
321 SECINFO_UNPROTECTED_DACL;
323 sec_info |= SECINFO_OWNER;
326 sec_info |= SECINFO_GROUP;
329 sec_info |= SECINFO_SACL;
332 sec_info |= SECINFO_DACL;
336 r.in.handle = handle;
337 r.in.sec_info = sec_info;
340 torture_assert_ntstatus_ok(tctx,
341 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
342 "SetKeySecurity failed");
344 torture_assert_werr_equal(tctx, r.out.result, werr,
345 "SetKeySecurity failed");
350 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
351 struct torture_context *tctx,
352 struct policy_handle *handle,
353 struct security_descriptor *sd)
355 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
358 static bool test_CloseKey(struct dcerpc_binding_handle *b,
359 struct torture_context *tctx,
360 struct policy_handle *handle)
362 struct winreg_CloseKey r;
365 r.in.handle = r.out.handle = handle;
367 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
370 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
375 static bool test_FlushKey(struct dcerpc_binding_handle *b,
376 struct torture_context *tctx,
377 struct policy_handle *handle)
379 struct winreg_FlushKey r;
382 r.in.handle = handle;
384 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
387 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
392 static bool test_OpenKey_opts(struct torture_context *tctx,
393 struct dcerpc_binding_handle *b,
394 struct policy_handle *hive_handle,
397 uint32_t access_mask,
398 struct policy_handle *key_handle,
399 WERROR expected_result)
401 struct winreg_OpenKey r;
404 r.in.parent_handle = hive_handle;
405 init_winreg_String(&r.in.keyname, keyname);
406 r.in.options = options;
407 r.in.access_mask = access_mask;
408 r.out.handle = key_handle;
410 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
413 torture_assert_werr_equal(tctx, r.out.result, expected_result,
419 static bool test_OpenKey(struct dcerpc_binding_handle *b,
420 struct torture_context *tctx,
421 struct policy_handle *hive_handle,
422 const char *keyname, struct policy_handle *key_handle)
424 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
425 REG_KEYTYPE_NON_VOLATILE,
426 SEC_FLAG_MAXIMUM_ALLOWED,
431 static bool test_Cleanup(struct dcerpc_binding_handle *b,
432 struct torture_context *tctx,
433 struct policy_handle *handle, const char *key)
435 struct winreg_DeleteKey r;
438 r.in.handle = handle;
440 init_winreg_String(&r.in.key, key);
441 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
446 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
447 struct torture_context *tctx,
448 struct policy_handle *handle,
452 struct security_descriptor *sd = NULL;
454 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
458 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
465 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
466 struct torture_context *tctx,
467 struct policy_handle *handle,
470 struct policy_handle new_handle;
472 struct dcerpc_binding_handle *b = p->binding_handle;
474 torture_comment(tctx, "SecurityDescriptor get & set\n");
476 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
480 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
485 if (!test_CloseKey(b, tctx, &new_handle)) {
492 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
493 struct torture_context *tctx,
494 struct policy_handle *handle,
495 uint32_t access_mask,
501 struct policy_handle new_handle;
503 struct dcerpc_binding_handle *b = p->binding_handle;
506 test_OpenKey_opts(tctx, b, handle, key,
507 REG_KEYTYPE_NON_VOLATILE,
511 "failed to open key");
513 if (!W_ERROR_IS_OK(open_werr)) {
517 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
518 get_werr, set_werr)) {
522 if (!test_CloseKey(b, tctx, &new_handle)) {
529 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
530 struct torture_context *tctx,
531 struct policy_handle *handle,
532 const struct dom_sid *sid)
534 struct security_descriptor *sd = NULL;
537 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
541 if (!sd || !sd->dacl) {
545 for (i = 0; i < sd->dacl->num_aces; i++) {
546 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
554 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
555 struct torture_context *tctx,
556 struct policy_handle *handle,
558 const struct dom_sid *sid)
560 struct policy_handle new_handle;
562 struct dcerpc_binding_handle *b = p->binding_handle;
564 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
568 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570 test_CloseKey(b, tctx, &new_handle);
575 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
576 struct torture_context *tctx,
577 struct policy_handle *handle,
578 const struct dom_sid *sid)
580 struct security_descriptor *sd = NULL;
582 uint32_t sec_info = SECINFO_SACL;
584 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
588 if (!sd || !sd->sacl) {
592 for (i = 0; i < sd->sacl->num_aces; i++) {
593 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
601 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
602 struct torture_context *tctx,
603 struct policy_handle *handle,
605 const struct dom_sid *sid)
607 struct policy_handle new_handle;
609 struct dcerpc_binding_handle *b = p->binding_handle;
612 test_OpenKey_opts(tctx, b, handle, key,
613 REG_KEYTYPE_NON_VOLATILE,
614 SEC_FLAG_SYSTEM_SECURITY,
617 "failed to open key");
619 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621 test_CloseKey(b, tctx, &new_handle);
626 static bool test_owner_present(struct dcerpc_pipe *p,
627 struct torture_context *tctx,
628 struct policy_handle *handle,
629 const struct dom_sid *sid)
631 struct security_descriptor *sd = NULL;
632 uint32_t sec_info = SECINFO_OWNER;
634 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
638 if (!sd || !sd->owner_sid) {
642 return dom_sid_equal(sd->owner_sid, sid);
645 static bool _test_owner_present(struct dcerpc_pipe *p,
646 struct torture_context *tctx,
647 struct policy_handle *handle,
649 const struct dom_sid *sid)
651 struct policy_handle new_handle;
653 struct dcerpc_binding_handle *b = p->binding_handle;
655 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
659 ret = test_owner_present(p, tctx, &new_handle, sid);
661 test_CloseKey(b, tctx, &new_handle);
666 static bool test_group_present(struct dcerpc_pipe *p,
667 struct torture_context *tctx,
668 struct policy_handle *handle,
669 const struct dom_sid *sid)
671 struct security_descriptor *sd = NULL;
672 uint32_t sec_info = SECINFO_GROUP;
674 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
678 if (!sd || !sd->group_sid) {
682 return dom_sid_equal(sd->group_sid, sid);
685 static bool _test_group_present(struct dcerpc_pipe *p,
686 struct torture_context *tctx,
687 struct policy_handle *handle,
689 const struct dom_sid *sid)
691 struct policy_handle new_handle;
693 struct dcerpc_binding_handle *b = p->binding_handle;
695 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
699 ret = test_group_present(p, tctx, &new_handle, sid);
701 test_CloseKey(b, tctx, &new_handle);
706 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
707 struct torture_context *tctx,
708 struct policy_handle *handle,
709 const struct dom_sid *sid,
712 struct security_descriptor *sd = NULL;
715 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
719 if (!sd || !sd->dacl) {
723 for (i = 0; i < sd->dacl->num_aces; i++) {
724 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
725 (sd->dacl->aces[i].flags == flags)) {
733 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
734 struct torture_context *tctx,
735 struct policy_handle *handle,
736 const struct security_ace *ace)
738 struct security_descriptor *sd = NULL;
741 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
745 if (!sd || !sd->dacl) {
749 for (i = 0; i < sd->dacl->num_aces; i++) {
750 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
758 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
759 struct torture_context *tctx,
760 struct policy_handle *handle,
762 struct security_descriptor *sd)
764 struct policy_handle new_handle;
766 struct dcerpc_binding_handle *b = p->binding_handle;
768 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
772 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
776 if (!test_CloseKey(b, tctx, &new_handle)) {
783 static bool test_BackupSecurity(struct dcerpc_pipe *p,
784 struct torture_context *tctx,
785 struct policy_handle *handle,
787 struct security_descriptor **sd)
789 struct policy_handle new_handle;
791 struct dcerpc_binding_handle *b = p->binding_handle;
793 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
797 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
801 if (!test_CloseKey(b, tctx, &new_handle)) {
808 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
809 struct torture_context *tctx,
810 struct policy_handle *handle,
814 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
829 struct security_descriptor *sd = NULL;
830 struct security_descriptor *sd_orig = NULL;
831 struct security_ace *ace = NULL;
832 struct policy_handle new_handle;
834 struct dcerpc_binding_handle *b = p->binding_handle;
836 torture_comment(tctx, "SecurityDescriptor inheritance\n");
838 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 sd_orig = security_descriptor_copy(tctx, sd);
847 if (sd_orig == NULL) {
851 ace = security_ace_create(tctx,
853 SEC_ACE_TYPE_ACCESS_ALLOWED,
855 SEC_ACE_FLAG_CONTAINER_INHERIT);
857 torture_assert_ntstatus_ok(tctx,
858 security_descriptor_dacl_add(sd, ace),
859 "failed to add ace");
861 /* FIXME: add further tests for these flags */
862 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
863 SEC_DESC_SACL_AUTO_INHERITED;
865 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
870 test_dacl_ace_present(p, tctx, &new_handle, ace),
871 "new ACE not present!");
873 if (!test_CloseKey(b, tctx, &new_handle)) {
877 if (!test_CreateKey(b, tctx, handle, TEST_SUBKEY_SD, NULL)) {
882 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
887 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
888 torture_comment(tctx, "inherited ACE not present!\n");
893 test_CloseKey(b, tctx, &new_handle);
894 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
899 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
904 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
905 torture_comment(tctx, "inherited ACE not present!\n");
911 test_CloseKey(b, tctx, &new_handle);
912 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
913 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
918 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
919 struct torture_context *tctx,
920 struct policy_handle *handle,
924 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
936 struct security_descriptor *sd = NULL;
937 struct security_descriptor *sd_orig = NULL;
938 struct security_ace *ace = NULL;
939 struct policy_handle new_handle;
940 struct dom_sid *sid = NULL;
942 uint8_t ace_flags = 0x0;
943 struct dcerpc_binding_handle *b = p->binding_handle;
945 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
947 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
951 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
955 sd_orig = security_descriptor_copy(tctx, sd);
956 if (sd_orig == NULL) {
960 ace = security_ace_create(tctx,
962 SEC_ACE_TYPE_ACCESS_ALLOWED,
964 SEC_ACE_FLAG_CONTAINER_INHERIT |
965 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
967 torture_assert_ntstatus_ok(tctx,
968 security_descriptor_dacl_add(sd, ace),
969 "failed to add ace");
971 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
976 test_dacl_ace_present(p, tctx, &new_handle, ace),
977 "new ACE not present!");
979 if (!test_CloseKey(b, tctx, &new_handle)) {
983 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
987 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
992 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
993 torture_comment(tctx, "inherited ACE present but should not!\n");
998 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1003 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1004 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1009 test_CloseKey(b, tctx, &new_handle);
1011 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
1016 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1017 torture_comment(tctx, "inherited ACE present but should not!\n");
1022 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1023 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1030 test_CloseKey(b, tctx, &new_handle);
1031 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
1032 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1037 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1038 struct torture_context *tctx,
1039 struct policy_handle *handle,
1045 struct winreg_mask_result_table {
1046 uint32_t access_mask;
1050 } sd_mask_tests[] = {
1052 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1053 { SEC_FLAG_MAXIMUM_ALLOWED,
1054 WERR_OK, WERR_OK, WERR_OK },
1055 { SEC_STD_WRITE_DAC,
1056 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1057 { SEC_FLAG_SYSTEM_SECURITY,
1058 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1061 /* FIXME: before this test can ever run successfully we need a way to
1062 * correctly read a NULL security_descritpor in ndr, get the required
1063 * length, requery, etc.
1068 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1070 torture_comment(tctx,
1071 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1072 sd_mask_tests[i].access_mask);
1073 torture_comment(tctx,
1074 "expecting: open %s, get: %s, set: %s\n",
1075 win_errstr(sd_mask_tests[i].open_werr),
1076 win_errstr(sd_mask_tests[i].get_werr),
1077 win_errstr(sd_mask_tests[i].set_werr));
1079 if (_test_SecurityDescriptor(p, tctx, handle,
1080 sd_mask_tests[i].access_mask, key,
1081 sd_mask_tests[i].open_werr,
1082 sd_mask_tests[i].get_werr,
1083 sd_mask_tests[i].set_werr)) {
1091 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1092 struct torture_context *,
1093 struct policy_handle *,
1095 const struct dom_sid *);
1097 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1098 struct torture_context *tctx,
1099 struct policy_handle *handle,
1102 uint32_t access_mask,
1104 struct security_descriptor *sd,
1106 bool expect_present,
1107 bool (*fn) (struct dcerpc_pipe *,
1108 struct torture_context *,
1109 struct policy_handle *,
1111 const struct dom_sid *),
1112 const struct dom_sid *sid)
1114 struct policy_handle new_handle;
1115 struct dcerpc_binding_handle *b = p->binding_handle;
1117 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1118 "0x%08x, access_mask: 0x%08x\n",
1119 test, sec_info, access_mask);
1121 torture_assert(tctx,
1122 test_OpenKey_opts(tctx, b, handle, key,
1123 REG_KEYTYPE_NON_VOLATILE,
1127 "failed to open key");
1129 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1132 torture_warning(tctx,
1133 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1136 test_CloseKey(b, tctx, &new_handle);
1140 test_CloseKey(b, tctx, &new_handle);
1142 if (W_ERROR_IS_OK(set_werr)) {
1144 present = fn(p, tctx, handle, key, sid);
1145 if ((expect_present) && (!present)) {
1146 torture_warning(tctx,
1147 "%s sid is not present!\n",
1151 if ((!expect_present) && (present)) {
1152 torture_warning(tctx,
1153 "%s sid is present but not expected!\n",
1162 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1163 struct torture_context *tctx,
1164 struct policy_handle *handle,
1167 struct security_descriptor *sd_orig = NULL;
1168 struct dom_sid *sid = NULL;
1172 struct security_descriptor *sd_owner =
1173 security_descriptor_dacl_create(tctx,
1175 TEST_SID, NULL, NULL);
1177 struct security_descriptor *sd_group =
1178 security_descriptor_dacl_create(tctx,
1180 NULL, TEST_SID, NULL);
1182 struct security_descriptor *sd_dacl =
1183 security_descriptor_dacl_create(tctx,
1187 SEC_ACE_TYPE_ACCESS_ALLOWED,
1190 SID_NT_AUTHENTICATED_USERS,
1191 SEC_ACE_TYPE_ACCESS_ALLOWED,
1196 struct security_descriptor *sd_sacl =
1197 security_descriptor_sacl_create(tctx,
1201 SEC_ACE_TYPE_SYSTEM_AUDIT,
1203 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1206 struct winreg_secinfo_table {
1207 struct security_descriptor *sd;
1211 secinfo_verify_fn fn;
1214 struct winreg_secinfo_table sec_info_owner_tests[] = {
1215 { sd_owner, 0, WERR_OK,
1216 false, (secinfo_verify_fn)_test_owner_present },
1217 { sd_owner, SECINFO_OWNER, WERR_OK,
1218 true, (secinfo_verify_fn)_test_owner_present },
1219 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1220 { sd_owner, SECINFO_DACL, WERR_OK,
1221 true, (secinfo_verify_fn)_test_owner_present },
1222 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1225 uint32_t sd_owner_good_access_masks[] = {
1226 SEC_FLAG_MAXIMUM_ALLOWED,
1227 /* SEC_STD_WRITE_OWNER, */
1230 struct winreg_secinfo_table sec_info_group_tests[] = {
1231 { sd_group, 0, WERR_OK,
1232 false, (secinfo_verify_fn)_test_group_present },
1233 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1234 { sd_group, SECINFO_GROUP, WERR_OK,
1235 true, (secinfo_verify_fn)_test_group_present },
1236 { sd_group, SECINFO_DACL, WERR_OK,
1237 true, (secinfo_verify_fn)_test_group_present },
1238 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1241 uint32_t sd_group_good_access_masks[] = {
1242 SEC_FLAG_MAXIMUM_ALLOWED,
1245 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1246 { sd_dacl, 0, WERR_OK,
1247 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1248 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1249 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1250 { sd_dacl, SECINFO_DACL, WERR_OK,
1251 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1252 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1255 uint32_t sd_dacl_good_access_masks[] = {
1256 SEC_FLAG_MAXIMUM_ALLOWED,
1260 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1261 { sd_sacl, 0, WERR_OK,
1262 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1263 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1264 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1265 { sd_sacl, SECINFO_DACL, WERR_OK,
1266 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1267 { sd_sacl, SECINFO_SACL, WERR_OK,
1268 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1271 uint32_t sd_sacl_good_access_masks[] = {
1272 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1273 /* SEC_FLAG_SYSTEM_SECURITY, */
1276 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1281 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1287 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1289 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1291 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1294 sd_owner_good_access_masks[a],
1295 sec_info_owner_tests[i].sec_info,
1296 sec_info_owner_tests[i].sd,
1297 sec_info_owner_tests[i].set_werr,
1298 sec_info_owner_tests[i].sid_present,
1299 sec_info_owner_tests[i].fn,
1302 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1311 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1313 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1315 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1318 sd_group_good_access_masks[a],
1319 sec_info_group_tests[i].sec_info,
1320 sec_info_group_tests[i].sd,
1321 sec_info_group_tests[i].set_werr,
1322 sec_info_group_tests[i].sid_present,
1323 sec_info_group_tests[i].fn,
1326 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1335 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1337 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1339 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1342 sd_dacl_good_access_masks[a],
1343 sec_info_dacl_tests[i].sec_info,
1344 sec_info_dacl_tests[i].sd,
1345 sec_info_dacl_tests[i].set_werr,
1346 sec_info_dacl_tests[i].sid_present,
1347 sec_info_dacl_tests[i].fn,
1350 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1359 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1361 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1363 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1366 sd_sacl_good_access_masks[a],
1367 sec_info_sacl_tests[i].sec_info,
1368 sec_info_sacl_tests[i].sd,
1369 sec_info_sacl_tests[i].set_werr,
1370 sec_info_sacl_tests[i].sid_present,
1371 sec_info_sacl_tests[i].fn,
1374 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1382 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1387 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1388 struct torture_context *tctx,
1389 struct policy_handle *handle,
1394 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1395 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1399 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1400 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1404 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1405 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1409 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1410 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1414 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1415 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1422 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1423 struct torture_context *tctx,
1424 struct policy_handle *handle,
1426 WERROR expected_result)
1428 struct winreg_DeleteKey r;
1430 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1432 r.in.handle = handle;
1433 init_winreg_String(&r.in.key, key);
1435 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1436 "Delete Key failed");
1437 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1438 "DeleteKey failed");
1443 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1444 struct torture_context *tctx,
1445 struct policy_handle *handle, const char *key)
1447 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1450 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1451 struct torture_context *tctx,
1452 struct policy_handle *handle, char *kclass)
1454 struct winreg_QueryInfoKey r;
1455 uint32_t num_subkeys, max_subkeylen, max_classlen,
1456 num_values, max_valnamelen, max_valbufsize,
1458 NTTIME last_changed_time;
1461 r.in.handle = handle;
1462 r.out.num_subkeys = &num_subkeys;
1463 r.out.max_subkeylen = &max_subkeylen;
1464 r.out.max_classlen = &max_classlen;
1465 r.out.num_values = &num_values;
1466 r.out.max_valnamelen = &max_valnamelen;
1467 r.out.max_valbufsize = &max_valbufsize;
1468 r.out.secdescsize = &secdescsize;
1469 r.out.last_changed_time = &last_changed_time;
1471 r.out.classname = talloc(tctx, struct winreg_String);
1473 r.in.classname = talloc(tctx, struct winreg_String);
1474 init_winreg_String(r.in.classname, kclass);
1476 torture_assert_ntstatus_ok(tctx,
1477 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1478 "QueryInfoKey failed");
1480 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1485 static bool test_SetValue(struct dcerpc_binding_handle *b,
1486 struct torture_context *tctx,
1487 struct policy_handle *handle,
1488 const char *value_name,
1489 enum winreg_Type type,
1493 struct winreg_SetValue r;
1494 struct winreg_String name;
1496 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1497 value_name, str_regtype(type), size);
1499 init_winreg_String(&name, value_name);
1501 r.in.handle = handle;
1507 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1508 "winreg_SetValue failed");
1509 torture_assert_werr_ok(tctx, r.out.result,
1510 "winreg_SetValue failed");
1515 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1516 struct torture_context *tctx,
1517 struct policy_handle *handle,
1518 const char *value_name)
1520 struct winreg_DeleteValue r;
1521 struct winreg_String value;
1523 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1525 init_winreg_String(&value, value_name);
1527 r.in.handle = handle;
1530 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1531 "winreg_DeleteValue failed");
1532 torture_assert_werr_ok(tctx, r.out.result,
1533 "winreg_DeleteValue failed");
1538 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1539 struct policy_handle *handle, int depth,
1540 bool test_security);
1542 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1543 struct policy_handle *handle, int depth,
1546 struct winreg_EnumKey r;
1547 struct winreg_StringBuf kclass, name;
1550 struct dcerpc_binding_handle *b = p->binding_handle;
1556 r.in.handle = handle;
1557 r.in.enum_index = 0;
1559 r.in.keyclass = &kclass;
1561 r.in.last_changed_time = &t;
1567 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1569 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1570 struct policy_handle key_handle;
1572 torture_comment(tctx, "EnumKey: %d: %s\n",
1576 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1579 test_key(p, tctx, &key_handle,
1580 depth + 1, test_security);
1586 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1588 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1590 if (!W_ERROR_IS_OK(r.out.result) &&
1591 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1592 torture_fail(tctx, "EnumKey failed");
1598 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1599 struct torture_context *tctx,
1600 struct policy_handle *handle,
1601 const char *valuename)
1603 struct winreg_QueryMultipleValues r;
1608 r.in.key_handle = handle;
1609 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1610 r.in.values[0].name = talloc(tctx, struct winreg_String);
1611 r.in.values[0].name->name = valuename;
1612 r.in.values[0].offset = 0;
1613 r.in.values[0].length = 0;
1614 r.in.values[0].type = 0;
1616 r.in.num_values = 1;
1617 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1618 *r.in.buffer_size = bufsize;
1620 *r.in.buffer_size = bufsize;
1621 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1624 status = dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r);
1626 if(NT_STATUS_IS_ERR(status))
1627 torture_fail(tctx, "QueryMultipleValues failed");
1629 talloc_free(r.in.buffer);
1631 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1633 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1638 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1639 struct torture_context *tctx,
1640 struct policy_handle *handle,
1641 const char *valuename)
1643 struct winreg_QueryValue r;
1645 enum winreg_Type zero_type = 0;
1646 uint32_t offered = 0xfff;
1650 r.in.handle = handle;
1652 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1653 r.in.value_name->name = valuename;
1654 r.in.type = &zero_type;
1655 r.in.data_size = &offered;
1656 r.in.data_length = &zero;
1658 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1659 if (NT_STATUS_IS_ERR(status)) {
1660 torture_fail(tctx, "QueryValue failed");
1663 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1668 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1669 struct torture_context *tctx,
1670 struct policy_handle *handle,
1671 const char *valuename,
1672 bool existing_value)
1674 struct winreg_QueryValue r;
1675 struct winreg_String value_name;
1676 enum winreg_Type type = REG_NONE;
1677 uint32_t data_size = 0;
1678 uint32_t real_data_size = 0;
1679 uint32_t data_length = 0;
1680 uint8_t *data = NULL;
1681 WERROR expected_error = WERR_BADFILE;
1683 if (valuename == NULL) {
1684 expected_error = WERR_INVALID_PARAM;
1689 init_winreg_String(&value_name, NULL);
1691 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1693 r.in.handle = handle;
1694 r.in.value_name = &value_name;
1696 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1697 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1698 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1700 init_winreg_String(&value_name, valuename);
1701 r.in.value_name = &value_name;
1703 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1704 "QueryValue failed");
1705 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1706 "QueryValue failed");
1710 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1711 "QueryValue failed");
1712 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1713 "QueryValue failed");
1715 r.in.data_length = &data_length;
1716 r.out.data_length = &data_length;
1717 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1718 "QueryValue failed");
1719 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1720 "QueryValue failed");
1722 r.in.data_size = &data_size;
1723 r.out.data_size = &data_size;
1724 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1725 "QueryValue failed");
1726 if (existing_value) {
1727 torture_assert_werr_ok(tctx, r.out.result,
1728 "QueryValue failed");
1730 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1731 "QueryValue failed");
1734 real_data_size = *r.out.data_size;
1736 data = talloc_zero_array(tctx, uint8_t, 0);
1739 *r.in.data_size = 0;
1740 *r.out.data_size = 0;
1741 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1742 "QueryValue failed");
1743 if (existing_value) {
1744 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1745 "QueryValue failed");
1747 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1748 "QueryValue failed");
1751 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1754 r.in.data_size = &real_data_size;
1755 r.out.data_size = &real_data_size;
1756 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1757 "QueryValue failed");
1758 if (existing_value) {
1759 torture_assert_werr_ok(tctx, r.out.result,
1760 "QueryValue failed");
1762 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1763 "QueryValue failed");
1769 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1770 struct torture_context *tctx,
1771 struct policy_handle *handle, int max_valnamelen,
1774 struct winreg_EnumValue r;
1775 enum winreg_Type type = 0;
1776 uint32_t size = max_valbufsize, zero = 0;
1779 struct winreg_ValNameBuf name;
1785 r.in.handle = handle;
1786 r.in.enum_index = 0;
1791 r.in.length = &zero;
1795 torture_assert_ntstatus_ok(tctx,
1796 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1797 "EnumValue failed");
1799 if (W_ERROR_IS_OK(r.out.result)) {
1800 ret &= test_QueryValue(b, tctx, handle,
1802 ret &= test_QueryMultipleValues(b, tctx, handle,
1807 } while (W_ERROR_IS_OK(r.out.result));
1809 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1810 "EnumValue failed");
1815 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1816 struct torture_context *tctx)
1818 struct winreg_AbortSystemShutdown r;
1819 uint16_t server = 0x0;
1822 r.in.server = &server;
1824 torture_assert_ntstatus_ok(tctx,
1825 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1826 "AbortSystemShutdown failed");
1828 torture_assert_werr_ok(tctx, r.out.result,
1829 "AbortSystemShutdown failed");
1834 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1835 struct dcerpc_pipe *p)
1837 struct winreg_InitiateSystemShutdown r;
1838 uint16_t hostname = 0x0;
1839 struct dcerpc_binding_handle *b = p->binding_handle;
1842 r.in.hostname = &hostname;
1843 r.in.message = talloc(tctx, struct lsa_StringLarge);
1844 init_lsa_StringLarge(r.in.message, "spottyfood");
1845 r.in.force_apps = 1;
1849 torture_assert_ntstatus_ok(tctx,
1850 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1851 "InitiateSystemShutdown failed");
1853 torture_assert_werr_ok(tctx, r.out.result,
1854 "InitiateSystemShutdown failed");
1856 return test_AbortSystemShutdown(b, tctx);
1860 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1861 struct dcerpc_pipe *p)
1863 struct winreg_InitiateSystemShutdownEx r;
1864 uint16_t hostname = 0x0;
1865 struct dcerpc_binding_handle *b = p->binding_handle;
1868 r.in.hostname = &hostname;
1869 r.in.message = talloc(tctx, struct lsa_StringLarge);
1870 init_lsa_StringLarge(r.in.message, "spottyfood");
1871 r.in.force_apps = 1;
1876 torture_assert_ntstatus_ok(tctx,
1877 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1878 "InitiateSystemShutdownEx failed");
1880 torture_assert_werr_ok(tctx, r.out.result,
1881 "InitiateSystemShutdownEx failed");
1883 return test_AbortSystemShutdown(b, tctx);
1885 #define MAX_DEPTH 2 /* Only go this far down the tree */
1887 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1888 struct policy_handle *handle, int depth,
1891 struct dcerpc_binding_handle *b = p->binding_handle;
1893 if (depth == MAX_DEPTH)
1896 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1899 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1902 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1905 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1908 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1911 test_CloseKey(b, tctx, handle);
1916 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1917 struct torture_context *tctx,
1918 struct policy_handle *handle)
1920 const char *value_name = TEST_VALUE;
1921 uint32_t value = 0x12345678;
1922 uint64_t value2 = 0x12345678;
1923 const char *string = "torture";
1925 enum winreg_Type types[] = {
1927 REG_DWORD_BIG_ENDIAN,
1935 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1937 for (t=0; t < ARRAY_SIZE(types); t++) {
1939 enum winreg_Type w_type;
1940 uint32_t w_size, w_length;
1945 case REG_DWORD_BIG_ENDIAN:
1946 blob = data_blob_talloc_zero(tctx, 4);
1947 SIVAL(blob.data, 0, value);
1950 blob = data_blob_talloc_zero(tctx, 8);
1951 SBVAL(blob.data, 0, value2);
1954 blob = data_blob_string_const("binary_blob");
1957 torture_assert(tctx,
1958 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1962 (void **)&blob.data,
1967 torture_assert(tctx,
1968 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1972 (void **)&blob.data,
1975 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1976 memset(&blob.data[blob.length - 2], '\0', 2);
1982 torture_assert(tctx,
1983 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1984 "test_SetValue failed");
1985 torture_assert(tctx,
1986 test_QueryValue_full(b, tctx, handle, value_name, true),
1987 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1988 torture_assert(tctx,
1989 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1990 "test_winreg_QueryValue failed");
1991 torture_assert(tctx,
1992 test_DeleteValue(b, tctx, handle, value_name),
1993 "test_DeleteValue failed");
1995 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1996 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1997 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1998 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2001 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2006 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2008 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2009 struct torture_context *tctx,
2010 struct policy_handle *handle)
2012 const char *value_name = TEST_VALUE;
2013 enum winreg_Type types[] = {
2019 REG_DWORD_BIG_ENDIAN,
2023 REG_FULL_RESOURCE_DESCRIPTOR,
2024 REG_RESOURCE_REQUIREMENTS_LIST,
2036 if (torture_setting_bool(tctx, "samba3", false) ||
2037 torture_setting_bool(tctx, "samba4", false)) {
2038 torture_skip(tctx, "skipping extended SetValue test against Samba");
2041 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2043 for (t=0; t < ARRAY_SIZE(types); t++) {
2044 for (l=0; l < 32; l++) {
2046 enum winreg_Type w_type;
2047 uint32_t w_size, w_length;
2054 data = talloc_array(tctx, uint8_t, size);
2056 generate_random_buffer(data, size);
2058 torture_assert(tctx,
2059 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2060 "test_SetValue failed");
2062 torture_assert(tctx,
2063 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2064 "test_winreg_QueryValue failed");
2066 torture_assert(tctx,
2067 test_DeleteValue(b, tctx, handle, value_name),
2068 "test_DeleteValue failed");
2070 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2071 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2072 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2073 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2077 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2082 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2083 #define VALUE_CURRENT_VERSION "CurrentVersion"
2085 static bool test_HKLM_wellknown(struct torture_context *tctx,
2086 struct dcerpc_binding_handle *b,
2087 struct policy_handle *handle)
2089 struct policy_handle newhandle;
2091 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2092 if (torture_setting_bool(tctx, "samba3", false)) {
2093 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2094 KEY_CURRENT_VERSION,
2095 REG_KEYTYPE_NON_VOLATILE,
2099 "failed to open current version key");
2101 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2102 "failed to open current version key");
2105 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2106 "failed to query current version");
2107 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2108 "failed to query current version");
2109 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2110 "test_QueryValue_full for NULL value failed");
2111 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2112 "test_QueryValue_full for \"\" value failed");
2114 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2115 "failed to close current version key");
2120 static bool test_volatile_keys(struct torture_context *tctx,
2121 struct dcerpc_binding_handle *b,
2122 struct policy_handle *handle)
2124 struct policy_handle new_handle;
2125 enum winreg_CreateAction action_taken;
2127 torture_comment(tctx, "Testing REG_KEYTYPE_VOLATILE key\n");
2129 torture_assert(tctx,
2130 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2131 REG_KEYTYPE_VOLATILE,
2132 SEC_FLAG_MAXIMUM_ALLOWED,
2137 "failed to create REG_KEYTYPE_VOLATILE type key");
2139 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2141 torture_assert(tctx,
2142 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2143 REG_KEYTYPE_NON_VOLATILE,
2144 SEC_FLAG_MAXIMUM_ALLOWED,
2146 WERR_CHILD_MUST_BE_VOLATILE,
2149 "failed to fail create REG_KEYTYPE_VOLATILE type key");
2151 torture_assert(tctx,
2152 test_CloseKey(b, tctx, &new_handle),
2155 torture_assert(tctx,
2156 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2157 REG_KEYTYPE_NON_VOLATILE,
2158 SEC_FLAG_MAXIMUM_ALLOWED,
2161 "failed to open volatile key");
2163 torture_assert(tctx,
2164 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2165 "failed to delete key");
2167 torture_assert(tctx,
2168 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2169 REG_KEYTYPE_VOLATILE,
2170 SEC_FLAG_MAXIMUM_ALLOWED,
2175 "failed to create REG_KEYTYPE_VOLATILE type key");
2177 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2179 torture_assert(tctx,
2180 test_CloseKey(b, tctx, &new_handle),
2183 torture_assert(tctx,
2184 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2185 REG_KEYTYPE_VOLATILE,
2186 SEC_FLAG_MAXIMUM_ALLOWED,
2189 "failed to open volatile key");
2191 torture_assert(tctx,
2192 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2193 "failed to delete key");
2195 torture_assert(tctx,
2196 test_CloseKey(b, tctx, &new_handle),
2202 static bool test_symlink_keys(struct torture_context *tctx,
2203 struct dcerpc_binding_handle *b,
2204 struct policy_handle *handle)
2206 struct policy_handle new_handle;
2207 enum winreg_CreateAction action_taken;
2209 /* symlink destination needs to be a kernel mode registry path */
2210 const char *dest = "\\Registry\\MACHINE\\SOFTWARE\\foo";
2212 /* disable until we know how to *not* screw up a windows registry */
2213 torture_skip(tctx, "symlink test disabled");
2215 torture_comment(tctx, "Testing REG_KEYTYPE_SYMLINK key\n");
2217 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2219 torture_assert(tctx,
2220 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2221 REG_KEYTYPE_SYMLINK | REG_KEYTYPE_VOLATILE,
2222 SEC_FLAG_MAXIMUM_ALLOWED,
2227 "failed to create REG_KEYTYPE_SYMLINK type key");
2229 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2231 torture_assert(tctx,
2232 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2233 dest, strlen(dest), /* not NULL terminated */
2234 &blob.data, &blob.length,
2236 "failed to convert");
2238 torture_assert(tctx,
2239 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2240 "failed to create SymbolicLinkValue value");
2242 torture_assert(tctx,
2243 test_CloseKey(b, tctx, &new_handle),
2246 torture_assert(tctx,
2247 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2248 REG_KEYTYPE_SYMLINK | REG_KEYTYPE_VOLATILE,
2249 SEC_FLAG_MAXIMUM_ALLOWED,
2252 "failed to open symlink key");
2254 torture_assert(tctx,
2255 test_DeleteKey(b, tctx, &new_handle, TEST_KEY_SYMLINK),
2256 "failed to delete key");
2261 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2262 struct dcerpc_binding_handle *b,
2263 struct policy_handle *handle)
2266 if (torture_setting_bool(tctx, "samba3", false) ||
2267 torture_setting_bool(tctx, "samba4", false)) {
2268 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2271 torture_assert(tctx,
2272 test_volatile_keys(tctx, b, handle),
2273 "failed to test volatile keys");
2275 torture_assert(tctx,
2276 test_symlink_keys(tctx, b, handle),
2277 "failed to test symlink keys");
2282 static bool test_key_base(struct torture_context *tctx,
2283 struct dcerpc_binding_handle *b,
2284 struct policy_handle *handle)
2286 struct policy_handle newhandle;
2287 bool ret = true, created = false, deleted = false;
2288 bool created3 = false;
2290 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2292 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2293 torture_comment(tctx,
2294 "CreateKey (TEST_KEY_BASE) failed\n");
2297 if (!test_CreateKey(b, tctx, handle, TEST_KEY1, NULL)) {
2298 torture_comment(tctx,
2299 "CreateKey failed - not considering a failure\n");
2305 if (!test_FlushKey(b, tctx, handle)) {
2306 torture_comment(tctx, "FlushKey failed\n");
2310 if (!test_OpenKey(b, tctx, handle, TEST_KEY1, &newhandle)) {
2312 "CreateKey failed (OpenKey after Create didn't work)\n");
2315 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2316 "simple SetValue test failed");
2317 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2318 "extended SetValue test failed");
2319 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle),
2320 "keytype test failed");
2322 if (!test_CloseKey(b, tctx, &newhandle)) {
2324 "CreateKey failed (CloseKey after Open didn't work)\n");
2327 if (!test_DeleteKey(b, tctx, handle, TEST_KEY1)) {
2328 torture_comment(tctx, "DeleteKey failed\n");
2334 if (!test_FlushKey(b, tctx, handle)) {
2335 torture_comment(tctx, "FlushKey failed\n");
2340 if (!test_OpenKey_opts(tctx, b, handle, TEST_KEY1,
2341 REG_KEYTYPE_NON_VOLATILE,
2342 SEC_FLAG_MAXIMUM_ALLOWED,
2345 torture_comment(tctx,
2346 "DeleteKey failed (OpenKey after Delete "
2347 "did not return WERR_BADFILE)\n");
2352 if (test_CreateKey(b, tctx, handle, TEST_KEY3, NULL)) {
2357 if (test_CreateKey(b, tctx, handle, TEST_SUBKEY, NULL)) {
2358 if (!test_DeleteKey(b, tctx, handle, TEST_SUBKEY)) {
2359 torture_comment(tctx, "DeleteKey failed\n");
2364 if (!test_DeleteKey(b, tctx, handle, TEST_KEY3)) {
2365 torture_comment(tctx, "DeleteKey failed\n");
2371 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2376 static bool test_key_base_sd(struct torture_context *tctx,
2377 struct dcerpc_pipe *p,
2378 struct policy_handle *handle)
2380 struct policy_handle newhandle;
2381 bool ret = true, created2 = false, created4 = false;
2382 struct dcerpc_binding_handle *b = p->binding_handle;
2384 if (torture_setting_bool(tctx, "samba3", false) ||
2385 torture_setting_bool(tctx, "samba4", false)) {
2386 torture_skip(tctx, "skipping security descriptor tests against Samba");
2389 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2391 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2392 torture_comment(tctx,
2393 "CreateKey (TEST_KEY_BASE) failed\n");
2396 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY2,
2397 NULL, &newhandle)) {
2401 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2402 torture_comment(tctx, "CloseKey failed\n");
2406 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY4, NULL, &newhandle)) {
2410 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2411 torture_comment(tctx, "CloseKey failed\n");
2415 if (created4 && !test_SecurityDescriptors(p, tctx, handle, TEST_KEY4)) {
2419 if (created4 && !test_DeleteKey(b, tctx, handle, TEST_KEY4)) {
2420 torture_comment(tctx, "DeleteKey failed\n");
2424 if (created2 && !test_DeleteKey(b, tctx, handle, TEST_KEY2)) {
2425 torture_comment(tctx, "DeleteKey failed\n");
2429 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2434 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2437 struct policy_handle handle;
2439 struct winreg_OpenHKLM r;
2440 struct dcerpc_binding_handle *b = p->binding_handle;
2442 winreg_open_fn open_fn = userdata;
2444 r.in.system_name = 0;
2445 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2446 r.out.handle = &handle;
2448 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2451 if (!test_GetVersion(b, tctx, &handle)) {
2452 torture_comment(tctx, "GetVersion failed\n");
2456 if (open_fn == (void *)dcerpc_winreg_OpenHKLM_r) {
2457 torture_assert(tctx,
2458 test_HKLM_wellknown(tctx, b, &handle),
2459 "failed to test HKLM wellknown keys");
2462 if (!test_key_base(tctx, b, &handle)) {
2463 torture_warning(tctx, "failed to test TEST_KEY_BASE");
2467 if (!test_key_base_sd(tctx, p, &handle)) {
2468 torture_warning(tctx, "failed to test TEST_KEY_BASE sd");
2472 /* The HKCR hive has a very large fanout */
2473 if (open_fn == (void *)dcerpc_winreg_OpenHKCR_r) {
2474 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2478 if (!test_key(p, tctx, &handle, 0, false)) {
2486 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2488 struct torture_rpc_tcase *tcase;
2489 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2490 struct torture_test *test;
2492 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2495 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2496 test_InitiateSystemShutdown);
2497 test->dangerous = true;
2499 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2500 test_InitiateSystemShutdownEx);
2501 test->dangerous = true;
2503 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2505 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2506 torture_rpc_tcase_add_test_ex(tcase, "HKU",
2508 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2509 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2511 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2512 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2514 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);