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/torture_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_OPTION_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_OPTION_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_OPTION_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_OPTION_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_OPTION_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;
1607 r.in.key_handle = handle;
1608 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1609 r.in.values[0].name = talloc(tctx, struct winreg_String);
1610 r.in.values[0].name->name = valuename;
1611 r.in.values[0].offset = 0;
1612 r.in.values[0].length = 0;
1613 r.in.values[0].type = 0;
1615 r.in.num_values = 1;
1616 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1617 *r.in.buffer_size = bufsize;
1619 *r.in.buffer_size = bufsize;
1620 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1623 torture_assert_ntstatus_ok(tctx,
1624 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1625 "QueryMultipleValues failed");
1627 talloc_free(r.in.buffer);
1629 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1631 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1636 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1637 struct torture_context *tctx,
1638 struct policy_handle *handle,
1639 const char *valuename)
1641 struct winreg_QueryValue r;
1643 enum winreg_Type zero_type = 0;
1644 uint32_t offered = 0xfff;
1648 r.in.handle = handle;
1650 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1651 r.in.value_name->name = valuename;
1652 r.in.type = &zero_type;
1653 r.in.data_size = &offered;
1654 r.in.data_length = &zero;
1656 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1657 if (NT_STATUS_IS_ERR(status)) {
1658 torture_fail(tctx, "QueryValue failed");
1661 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1666 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1667 struct torture_context *tctx,
1668 struct policy_handle *handle,
1669 const char *valuename,
1670 bool existing_value)
1672 struct winreg_QueryValue r;
1673 struct winreg_String value_name;
1674 enum winreg_Type type = REG_NONE;
1675 uint32_t data_size = 0;
1676 uint32_t real_data_size = 0;
1677 uint32_t data_length = 0;
1678 uint8_t *data = NULL;
1679 WERROR expected_error = WERR_BADFILE;
1681 if (valuename == NULL) {
1682 expected_error = WERR_INVALID_PARAM;
1687 init_winreg_String(&value_name, NULL);
1689 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1691 r.in.handle = handle;
1692 r.in.value_name = &value_name;
1694 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1695 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1696 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1698 init_winreg_String(&value_name, valuename);
1699 r.in.value_name = &value_name;
1701 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1702 "QueryValue failed");
1703 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1704 "QueryValue failed");
1708 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1709 "QueryValue failed");
1710 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1711 "QueryValue failed");
1713 r.in.data_length = &data_length;
1714 r.out.data_length = &data_length;
1715 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1716 "QueryValue failed");
1717 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1718 "QueryValue failed");
1720 r.in.data_size = &data_size;
1721 r.out.data_size = &data_size;
1722 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1723 "QueryValue failed");
1724 if (existing_value) {
1725 torture_assert_werr_ok(tctx, r.out.result,
1726 "QueryValue failed");
1728 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1729 "QueryValue failed");
1732 real_data_size = *r.out.data_size;
1734 data = talloc_zero_array(tctx, uint8_t, 0);
1737 *r.in.data_size = 0;
1738 *r.out.data_size = 0;
1739 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1740 "QueryValue failed");
1741 if (existing_value) {
1742 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1743 "QueryValue failed");
1745 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1746 "QueryValue failed");
1749 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1752 r.in.data_size = &real_data_size;
1753 r.out.data_size = &real_data_size;
1754 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1755 "QueryValue failed");
1756 if (existing_value) {
1757 torture_assert_werr_ok(tctx, r.out.result,
1758 "QueryValue failed");
1760 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1761 "QueryValue failed");
1767 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1768 struct torture_context *tctx,
1769 struct policy_handle *handle, int max_valnamelen,
1772 struct winreg_EnumValue r;
1773 enum winreg_Type type = 0;
1774 uint32_t size = max_valbufsize, zero = 0;
1777 struct winreg_ValNameBuf name;
1783 r.in.handle = handle;
1784 r.in.enum_index = 0;
1789 r.in.length = &zero;
1793 torture_assert_ntstatus_ok(tctx,
1794 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1795 "EnumValue failed");
1797 if (W_ERROR_IS_OK(r.out.result)) {
1798 ret &= test_QueryValue(b, tctx, handle,
1800 ret &= test_QueryMultipleValues(b, tctx, handle,
1805 } while (W_ERROR_IS_OK(r.out.result));
1807 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1808 "EnumValue failed");
1813 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1814 struct torture_context *tctx)
1816 struct winreg_AbortSystemShutdown r;
1817 uint16_t server = 0x0;
1820 r.in.server = &server;
1822 torture_assert_ntstatus_ok(tctx,
1823 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1824 "AbortSystemShutdown failed");
1826 torture_assert_werr_ok(tctx, r.out.result,
1827 "AbortSystemShutdown failed");
1832 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1833 struct dcerpc_pipe *p)
1835 struct winreg_InitiateSystemShutdown r;
1836 uint16_t hostname = 0x0;
1837 struct dcerpc_binding_handle *b = p->binding_handle;
1840 r.in.hostname = &hostname;
1841 r.in.message = talloc(tctx, struct lsa_StringLarge);
1842 init_lsa_StringLarge(r.in.message, "spottyfood");
1843 r.in.force_apps = 1;
1847 torture_assert_ntstatus_ok(tctx,
1848 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1849 "InitiateSystemShutdown failed");
1851 torture_assert_werr_ok(tctx, r.out.result,
1852 "InitiateSystemShutdown failed");
1854 return test_AbortSystemShutdown(b, tctx);
1858 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1859 struct dcerpc_pipe *p)
1861 struct winreg_InitiateSystemShutdownEx r;
1862 uint16_t hostname = 0x0;
1863 struct dcerpc_binding_handle *b = p->binding_handle;
1866 r.in.hostname = &hostname;
1867 r.in.message = talloc(tctx, struct lsa_StringLarge);
1868 init_lsa_StringLarge(r.in.message, "spottyfood");
1869 r.in.force_apps = 1;
1874 torture_assert_ntstatus_ok(tctx,
1875 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1876 "InitiateSystemShutdownEx failed");
1878 torture_assert_werr_ok(tctx, r.out.result,
1879 "InitiateSystemShutdownEx failed");
1881 return test_AbortSystemShutdown(b, tctx);
1883 #define MAX_DEPTH 2 /* Only go this far down the tree */
1885 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1886 struct policy_handle *handle, int depth,
1889 struct dcerpc_binding_handle *b = p->binding_handle;
1891 if (depth == MAX_DEPTH)
1894 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1897 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1900 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1903 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1906 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1909 test_CloseKey(b, tctx, handle);
1914 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1915 struct torture_context *tctx,
1916 struct policy_handle *handle)
1918 const char *value_name = TEST_VALUE;
1919 uint32_t value = 0x12345678;
1920 uint64_t value2 = 0x12345678;
1921 const char *string = "torture";
1923 enum winreg_Type types[] = {
1925 REG_DWORD_BIG_ENDIAN,
1933 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1935 for (t=0; t < ARRAY_SIZE(types); t++) {
1937 enum winreg_Type w_type;
1938 uint32_t w_size, w_length;
1943 case REG_DWORD_BIG_ENDIAN:
1944 blob = data_blob_talloc_zero(tctx, 4);
1945 SIVAL(blob.data, 0, value);
1948 blob = data_blob_talloc_zero(tctx, 8);
1949 SBVAL(blob.data, 0, value2);
1952 blob = data_blob_string_const("binary_blob");
1955 torture_assert(tctx,
1956 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1960 (void **)&blob.data,
1965 torture_assert(tctx,
1966 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1970 (void **)&blob.data,
1973 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1974 memset(&blob.data[blob.length - 2], '\0', 2);
1980 torture_assert(tctx,
1981 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1982 "test_SetValue failed");
1983 torture_assert(tctx,
1984 test_QueryValue_full(b, tctx, handle, value_name, true),
1985 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1986 torture_assert(tctx,
1987 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1988 "test_winreg_QueryValue failed");
1989 torture_assert(tctx,
1990 test_DeleteValue(b, tctx, handle, value_name),
1991 "test_DeleteValue failed");
1993 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1994 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1995 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1996 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1999 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2004 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2006 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2007 struct torture_context *tctx,
2008 struct policy_handle *handle)
2010 const char *value_name = TEST_VALUE;
2011 enum winreg_Type types[] = {
2017 REG_DWORD_BIG_ENDIAN,
2021 REG_FULL_RESOURCE_DESCRIPTOR,
2022 REG_RESOURCE_REQUIREMENTS_LIST,
2034 if (torture_setting_bool(tctx, "samba3", false) ||
2035 torture_setting_bool(tctx, "samba4", false)) {
2036 torture_skip(tctx, "skipping extended SetValue test against Samba");
2039 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2041 for (t=0; t < ARRAY_SIZE(types); t++) {
2042 for (l=0; l < 32; l++) {
2044 enum winreg_Type w_type;
2045 uint32_t w_size, w_length;
2052 data = talloc_array(tctx, uint8_t, size);
2054 generate_random_buffer(data, size);
2056 torture_assert(tctx,
2057 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2058 "test_SetValue failed");
2060 torture_assert(tctx,
2061 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2062 "test_winreg_QueryValue failed");
2064 torture_assert(tctx,
2065 test_DeleteValue(b, tctx, handle, value_name),
2066 "test_DeleteValue failed");
2068 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2069 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2070 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2071 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2075 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2080 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2081 #define VALUE_CURRENT_VERSION "CurrentVersion"
2083 static bool test_HKLM_wellknown(struct torture_context *tctx,
2084 struct dcerpc_binding_handle *b,
2085 struct policy_handle *handle)
2087 struct policy_handle newhandle;
2089 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2090 if (torture_setting_bool(tctx, "samba3", false)) {
2091 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2092 KEY_CURRENT_VERSION,
2093 REG_OPTION_NON_VOLATILE,
2097 "failed to open current version key");
2099 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2100 "failed to open current version key");
2103 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2104 "failed to query current version");
2105 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2106 "failed to query current version");
2107 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2108 "test_QueryValue_full for NULL value failed");
2109 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2110 "test_QueryValue_full for \"\" value failed");
2112 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2113 "failed to close current version key");
2118 static bool test_volatile_keys(struct torture_context *tctx,
2119 struct dcerpc_binding_handle *b,
2120 struct policy_handle *handle)
2122 struct policy_handle new_handle;
2123 enum winreg_CreateAction action_taken;
2125 torture_comment(tctx, "Testing REG_OPTION_VOLATILE key\n");
2127 torture_assert(tctx,
2128 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2129 REG_OPTION_VOLATILE,
2130 SEC_FLAG_MAXIMUM_ALLOWED,
2135 "failed to create REG_OPTION_VOLATILE type key");
2137 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2139 torture_assert(tctx,
2140 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2141 REG_OPTION_NON_VOLATILE,
2142 SEC_FLAG_MAXIMUM_ALLOWED,
2144 WERR_CHILD_MUST_BE_VOLATILE,
2147 "failed to fail create REG_OPTION_VOLATILE type key");
2149 torture_assert(tctx,
2150 test_CloseKey(b, tctx, &new_handle),
2153 torture_assert(tctx,
2154 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2155 REG_OPTION_NON_VOLATILE,
2156 SEC_FLAG_MAXIMUM_ALLOWED,
2159 "failed to open volatile key");
2161 torture_assert(tctx,
2162 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2163 "failed to delete key");
2165 torture_assert(tctx,
2166 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2167 REG_OPTION_VOLATILE,
2168 SEC_FLAG_MAXIMUM_ALLOWED,
2173 "failed to create REG_OPTION_VOLATILE type key");
2175 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2177 torture_assert(tctx,
2178 test_CloseKey(b, tctx, &new_handle),
2181 torture_assert(tctx,
2182 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2183 REG_OPTION_VOLATILE,
2184 SEC_FLAG_MAXIMUM_ALLOWED,
2187 "failed to open volatile key");
2189 torture_assert(tctx,
2190 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2191 "failed to delete key");
2193 torture_assert(tctx,
2194 test_CloseKey(b, tctx, &new_handle),
2200 static bool test_symlink_keys(struct torture_context *tctx,
2201 struct dcerpc_binding_handle *b,
2202 struct policy_handle *handle)
2204 struct policy_handle new_handle;
2205 enum winreg_CreateAction action_taken;
2207 /* symlink destination needs to be a kernel mode registry path */
2208 const char *dest = "\\Registry\\MACHINE\\SOFTWARE\\foo";
2210 /* disable until we know how to *not* screw up a windows registry */
2211 torture_skip(tctx, "symlink test disabled");
2213 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2215 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2217 torture_assert(tctx,
2218 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2219 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2220 SEC_FLAG_MAXIMUM_ALLOWED,
2225 "failed to create REG_OPTION_CREATE_LINK type key");
2227 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2229 torture_assert(tctx,
2230 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2231 dest, strlen(dest), /* not NULL terminated */
2232 &blob.data, &blob.length,
2234 "failed to convert");
2236 torture_assert(tctx,
2237 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2238 "failed to create SymbolicLinkValue value");
2240 torture_assert(tctx,
2241 test_CloseKey(b, tctx, &new_handle),
2244 torture_assert(tctx,
2245 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2246 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2247 SEC_FLAG_MAXIMUM_ALLOWED,
2250 "failed to open symlink key");
2252 torture_assert(tctx,
2253 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK),
2254 "failed to delete key");
2259 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2260 struct dcerpc_binding_handle *b,
2261 struct policy_handle *handle)
2264 if (torture_setting_bool(tctx, "samba3", false) ||
2265 torture_setting_bool(tctx, "samba4", false)) {
2266 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2269 torture_assert(tctx,
2270 test_volatile_keys(tctx, b, handle),
2271 "failed to test volatile keys");
2273 torture_assert(tctx,
2274 test_symlink_keys(tctx, b, handle),
2275 "failed to test symlink keys");
2280 static bool test_key_base(struct torture_context *tctx,
2281 struct dcerpc_binding_handle *b,
2282 struct policy_handle *handle)
2284 struct policy_handle newhandle;
2285 bool ret = true, created = false, deleted = false;
2286 bool created3 = false;
2288 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2290 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2291 torture_comment(tctx,
2292 "CreateKey (TEST_KEY_BASE) failed\n");
2295 if (!test_CreateKey(b, tctx, handle, TEST_KEY1, NULL)) {
2296 torture_comment(tctx,
2297 "CreateKey failed - not considering a failure\n");
2303 if (!test_FlushKey(b, tctx, handle)) {
2304 torture_comment(tctx, "FlushKey failed\n");
2308 if (!test_OpenKey(b, tctx, handle, TEST_KEY1, &newhandle)) {
2310 "CreateKey failed (OpenKey after Create didn't work)\n");
2313 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2314 "simple SetValue test failed");
2315 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2316 "extended SetValue test failed");
2317 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle),
2318 "keytype test failed");
2320 if (!test_CloseKey(b, tctx, &newhandle)) {
2322 "CreateKey failed (CloseKey after Open didn't work)\n");
2325 if (!test_DeleteKey(b, tctx, handle, TEST_KEY1)) {
2326 torture_comment(tctx, "DeleteKey failed\n");
2332 if (!test_FlushKey(b, tctx, handle)) {
2333 torture_comment(tctx, "FlushKey failed\n");
2338 if (!test_OpenKey_opts(tctx, b, handle, TEST_KEY1,
2339 REG_OPTION_NON_VOLATILE,
2340 SEC_FLAG_MAXIMUM_ALLOWED,
2343 torture_comment(tctx,
2344 "DeleteKey failed (OpenKey after Delete "
2345 "did not return WERR_BADFILE)\n");
2350 if (test_CreateKey(b, tctx, handle, TEST_KEY3, NULL)) {
2355 if (test_CreateKey(b, tctx, handle, TEST_SUBKEY, NULL)) {
2356 if (!test_DeleteKey(b, tctx, handle, TEST_SUBKEY)) {
2357 torture_comment(tctx, "DeleteKey failed\n");
2362 if (!test_DeleteKey(b, tctx, handle, TEST_KEY3)) {
2363 torture_comment(tctx, "DeleteKey failed\n");
2369 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2374 static bool test_key_base_sd(struct torture_context *tctx,
2375 struct dcerpc_pipe *p,
2376 struct policy_handle *handle)
2378 struct policy_handle newhandle;
2379 bool ret = true, created2 = false, created4 = false;
2380 struct dcerpc_binding_handle *b = p->binding_handle;
2382 if (torture_setting_bool(tctx, "samba3", false) ||
2383 torture_setting_bool(tctx, "samba4", false)) {
2384 torture_skip(tctx, "skipping security descriptor tests against Samba");
2387 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2389 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2390 torture_comment(tctx,
2391 "CreateKey (TEST_KEY_BASE) failed\n");
2394 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY2,
2395 NULL, &newhandle)) {
2399 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2400 torture_comment(tctx, "CloseKey failed\n");
2404 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY4, NULL, &newhandle)) {
2408 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2409 torture_comment(tctx, "CloseKey failed\n");
2413 if (created4 && !test_SecurityDescriptors(p, tctx, handle, TEST_KEY4)) {
2417 if (created4 && !test_DeleteKey(b, tctx, handle, TEST_KEY4)) {
2418 torture_comment(tctx, "DeleteKey failed\n");
2422 if (created2 && !test_DeleteKey(b, tctx, handle, TEST_KEY2)) {
2423 torture_comment(tctx, "DeleteKey failed\n");
2427 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2432 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2435 struct policy_handle handle;
2437 struct winreg_OpenHKLM r;
2438 struct dcerpc_binding_handle *b = p->binding_handle;
2440 winreg_open_fn open_fn = (winreg_open_fn)userdata;
2442 r.in.system_name = 0;
2443 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2444 r.out.handle = &handle;
2446 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2449 if (!test_GetVersion(b, tctx, &handle)) {
2450 torture_comment(tctx, "GetVersion failed\n");
2454 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
2455 torture_assert(tctx,
2456 test_HKLM_wellknown(tctx, b, &handle),
2457 "failed to test HKLM wellknown keys");
2460 if (!test_key_base(tctx, b, &handle)) {
2461 torture_warning(tctx, "failed to test TEST_KEY_BASE");
2465 if (!test_key_base_sd(tctx, p, &handle)) {
2466 torture_warning(tctx, "failed to test TEST_KEY_BASE sd");
2470 /* The HKCR hive has a very large fanout */
2471 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
2472 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2476 if (!test_key(p, tctx, &handle, 0, false)) {
2484 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2486 struct torture_rpc_tcase *tcase;
2487 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2488 struct torture_test *test;
2490 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2493 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2494 test_InitiateSystemShutdown);
2495 test->dangerous = true;
2497 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2498 test_InitiateSystemShutdownEx);
2499 test->dangerous = true;
2501 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2503 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2504 torture_rpc_tcase_add_test_ex(tcase, "HKU",
2506 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2507 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2509 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2510 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2512 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);