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,2010
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 "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "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
, 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
, 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
, 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
;
835 const char *test_subkey_sd
;
836 const char *test_subsubkey_sd
;
838 torture_comment(tctx
, "SecurityDescriptor inheritance\n");
840 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
844 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
848 sd_orig
= security_descriptor_copy(tctx
, sd
);
849 if (sd_orig
== NULL
) {
853 ace
= security_ace_create(tctx
,
855 SEC_ACE_TYPE_ACCESS_ALLOWED
,
857 SEC_ACE_FLAG_CONTAINER_INHERIT
);
859 torture_assert_ntstatus_ok(tctx
,
860 security_descriptor_dacl_add(sd
, ace
),
861 "failed to add ace");
863 /* FIXME: add further tests for these flags */
864 sd
->type
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
|
865 SEC_DESC_SACL_AUTO_INHERITED
;
867 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
872 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
873 "new ACE not present!");
875 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
879 test_subkey_sd
= talloc_asprintf(tctx
, "%s\\%s", key
, TEST_SUBKEY_SD
);
881 if (!test_CreateKey(b
, tctx
, handle
, test_subkey_sd
, NULL
)) {
886 if (!test_OpenKey(b
, tctx
, handle
, test_subkey_sd
, &new_handle
)) {
891 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
892 torture_comment(tctx
, "inherited ACE not present!\n");
897 test_subsubkey_sd
= talloc_asprintf(tctx
, "%s\\%s", key
, TEST_SUBSUBKEY_SD
);
899 test_CloseKey(b
, tctx
, &new_handle
);
900 if (!test_CreateKey(b
, tctx
, handle
, test_subsubkey_sd
, NULL
)) {
905 if (!test_OpenKey(b
, tctx
, handle
, test_subsubkey_sd
, &new_handle
)) {
910 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
911 torture_comment(tctx
, "inherited ACE not present!\n");
917 test_CloseKey(b
, tctx
, &new_handle
);
918 test_Cleanup(b
, tctx
, handle
, test_subkey_sd
);
919 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
924 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe
*p
,
925 struct torture_context
*tctx
,
926 struct policy_handle
*handle
,
930 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
942 struct security_descriptor
*sd
= NULL
;
943 struct security_descriptor
*sd_orig
= NULL
;
944 struct security_ace
*ace
= NULL
;
945 struct policy_handle new_handle
;
946 struct dom_sid
*sid
= NULL
;
948 uint8_t ace_flags
= 0x0;
949 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
950 const char *test_subkey_sd
;
951 const char *test_subsubkey_sd
;
953 torture_comment(tctx
, "SecurityDescriptor inheritance block\n");
955 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
959 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
963 sd_orig
= security_descriptor_copy(tctx
, sd
);
964 if (sd_orig
== NULL
) {
968 ace
= security_ace_create(tctx
,
970 SEC_ACE_TYPE_ACCESS_ALLOWED
,
972 SEC_ACE_FLAG_CONTAINER_INHERIT
|
973 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
);
975 torture_assert_ntstatus_ok(tctx
,
976 security_descriptor_dacl_add(sd
, ace
),
977 "failed to add ace");
979 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, NULL
, sd
, WERR_OK
)) {
984 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
985 "new ACE not present!");
987 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
991 test_subkey_sd
= talloc_asprintf(tctx
, "%s\\%s", key
, TEST_SUBKEY_SD
);
992 test_subsubkey_sd
= talloc_asprintf(tctx
, "%s\\%s", key
, TEST_SUBSUBKEY_SD
);
994 if (!test_CreateKey(b
, tctx
, handle
, test_subsubkey_sd
, NULL
)) {
998 if (!test_OpenKey(b
, tctx
, handle
, test_subsubkey_sd
, &new_handle
)) {
1003 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
1004 torture_comment(tctx
, "inherited ACE present but should not!\n");
1009 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1014 if (test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
)) {
1015 torture_comment(tctx
, "inherited trustee SID present but should not!\n");
1020 test_CloseKey(b
, tctx
, &new_handle
);
1022 if (!test_OpenKey(b
, tctx
, handle
, test_subkey_sd
, &new_handle
)) {
1027 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
1028 torture_comment(tctx
, "inherited ACE present but should not!\n");
1033 if (!test_dacl_trustee_flags_present(p
, tctx
, &new_handle
, sid
, ace_flags
)) {
1034 torture_comment(tctx
, "inherited trustee SID with flags 0x%02x not present!\n",
1041 test_CloseKey(b
, tctx
, &new_handle
);
1042 test_Cleanup(b
, tctx
, handle
, test_subkey_sd
);
1043 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1048 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe
*p
,
1049 struct torture_context
*tctx
,
1050 struct policy_handle
*handle
,
1056 struct winreg_mask_result_table
{
1057 uint32_t access_mask
;
1061 } sd_mask_tests
[] = {
1063 WERR_ACCESS_DENIED
, WERR_BADFILE
, WERR_FOOBAR
},
1064 { SEC_FLAG_MAXIMUM_ALLOWED
,
1065 WERR_OK
, WERR_OK
, WERR_OK
},
1066 { SEC_STD_WRITE_DAC
,
1067 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
},
1068 { SEC_FLAG_SYSTEM_SECURITY
,
1069 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
}
1072 /* FIXME: before this test can ever run successfully we need a way to
1073 * correctly read a NULL security_descritpor in ndr, get the required
1074 * length, requery, etc.
1079 for (i
=0; i
< ARRAY_SIZE(sd_mask_tests
); i
++) {
1081 torture_comment(tctx
,
1082 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1083 sd_mask_tests
[i
].access_mask
);
1084 torture_comment(tctx
,
1085 "expecting: open %s, get: %s, set: %s\n",
1086 win_errstr(sd_mask_tests
[i
].open_werr
),
1087 win_errstr(sd_mask_tests
[i
].get_werr
),
1088 win_errstr(sd_mask_tests
[i
].set_werr
));
1090 if (_test_SecurityDescriptor(p
, tctx
, handle
,
1091 sd_mask_tests
[i
].access_mask
, key
,
1092 sd_mask_tests
[i
].open_werr
,
1093 sd_mask_tests
[i
].get_werr
,
1094 sd_mask_tests
[i
].set_werr
)) {
1102 typedef bool (*secinfo_verify_fn
)(struct dcerpc_pipe
*,
1103 struct torture_context
*,
1104 struct policy_handle
*,
1106 const struct dom_sid
*);
1108 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe
*p
,
1109 struct torture_context
*tctx
,
1110 struct policy_handle
*handle
,
1113 uint32_t access_mask
,
1115 struct security_descriptor
*sd
,
1117 bool expect_present
,
1118 bool (*fn
) (struct dcerpc_pipe
*,
1119 struct torture_context
*,
1120 struct policy_handle
*,
1122 const struct dom_sid
*),
1123 const struct dom_sid
*sid
)
1125 struct policy_handle new_handle
;
1126 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1128 torture_comment(tctx
, "SecurityDescriptor (%s) sets for secinfo: "
1129 "0x%08x, access_mask: 0x%08x\n",
1130 test
, sec_info
, access_mask
);
1132 torture_assert(tctx
,
1133 test_OpenKey_opts(tctx
, b
, handle
, key
,
1134 REG_OPTION_NON_VOLATILE
,
1138 "failed to open key");
1140 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, &sec_info
,
1143 torture_warning(tctx
,
1144 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1147 test_CloseKey(b
, tctx
, &new_handle
);
1151 test_CloseKey(b
, tctx
, &new_handle
);
1153 if (W_ERROR_IS_OK(set_werr
)) {
1155 present
= fn(p
, tctx
, handle
, key
, sid
);
1156 if ((expect_present
) && (!present
)) {
1157 torture_warning(tctx
,
1158 "%s sid is not present!\n",
1162 if ((!expect_present
) && (present
)) {
1163 torture_warning(tctx
,
1164 "%s sid is present but not expected!\n",
1173 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe
*p
,
1174 struct torture_context
*tctx
,
1175 struct policy_handle
*handle
,
1178 struct security_descriptor
*sd_orig
= NULL
;
1179 struct dom_sid
*sid
= NULL
;
1183 struct security_descriptor
*sd_owner
=
1184 security_descriptor_dacl_create(tctx
,
1186 TEST_SID
, NULL
, NULL
);
1188 struct security_descriptor
*sd_group
=
1189 security_descriptor_dacl_create(tctx
,
1191 NULL
, TEST_SID
, NULL
);
1193 struct security_descriptor
*sd_dacl
=
1194 security_descriptor_dacl_create(tctx
,
1198 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1201 SID_NT_AUTHENTICATED_USERS
,
1202 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1207 struct security_descriptor
*sd_sacl
=
1208 security_descriptor_sacl_create(tctx
,
1212 SEC_ACE_TYPE_SYSTEM_AUDIT
,
1214 SEC_ACE_FLAG_SUCCESSFUL_ACCESS
,
1217 struct winreg_secinfo_table
{
1218 struct security_descriptor
*sd
;
1222 secinfo_verify_fn fn
;
1225 struct winreg_secinfo_table sec_info_owner_tests
[] = {
1226 { sd_owner
, 0, WERR_OK
,
1227 false, (secinfo_verify_fn
)_test_owner_present
},
1228 { sd_owner
, SECINFO_OWNER
, WERR_OK
,
1229 true, (secinfo_verify_fn
)_test_owner_present
},
1230 { sd_owner
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1231 { sd_owner
, SECINFO_DACL
, WERR_OK
,
1232 true, (secinfo_verify_fn
)_test_owner_present
},
1233 { sd_owner
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1236 uint32_t sd_owner_good_access_masks
[] = {
1237 SEC_FLAG_MAXIMUM_ALLOWED
,
1238 /* SEC_STD_WRITE_OWNER, */
1241 struct winreg_secinfo_table sec_info_group_tests
[] = {
1242 { sd_group
, 0, WERR_OK
,
1243 false, (secinfo_verify_fn
)_test_group_present
},
1244 { sd_group
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1245 { sd_group
, SECINFO_GROUP
, WERR_OK
,
1246 true, (secinfo_verify_fn
)_test_group_present
},
1247 { sd_group
, SECINFO_DACL
, WERR_OK
,
1248 true, (secinfo_verify_fn
)_test_group_present
},
1249 { sd_group
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1252 uint32_t sd_group_good_access_masks
[] = {
1253 SEC_FLAG_MAXIMUM_ALLOWED
,
1256 struct winreg_secinfo_table sec_info_dacl_tests
[] = {
1257 { sd_dacl
, 0, WERR_OK
,
1258 false, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1259 { sd_dacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1260 { sd_dacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1261 { sd_dacl
, SECINFO_DACL
, WERR_OK
,
1262 true, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1263 { sd_dacl
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1266 uint32_t sd_dacl_good_access_masks
[] = {
1267 SEC_FLAG_MAXIMUM_ALLOWED
,
1271 struct winreg_secinfo_table sec_info_sacl_tests
[] = {
1272 { sd_sacl
, 0, WERR_OK
,
1273 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1274 { sd_sacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1275 { sd_sacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1276 { sd_sacl
, SECINFO_DACL
, WERR_OK
,
1277 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1278 { sd_sacl
, SECINFO_SACL
, WERR_OK
,
1279 true, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1282 uint32_t sd_sacl_good_access_masks
[] = {
1283 SEC_FLAG_MAXIMUM_ALLOWED
| SEC_FLAG_SYSTEM_SECURITY
,
1284 /* SEC_FLAG_SYSTEM_SECURITY, */
1287 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1292 if (!test_BackupSecurity(p
, tctx
, handle
, key
, &sd_orig
)) {
1298 for (i
=0; i
< ARRAY_SIZE(sec_info_owner_tests
); i
++) {
1300 for (a
=0; a
< ARRAY_SIZE(sd_owner_good_access_masks
); a
++) {
1302 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1305 sd_owner_good_access_masks
[a
],
1306 sec_info_owner_tests
[i
].sec_info
,
1307 sec_info_owner_tests
[i
].sd
,
1308 sec_info_owner_tests
[i
].set_werr
,
1309 sec_info_owner_tests
[i
].sid_present
,
1310 sec_info_owner_tests
[i
].fn
,
1313 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1322 for (i
=0; i
< ARRAY_SIZE(sec_info_group_tests
); i
++) {
1324 for (a
=0; a
< ARRAY_SIZE(sd_group_good_access_masks
); a
++) {
1326 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1329 sd_group_good_access_masks
[a
],
1330 sec_info_group_tests
[i
].sec_info
,
1331 sec_info_group_tests
[i
].sd
,
1332 sec_info_group_tests
[i
].set_werr
,
1333 sec_info_group_tests
[i
].sid_present
,
1334 sec_info_group_tests
[i
].fn
,
1337 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1346 for (i
=0; i
< ARRAY_SIZE(sec_info_dacl_tests
); i
++) {
1348 for (a
=0; a
< ARRAY_SIZE(sd_dacl_good_access_masks
); a
++) {
1350 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1353 sd_dacl_good_access_masks
[a
],
1354 sec_info_dacl_tests
[i
].sec_info
,
1355 sec_info_dacl_tests
[i
].sd
,
1356 sec_info_dacl_tests
[i
].set_werr
,
1357 sec_info_dacl_tests
[i
].sid_present
,
1358 sec_info_dacl_tests
[i
].fn
,
1361 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1370 for (i
=0; i
< ARRAY_SIZE(sec_info_sacl_tests
); i
++) {
1372 for (a
=0; a
< ARRAY_SIZE(sd_sacl_good_access_masks
); a
++) {
1374 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1377 sd_sacl_good_access_masks
[a
],
1378 sec_info_sacl_tests
[i
].sec_info
,
1379 sec_info_sacl_tests
[i
].sd
,
1380 sec_info_sacl_tests
[i
].set_werr
,
1381 sec_info_sacl_tests
[i
].sid_present
,
1382 sec_info_sacl_tests
[i
].fn
,
1385 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1393 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1398 static bool test_SecurityDescriptors(struct dcerpc_pipe
*p
,
1399 struct torture_context
*tctx
,
1400 struct policy_handle
*handle
,
1405 if (!test_SecurityDescriptor(p
, tctx
, handle
, key
)) {
1406 torture_comment(tctx
, "test_SecurityDescriptor failed\n");
1410 if (!test_SecurityDescriptorInheritance(p
, tctx
, handle
, key
)) {
1411 torture_comment(tctx
, "test_SecurityDescriptorInheritance failed\n");
1415 if (!test_SecurityDescriptorBlockInheritance(p
, tctx
, handle
, key
)) {
1416 torture_comment(tctx
, "test_SecurityDescriptorBlockInheritance failed\n");
1420 if (!test_SecurityDescriptorsSecInfo(p
, tctx
, handle
, key
)) {
1421 torture_comment(tctx
, "test_SecurityDescriptorsSecInfo failed\n");
1425 if (!test_SecurityDescriptorsMasks(p
, tctx
, handle
, key
)) {
1426 torture_comment(tctx
, "test_SecurityDescriptorsMasks failed\n");
1433 static bool test_DeleteKey_opts(struct dcerpc_binding_handle
*b
,
1434 struct torture_context
*tctx
,
1435 struct policy_handle
*handle
,
1437 WERROR expected_result
)
1439 struct winreg_DeleteKey r
;
1441 torture_comment(tctx
, "Testing DeleteKey(%s)\n", key
);
1443 r
.in
.handle
= handle
;
1444 init_winreg_String(&r
.in
.key
, key
);
1446 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteKey_r(b
, tctx
, &r
),
1447 "Delete Key failed");
1448 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
1449 "DeleteKey failed");
1454 static bool test_DeleteKey(struct dcerpc_binding_handle
*b
,
1455 struct torture_context
*tctx
,
1456 struct policy_handle
*handle
, const char *key
)
1458 return test_DeleteKey_opts(b
, tctx
, handle
, key
, WERR_OK
);
1461 static bool test_QueryInfoKey(struct dcerpc_binding_handle
*b
,
1462 struct torture_context
*tctx
,
1463 struct policy_handle
*handle
, char *kclass
)
1465 struct winreg_QueryInfoKey r
;
1466 uint32_t num_subkeys
, max_subkeylen
, max_classlen
,
1467 num_values
, max_valnamelen
, max_valbufsize
,
1469 NTTIME last_changed_time
;
1472 r
.in
.handle
= handle
;
1473 r
.out
.num_subkeys
= &num_subkeys
;
1474 r
.out
.max_subkeylen
= &max_subkeylen
;
1475 r
.out
.max_classlen
= &max_classlen
;
1476 r
.out
.num_values
= &num_values
;
1477 r
.out
.max_valnamelen
= &max_valnamelen
;
1478 r
.out
.max_valbufsize
= &max_valbufsize
;
1479 r
.out
.secdescsize
= &secdescsize
;
1480 r
.out
.last_changed_time
= &last_changed_time
;
1482 r
.out
.classname
= talloc(tctx
, struct winreg_String
);
1484 r
.in
.classname
= talloc(tctx
, struct winreg_String
);
1485 init_winreg_String(r
.in
.classname
, kclass
);
1487 torture_assert_ntstatus_ok(tctx
,
1488 dcerpc_winreg_QueryInfoKey_r(b
, tctx
, &r
),
1489 "QueryInfoKey failed");
1491 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryInfoKey failed");
1496 static bool test_SetValue(struct dcerpc_binding_handle
*b
,
1497 struct torture_context
*tctx
,
1498 struct policy_handle
*handle
,
1499 const char *value_name
,
1500 enum winreg_Type type
,
1504 struct winreg_SetValue r
;
1505 struct winreg_String name
;
1507 torture_comment(tctx
, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1508 value_name
, str_regtype(type
), size
);
1510 init_winreg_String(&name
, value_name
);
1512 r
.in
.handle
= handle
;
1518 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_SetValue_r(b
, tctx
, &r
),
1519 "winreg_SetValue failed");
1520 torture_assert_werr_ok(tctx
, r
.out
.result
,
1521 "winreg_SetValue failed");
1526 static bool test_DeleteValue(struct dcerpc_binding_handle
*b
,
1527 struct torture_context
*tctx
,
1528 struct policy_handle
*handle
,
1529 const char *value_name
)
1531 struct winreg_DeleteValue r
;
1532 struct winreg_String value
;
1534 torture_comment(tctx
, "Testing DeleteValue(%s)\n", value_name
);
1536 init_winreg_String(&value
, value_name
);
1538 r
.in
.handle
= handle
;
1541 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteValue_r(b
, tctx
, &r
),
1542 "winreg_DeleteValue failed");
1543 torture_assert_werr_ok(tctx
, r
.out
.result
,
1544 "winreg_DeleteValue failed");
1549 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1550 struct policy_handle
*handle
, int depth
,
1551 bool test_security
);
1553 static bool test_EnumKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1554 struct policy_handle
*handle
, int depth
,
1557 struct winreg_EnumKey r
;
1558 struct winreg_StringBuf kclass
, name
;
1561 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1567 r
.in
.handle
= handle
;
1568 r
.in
.enum_index
= 0;
1570 r
.in
.keyclass
= &kclass
;
1572 r
.in
.last_changed_time
= &t
;
1578 status
= dcerpc_winreg_EnumKey_r(b
, tctx
, &r
);
1580 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
1581 struct policy_handle key_handle
;
1583 torture_comment(tctx
, "EnumKey: %d: %s\n",
1587 if (!test_OpenKey(b
, tctx
, handle
, r
.out
.name
->name
,
1590 test_key(p
, tctx
, &key_handle
,
1591 depth
+ 1, test_security
);
1597 } while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
));
1599 torture_assert_ntstatus_ok(tctx
, status
, "EnumKey failed");
1601 if (!W_ERROR_IS_OK(r
.out
.result
) &&
1602 !W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
1603 torture_fail(tctx
, "EnumKey failed");
1609 static bool test_QueryMultipleValues(struct dcerpc_binding_handle
*b
,
1610 struct torture_context
*tctx
,
1611 struct policy_handle
*handle
,
1612 const char *valuename
)
1614 struct winreg_QueryMultipleValues r
;
1618 r
.in
.key_handle
= handle
;
1619 r
.in
.values
= r
.out
.values
= talloc_array(tctx
, struct QueryMultipleValue
, 1);
1620 r
.in
.values
[0].name
= talloc(tctx
, struct winreg_String
);
1621 r
.in
.values
[0].name
->name
= valuename
;
1622 r
.in
.values
[0].offset
= 0;
1623 r
.in
.values
[0].length
= 0;
1624 r
.in
.values
[0].type
= 0;
1626 r
.in
.num_values
= 1;
1627 r
.in
.buffer_size
= r
.out
.buffer_size
= talloc(tctx
, uint32_t);
1628 *r
.in
.buffer_size
= bufsize
;
1630 *r
.in
.buffer_size
= bufsize
;
1631 r
.in
.buffer
= r
.out
.buffer
= talloc_zero_array(tctx
, uint8_t,
1634 torture_assert_ntstatus_ok(tctx
,
1635 dcerpc_winreg_QueryMultipleValues_r(b
, tctx
, &r
),
1636 "QueryMultipleValues failed");
1638 talloc_free(r
.in
.buffer
);
1640 } while (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
));
1642 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryMultipleValues failed");
1647 static bool test_QueryValue(struct dcerpc_binding_handle
*b
,
1648 struct torture_context
*tctx
,
1649 struct policy_handle
*handle
,
1650 const char *valuename
)
1652 struct winreg_QueryValue r
;
1654 enum winreg_Type zero_type
= 0;
1655 uint32_t offered
= 0xfff;
1659 r
.in
.handle
= handle
;
1661 r
.in
.value_name
= talloc_zero(tctx
, struct winreg_String
);
1662 r
.in
.value_name
->name
= valuename
;
1663 r
.in
.type
= &zero_type
;
1664 r
.in
.data_size
= &offered
;
1665 r
.in
.data_length
= &zero
;
1667 status
= dcerpc_winreg_QueryValue_r(b
, tctx
, &r
);
1668 if (NT_STATUS_IS_ERR(status
)) {
1669 torture_fail(tctx
, "QueryValue failed");
1672 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
1677 static bool test_QueryValue_full(struct dcerpc_binding_handle
*b
,
1678 struct torture_context
*tctx
,
1679 struct policy_handle
*handle
,
1680 const char *valuename
,
1681 bool existing_value
)
1683 struct winreg_QueryValue r
;
1684 struct winreg_String value_name
;
1685 enum winreg_Type type
= REG_NONE
;
1686 uint32_t data_size
= 0;
1687 uint32_t real_data_size
= 0;
1688 uint32_t data_length
= 0;
1689 uint8_t *data
= NULL
;
1690 WERROR expected_error
= WERR_BADFILE
;
1691 const char *errmsg_nonexisting
= "expected WERR_BADFILE for nonexisting value";
1693 if (valuename
== NULL
) {
1694 expected_error
= WERR_INVALID_PARAM
;
1695 errmsg_nonexisting
= "expected WERR_INVALID_PARAM for NULL valuename";
1700 init_winreg_String(&value_name
, NULL
);
1702 torture_comment(tctx
, "Testing QueryValue(%s)\n", valuename
);
1704 r
.in
.handle
= handle
;
1705 r
.in
.value_name
= &value_name
;
1707 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
), "QueryValue failed");
1708 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1709 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1711 init_winreg_String(&value_name
, valuename
);
1712 r
.in
.value_name
= &value_name
;
1714 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1715 "QueryValue failed");
1716 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1717 "expected WERR_INVALID_PARAM for missing type length and size");
1721 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1722 "QueryValue failed");
1723 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1724 "expected WERR_INVALID_PARAM for missing length and size");
1726 r
.in
.data_length
= &data_length
;
1727 r
.out
.data_length
= &data_length
;
1728 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1729 "QueryValue failed");
1730 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1731 "expected WERR_INVALID_PARAM for missing size");
1733 r
.in
.data_size
= &data_size
;
1734 r
.out
.data_size
= &data_size
;
1735 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1736 "QueryValue failed");
1737 if (existing_value
) {
1738 torture_assert_werr_ok(tctx
, r
.out
.result
,
1739 "QueryValue failed");
1741 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1742 errmsg_nonexisting
);
1745 real_data_size
= *r
.out
.data_size
;
1747 data
= talloc_zero_array(tctx
, uint8_t, 0);
1750 *r
.in
.data_size
= 0;
1751 *r
.out
.data_size
= 0;
1752 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1753 "QueryValue failed");
1754 if (existing_value
) {
1755 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_MORE_DATA
,
1756 "expected WERR_MORE_DATA for query with too small buffer");
1758 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1759 errmsg_nonexisting
);
1762 data
= talloc_zero_array(tctx
, uint8_t, real_data_size
);
1765 r
.in
.data_size
= &real_data_size
;
1766 r
.out
.data_size
= &real_data_size
;
1767 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1768 "QueryValue failed");
1769 if (existing_value
) {
1770 torture_assert_werr_ok(tctx
, r
.out
.result
,
1771 "QueryValue failed");
1773 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1774 errmsg_nonexisting
);
1780 static bool test_EnumValue(struct dcerpc_binding_handle
*b
,
1781 struct torture_context
*tctx
,
1782 struct policy_handle
*handle
, int max_valnamelen
,
1785 struct winreg_EnumValue r
;
1786 enum winreg_Type type
= 0;
1787 uint32_t size
= max_valbufsize
, zero
= 0;
1790 struct winreg_ValNameBuf name
;
1796 r
.in
.handle
= handle
;
1797 r
.in
.enum_index
= 0;
1802 r
.in
.length
= &zero
;
1806 torture_assert_ntstatus_ok(tctx
,
1807 dcerpc_winreg_EnumValue_r(b
, tctx
, &r
),
1808 "EnumValue failed");
1810 if (W_ERROR_IS_OK(r
.out
.result
)) {
1811 ret
&= test_QueryValue(b
, tctx
, handle
,
1813 ret
&= test_QueryMultipleValues(b
, tctx
, handle
,
1818 } while (W_ERROR_IS_OK(r
.out
.result
));
1820 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NO_MORE_ITEMS
,
1821 "EnumValue failed");
1826 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle
*b
,
1827 struct torture_context
*tctx
)
1829 struct winreg_AbortSystemShutdown r
;
1830 uint16_t server
= 0x0;
1833 r
.in
.server
= &server
;
1835 torture_assert_ntstatus_ok(tctx
,
1836 dcerpc_winreg_AbortSystemShutdown_r(b
, tctx
, &r
),
1837 "AbortSystemShutdown failed");
1839 torture_assert_werr_ok(tctx
, r
.out
.result
,
1840 "AbortSystemShutdown failed");
1845 static bool test_InitiateSystemShutdown(struct torture_context
*tctx
,
1846 struct dcerpc_pipe
*p
)
1848 struct winreg_InitiateSystemShutdown r
;
1849 uint16_t hostname
= 0x0;
1850 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1853 r
.in
.hostname
= &hostname
;
1854 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1855 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1856 r
.in
.force_apps
= 1;
1860 torture_assert_ntstatus_ok(tctx
,
1861 dcerpc_winreg_InitiateSystemShutdown_r(b
, tctx
, &r
),
1862 "InitiateSystemShutdown failed");
1864 torture_assert_werr_ok(tctx
, r
.out
.result
,
1865 "InitiateSystemShutdown failed");
1867 return test_AbortSystemShutdown(b
, tctx
);
1871 static bool test_InitiateSystemShutdownEx(struct torture_context
*tctx
,
1872 struct dcerpc_pipe
*p
)
1874 struct winreg_InitiateSystemShutdownEx r
;
1875 uint16_t hostname
= 0x0;
1876 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1879 r
.in
.hostname
= &hostname
;
1880 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1881 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1882 r
.in
.force_apps
= 1;
1887 torture_assert_ntstatus_ok(tctx
,
1888 dcerpc_winreg_InitiateSystemShutdownEx_r(b
, tctx
, &r
),
1889 "InitiateSystemShutdownEx failed");
1891 torture_assert_werr_ok(tctx
, r
.out
.result
,
1892 "InitiateSystemShutdownEx failed");
1894 return test_AbortSystemShutdown(b
, tctx
);
1896 #define MAX_DEPTH 2 /* Only go this far down the tree */
1898 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1899 struct policy_handle
*handle
, int depth
,
1902 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1904 if (depth
== MAX_DEPTH
)
1907 if (!test_QueryInfoKey(b
, tctx
, handle
, NULL
)) {
1910 if (!test_NotifyChangeKeyValue(b
, tctx
, handle
)) {
1913 if (test_security
&& !test_GetKeySecurity(p
, tctx
, handle
, NULL
)) {
1916 if (!test_EnumKey(p
, tctx
, handle
, depth
, test_security
)) {
1919 if (!test_EnumValue(b
, tctx
, handle
, 0xFF, 0xFFFF)) {
1922 test_CloseKey(b
, tctx
, handle
);
1927 static bool test_SetValue_simple(struct dcerpc_binding_handle
*b
,
1928 struct torture_context
*tctx
,
1929 struct policy_handle
*handle
)
1931 const char *value_name
= TEST_VALUE
;
1932 uint32_t value
= 0x12345678;
1933 uint64_t value2
= 0x12345678;
1934 const char *string
= "torture";
1935 const char *array
[2];
1937 enum winreg_Type types
[] = {
1939 REG_DWORD_BIG_ENDIAN
,
1947 array
[0] = "array0";
1950 torture_comment(tctx
, "Testing SetValue (standard formats)\n");
1952 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
1954 enum winreg_Type w_type
;
1955 uint32_t w_size
, w_length
;
1960 case REG_DWORD_BIG_ENDIAN
:
1961 blob
= data_blob_talloc_zero(tctx
, 4);
1962 SIVAL(blob
.data
, 0, value
);
1965 blob
= data_blob_talloc_zero(tctx
, 8);
1966 SBVAL(blob
.data
, 0, value2
);
1969 blob
= data_blob_string_const("binary_blob");
1972 torture_assert(tctx
, push_reg_sz(tctx
, &blob
, string
), "failed to push REG_SZ");
1975 torture_assert(tctx
, push_reg_multi_sz(tctx
, &blob
, array
), "failed to push REG_MULTI_SZ");
1981 torture_assert(tctx
,
1982 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
1983 "test_SetValue failed");
1984 torture_assert(tctx
,
1985 test_QueryValue_full(b
, tctx
, handle
, value_name
, true),
1986 talloc_asprintf(tctx
, "test_QueryValue_full for %s value failed", value_name
));
1987 torture_assert(tctx
,
1988 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
1989 "test_winreg_QueryValue failed");
1990 torture_assert(tctx
,
1991 test_DeleteValue(b
, tctx
, handle
, value_name
),
1992 "test_DeleteValue failed");
1994 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
1995 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
1996 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
1997 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
2000 torture_comment(tctx
, "Testing SetValue (standard formats) succeeded\n");
2005 typedef NTSTATUS (*winreg_open_fn
)(struct dcerpc_binding_handle
*, TALLOC_CTX
*, void *);
2007 static bool test_SetValue_extended(struct dcerpc_binding_handle
*b
,
2008 struct torture_context
*tctx
,
2009 struct policy_handle
*handle
)
2011 const char *value_name
= TEST_VALUE
;
2012 enum winreg_Type types
[] = {
2018 REG_DWORD_BIG_ENDIAN
,
2022 REG_FULL_RESOURCE_DESCRIPTOR
,
2023 REG_RESOURCE_REQUIREMENTS_LIST
,
2035 if (torture_setting_bool(tctx
, "samba3", false) ||
2036 torture_setting_bool(tctx
, "samba4", false)) {
2037 torture_skip(tctx
, "skipping extended SetValue test against Samba");
2040 torture_comment(tctx
, "Testing SetValue (extended formats)\n");
2042 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
2043 for (l
=0; l
< 32; l
++) {
2045 enum winreg_Type w_type
;
2046 uint32_t w_size
, w_length
;
2053 data
= talloc_array(tctx
, uint8_t, size
);
2055 generate_random_buffer(data
, size
);
2057 torture_assert(tctx
,
2058 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], data
, size
),
2059 "test_SetValue failed");
2061 torture_assert(tctx
,
2062 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2063 "test_winreg_QueryValue failed");
2065 torture_assert(tctx
,
2066 test_DeleteValue(b
, tctx
, handle
, value_name
),
2067 "test_DeleteValue failed");
2069 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
2070 torture_assert_int_equal(tctx
, w_size
, size
, "winreg size mismatch");
2071 torture_assert_int_equal(tctx
, w_length
, size
, "winreg length mismatch");
2072 torture_assert_mem_equal(tctx
, w_data
, data
, size
, "winreg buffer mismatch");
2076 torture_comment(tctx
, "Testing SetValue (extended formats) succeeded\n");
2081 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2082 #define VALUE_CURRENT_VERSION "CurrentVersion"
2084 static bool test_HKLM_wellknown(struct torture_context
*tctx
,
2085 struct dcerpc_binding_handle
*b
,
2086 struct policy_handle
*handle
)
2088 struct policy_handle newhandle
;
2090 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2091 if (torture_setting_bool(tctx
, "samba3", false)) {
2092 torture_assert(tctx
, test_OpenKey_opts(tctx
, b
, handle
,
2093 KEY_CURRENT_VERSION
,
2094 REG_OPTION_NON_VOLATILE
,
2098 "failed to open current version key");
2100 torture_assert(tctx
, test_OpenKey(b
, tctx
, handle
, KEY_CURRENT_VERSION
, &newhandle
),
2101 "failed to open current version key");
2104 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, VALUE_CURRENT_VERSION
, true),
2105 "failed to query current version");
2106 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "IDoNotExist", false),
2107 "succeeded to query nonexistent value");
2108 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, NULL
, false),
2109 "succeeded to query value with NULL name");
2110 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "", false),
2111 "succeeded to query nonexistent default value (\"\")");
2113 torture_assert(tctx
, test_CloseKey(b
, tctx
, &newhandle
),
2114 "failed to close current version key");
2119 static bool test_OpenHive(struct torture_context
*tctx
,
2120 struct dcerpc_binding_handle
*b
,
2121 struct policy_handle
*handle
,
2124 struct winreg_OpenHKLM r
;
2126 r
.in
.system_name
= 0;
2127 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2128 r
.out
.handle
= handle
;
2131 case HKEY_LOCAL_MACHINE
:
2132 torture_assert_ntstatus_ok(tctx
,
2133 dcerpc_winreg_OpenHKLM_r(b
, tctx
, &r
),
2134 "failed to open HKLM");
2135 torture_assert_werr_ok(tctx
, r
.out
.result
,
2136 "failed to open HKLM");
2138 case HKEY_CURRENT_USER
:
2139 torture_assert_ntstatus_ok(tctx
,
2140 dcerpc_winreg_OpenHKCU_r(b
, tctx
, (struct winreg_OpenHKCU
*)&r
),
2141 "failed to open HKCU");
2142 torture_assert_werr_ok(tctx
, r
.out
.result
,
2143 "failed to open HKCU");
2146 torture_assert_ntstatus_ok(tctx
,
2147 dcerpc_winreg_OpenHKU_r(b
, tctx
, (struct winreg_OpenHKU
*)&r
),
2148 "failed to open HKU");
2149 torture_assert_werr_ok(tctx
, r
.out
.result
,
2150 "failed to open HKU");
2152 case HKEY_CLASSES_ROOT
:
2153 torture_assert_ntstatus_ok(tctx
,
2154 dcerpc_winreg_OpenHKCR_r(b
, tctx
, (struct winreg_OpenHKCR
*)&r
),
2155 "failed to open HKCR");
2156 torture_assert_werr_ok(tctx
, r
.out
.result
,
2157 "failed to open HKCR");
2160 torture_warning(tctx
, "unsupported hkey: 0x%08x\n", hkey
);
2167 static bool test_volatile_keys(struct torture_context
*tctx
,
2168 struct dcerpc_binding_handle
*b
,
2169 struct policy_handle
*handle
,
2172 struct policy_handle new_handle
;
2173 enum winreg_CreateAction action_taken
;
2175 torture_comment(tctx
, "Testing VOLATILE key\n");
2177 test_DeleteKey(b
, tctx
, handle
, TEST_KEY_VOLATILE
);
2179 torture_assert(tctx
,
2180 test_CreateKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
, NULL
,
2181 REG_OPTION_VOLATILE
,
2182 SEC_FLAG_MAXIMUM_ALLOWED
,
2187 "failed to create REG_OPTION_VOLATILE type key");
2189 torture_assert_int_equal(tctx
, action_taken
, REG_CREATED_NEW_KEY
, "unexpected action");
2191 torture_assert(tctx
,
2192 test_CreateKey_opts(tctx
, b
, &new_handle
, TEST_SUBKEY_VOLATILE
, NULL
,
2193 REG_OPTION_NON_VOLATILE
,
2194 SEC_FLAG_MAXIMUM_ALLOWED
,
2196 WERR_CHILD_MUST_BE_VOLATILE
,
2199 "failed to fail create REG_OPTION_VOLATILE type key");
2201 torture_assert(tctx
,
2202 test_CloseKey(b
, tctx
, &new_handle
),
2205 torture_assert(tctx
,
2206 test_OpenKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
,
2207 REG_OPTION_NON_VOLATILE
,
2208 SEC_FLAG_MAXIMUM_ALLOWED
,
2211 "failed to open volatile key");
2213 torture_assert(tctx
,
2214 test_DeleteKey(b
, tctx
, handle
, TEST_KEY_VOLATILE
),
2215 "failed to delete key");
2217 torture_assert(tctx
,
2218 test_CreateKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
, NULL
,
2219 REG_OPTION_VOLATILE
,
2220 SEC_FLAG_MAXIMUM_ALLOWED
,
2225 "failed to create REG_OPTION_VOLATILE type key");
2227 torture_assert_int_equal(tctx
, action_taken
, REG_CREATED_NEW_KEY
, "unexpected action");
2229 torture_assert(tctx
,
2230 test_CloseKey(b
, tctx
, &new_handle
),
2233 torture_assert(tctx
,
2234 test_OpenKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
,
2235 REG_OPTION_VOLATILE
,
2236 SEC_FLAG_MAXIMUM_ALLOWED
,
2239 "failed to open volatile key");
2241 torture_assert(tctx
,
2242 test_CloseKey(b
, tctx
, &new_handle
),
2245 torture_assert(tctx
,
2246 test_CloseKey(b
, tctx
, handle
),
2249 torture_assert(tctx
,
2250 test_OpenHive(tctx
, b
, handle
, hkey
),
2251 "failed top open hive");
2253 torture_assert(tctx
,
2254 test_OpenKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
,
2255 REG_OPTION_VOLATILE
,
2256 SEC_FLAG_MAXIMUM_ALLOWED
,
2259 "failed to open volatile key");
2261 torture_assert(tctx
,
2262 test_OpenKey_opts(tctx
, b
, handle
, TEST_KEY_VOLATILE
,
2263 REG_OPTION_NON_VOLATILE
,
2264 SEC_FLAG_MAXIMUM_ALLOWED
,
2267 "failed to open volatile key");
2269 torture_comment(tctx
, "Testing VOLATILE key succeeded\n");
2274 static const char *kernel_mode_registry_path(struct torture_context
*tctx
,
2276 const char *sid_string
,
2280 case HKEY_LOCAL_MACHINE
:
2281 return talloc_asprintf(tctx
, "\\Registry\\MACHINE\\%s", path
);
2282 case HKEY_CURRENT_USER
:
2283 return talloc_asprintf(tctx
, "\\Registry\\USER\\%s\\%s", sid_string
, path
);
2285 return talloc_asprintf(tctx
, "\\Registry\\USER\\%s", path
);
2286 case HKEY_CLASSES_ROOT
:
2287 return talloc_asprintf(tctx
, "\\Registry\\MACHINE\\Software\\Classes\\%s", path
);
2289 torture_warning(tctx
, "unsupported hkey: 0x%08x\n", hkey
);
2296 static bool test_symlink_keys(struct torture_context
*tctx
,
2297 struct dcerpc_binding_handle
*b
,
2298 struct policy_handle
*handle
,
2301 struct policy_handle new_handle
;
2302 enum winreg_CreateAction action_taken
;
2304 /* symlink destination needs to be a kernel mode registry path */
2305 const char *dest
= "\\Registry\\MACHINE\\SOFTWARE\\foo";
2307 /* disable until we know how to *not* screw up a windows registry */
2308 torture_skip(tctx
, "symlink test disabled");
2310 torture_comment(tctx
, "Testing REG_OPTION_CREATE_LINK key\n");
2312 test_DeleteKey(b
, tctx
, handle
, TEST_KEY_SYMLINK
);
2314 torture_assert(tctx
,
2315 test_CreateKey_opts(tctx
, b
, handle
, TEST_KEY_SYMLINK
, NULL
,
2316 REG_OPTION_CREATE_LINK
| REG_OPTION_VOLATILE
,
2317 SEC_FLAG_MAXIMUM_ALLOWED
,
2322 "failed to create REG_OPTION_CREATE_LINK type key");
2324 torture_assert_int_equal(tctx
, action_taken
, REG_CREATED_NEW_KEY
, "unexpected action");
2326 torture_assert(tctx
,
2327 convert_string_talloc(tctx
, CH_UNIX
, CH_UTF16
,
2328 dest
, strlen(dest
), /* not NULL terminated */
2329 &blob
.data
, &blob
.length
,
2331 "failed to convert");
2333 torture_assert(tctx
,
2334 test_SetValue(b
, tctx
, &new_handle
, "SymbolicLinkValue", REG_LINK
, blob
.data
, blob
.length
),
2335 "failed to create SymbolicLinkValue value");
2337 torture_assert(tctx
,
2338 test_CloseKey(b
, tctx
, &new_handle
),
2341 torture_assert(tctx
,
2342 test_OpenKey_opts(tctx
, b
, handle
, TEST_KEY_SYMLINK
,
2343 REG_OPTION_OPEN_LINK
| REG_OPTION_VOLATILE
,
2344 SEC_FLAG_MAXIMUM_ALLOWED
,
2347 "failed to open symlink key");
2349 torture_assert(tctx
,
2350 test_DeleteKey(b
, tctx
, handle
, TEST_KEY_SYMLINK
),
2351 "failed to delete key");
2356 static bool test_CreateKey_keytypes(struct torture_context
*tctx
,
2357 struct dcerpc_binding_handle
*b
,
2358 struct policy_handle
*handle
,
2362 if (torture_setting_bool(tctx
, "samba3", false) ||
2363 torture_setting_bool(tctx
, "samba4", false)) {
2364 torture_skip(tctx
, "skipping CreateKey keytypes test against Samba");
2367 torture_assert(tctx
,
2368 test_volatile_keys(tctx
, b
, handle
, hkey
),
2369 "failed to test volatile keys");
2371 torture_assert(tctx
,
2372 test_symlink_keys(tctx
, b
, handle
, hkey
),
2373 "failed to test symlink keys");
2378 static bool test_key_base(struct torture_context
*tctx
,
2379 struct dcerpc_binding_handle
*b
,
2380 struct policy_handle
*handle
,
2381 const char *base_key
,
2384 struct policy_handle newhandle
;
2385 bool ret
= true, created
= false, deleted
= false;
2386 bool created3
= false;
2387 const char *test_key1
;
2388 const char *test_key3
;
2389 const char *test_subkey
;
2391 test_Cleanup(b
, tctx
, handle
, base_key
);
2393 if (!test_CreateKey(b
, tctx
, handle
, base_key
, NULL
)) {
2394 torture_comment(tctx
,
2395 "CreateKey(%s) failed\n", base_key
);
2398 test_key1
= talloc_asprintf(tctx
, "%s\\%s", base_key
, TEST_KEY1
);
2400 if (!test_CreateKey(b
, tctx
, handle
, test_key1
, NULL
)) {
2401 torture_comment(tctx
,
2402 "CreateKey failed - not considering a failure\n");
2408 if (!test_FlushKey(b
, tctx
, handle
)) {
2409 torture_comment(tctx
, "FlushKey failed\n");
2413 if (!test_OpenKey(b
, tctx
, handle
, test_key1
, &newhandle
)) {
2415 "CreateKey failed (OpenKey after Create didn't work)\n");
2418 if (hkey
== HKEY_CURRENT_USER
) {
2419 torture_assert(tctx
, test_SetValue_simple(b
, tctx
, &newhandle
),
2420 "simple SetValue test failed");
2421 torture_assert(tctx
, test_SetValue_extended(b
, tctx
, &newhandle
),
2422 "extended SetValue test failed");
2423 torture_assert(tctx
, test_CreateKey_keytypes(tctx
, b
, &newhandle
, hkey
),
2424 "keytype test failed");
2427 if (!test_CloseKey(b
, tctx
, &newhandle
)) {
2429 "CreateKey failed (CloseKey after Open didn't work)\n");
2432 if (!test_DeleteKey(b
, tctx
, handle
, test_key1
)) {
2433 torture_comment(tctx
, "DeleteKey failed\n");
2439 if (!test_FlushKey(b
, tctx
, handle
)) {
2440 torture_comment(tctx
, "FlushKey failed\n");
2445 if (!test_OpenKey_opts(tctx
, b
, handle
, test_key1
,
2446 REG_OPTION_NON_VOLATILE
,
2447 SEC_FLAG_MAXIMUM_ALLOWED
,
2450 torture_comment(tctx
,
2451 "DeleteKey failed (OpenKey after Delete "
2452 "did not return WERR_BADFILE)\n");
2457 test_key3
= talloc_asprintf(tctx
, "%s\\%s", base_key
, TEST_KEY3
);
2459 if (test_CreateKey(b
, tctx
, handle
, test_key3
, NULL
)) {
2463 test_subkey
= talloc_asprintf(tctx
, "%s\\%s", test_key3
, TEST_SUBKEY
);
2466 if (test_CreateKey(b
, tctx
, handle
, test_subkey
, NULL
)) {
2467 if (!test_DeleteKey(b
, tctx
, handle
, test_subkey
)) {
2468 torture_comment(tctx
, "DeleteKey failed\n");
2473 if (!test_DeleteKey(b
, tctx
, handle
, test_key3
)) {
2474 torture_comment(tctx
, "DeleteKey failed\n");
2480 test_Cleanup(b
, tctx
, handle
, base_key
);
2485 static bool test_key_base_sd(struct torture_context
*tctx
,
2486 struct dcerpc_pipe
*p
,
2487 struct policy_handle
*handle
,
2488 const char *base_key
)
2490 struct policy_handle newhandle
;
2491 bool ret
= true, created2
= false, created4
= false;
2492 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2493 const char *test_key2
;
2494 const char *test_key4
;
2496 torture_skip(tctx
, "security descriptor test disabled\n");
2498 if (torture_setting_bool(tctx
, "samba3", false) ||
2499 torture_setting_bool(tctx
, "samba4", false)) {
2500 torture_skip(tctx
, "skipping security descriptor tests against Samba");
2503 test_Cleanup(b
, tctx
, handle
, base_key
);
2505 if (!test_CreateKey(b
, tctx
, handle
, base_key
, NULL
)) {
2506 torture_comment(tctx
,
2507 "CreateKey(%s) failed\n", base_key
);
2510 test_key2
= talloc_asprintf(tctx
, "%s\\%s", base_key
, TEST_KEY2
);
2512 if (test_CreateKey_sd(b
, tctx
, handle
, test_key2
,
2513 NULL
, &newhandle
)) {
2517 if (created2
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2518 torture_comment(tctx
, "CloseKey failed\n");
2522 test_key4
= talloc_asprintf(tctx
, "%s\\%s", base_key
, TEST_KEY4
);
2524 if (test_CreateKey_sd(b
, tctx
, handle
, test_key4
, NULL
, &newhandle
)) {
2528 if (created4
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2529 torture_comment(tctx
, "CloseKey failed\n");
2533 if (created4
&& !test_SecurityDescriptors(p
, tctx
, handle
, test_key4
)) {
2537 if (created4
&& !test_DeleteKey(b
, tctx
, handle
, test_key4
)) {
2538 torture_comment(tctx
, "DeleteKey failed\n");
2542 if (created2
&& !test_DeleteKey(b
, tctx
, handle
, test_key4
)) {
2543 torture_comment(tctx
, "DeleteKey failed\n");
2547 test_Cleanup(b
, tctx
, handle
, base_key
);
2552 static bool test_Open(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2555 struct policy_handle handle
;
2557 struct winreg_OpenHKLM r
;
2558 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2559 const char *torture_base_key
;
2562 winreg_open_fn open_fn
= (winreg_open_fn
)userdata
;
2564 r
.in
.system_name
= 0;
2565 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2566 r
.out
.handle
= &handle
;
2568 torture_assert_ntstatus_ok(tctx
, open_fn(b
, tctx
, &r
),
2571 if (!test_GetVersion(b
, tctx
, &handle
)) {
2572 torture_comment(tctx
, "GetVersion failed\n");
2576 if (open_fn
== (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
) {
2577 hkey
= HKEY_LOCAL_MACHINE
;
2578 torture_base_key
= "SOFTWARE\\Samba\\" TEST_KEY_BASE
;
2579 } else if (open_fn
== (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
) {
2581 torture_base_key
= TEST_KEY_BASE
;
2582 } else if (open_fn
== (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
) {
2583 hkey
= HKEY_CLASSES_ROOT
;
2584 torture_base_key
= TEST_KEY_BASE
;
2585 } else if (open_fn
== (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
) {
2586 hkey
= HKEY_CURRENT_USER
;
2587 torture_base_key
= TEST_KEY_BASE
;
2589 torture_fail(tctx
, "unsupported hkey");
2592 if (hkey
== HKEY_LOCAL_MACHINE
) {
2593 torture_assert(tctx
,
2594 test_HKLM_wellknown(tctx
, b
, &handle
),
2595 "failed to test HKLM wellknown keys");
2598 if (!test_key_base(tctx
, b
, &handle
, torture_base_key
, hkey
)) {
2599 torture_warning(tctx
, "failed to test TEST_KEY_BASE(%s)",
2604 if (!test_key_base_sd(tctx
, p
, &handle
, torture_base_key
)) {
2605 torture_warning(tctx
, "failed to test TEST_KEY_BASE(%s) sd",
2610 /* The HKCR hive has a very large fanout */
2611 if (hkey
== HKEY_CLASSES_ROOT
) {
2612 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, false)) {
2615 } else if (hkey
== HKEY_LOCAL_MACHINE
) {
2616 /* FIXME we are not allowed to enum values in the HKLM root */
2618 if (!test_key(p
, tctx
, &handle
, 0, false)) {
2626 struct torture_suite
*torture_rpc_winreg(TALLOC_CTX
*mem_ctx
)
2628 struct torture_rpc_tcase
*tcase
;
2629 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WINREG");
2630 struct torture_test
*test
;
2632 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "winreg",
2635 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdown",
2636 test_InitiateSystemShutdown
);
2637 test
->dangerous
= true;
2639 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdownEx",
2640 test_InitiateSystemShutdownEx
);
2641 test
->dangerous
= true;
2643 torture_rpc_tcase_add_test_ex(tcase
, "HKLM",
2645 (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
);
2646 torture_rpc_tcase_add_test_ex(tcase
, "HKU",
2648 (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
);
2649 torture_rpc_tcase_add_test_ex(tcase
, "HKCR",
2651 (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
);
2652 torture_rpc_tcase_add_test_ex(tcase
, "HKCU",
2654 (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
);