2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "smbtorture test"
32 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
33 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
34 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
35 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
36 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
37 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
38 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
41 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
43 static void init_lsa_StringLarge(struct lsa_StringLarge
*name
, const char *s
)
48 static void init_winreg_String(struct winreg_String
*name
, const char *s
)
52 name
->name_len
= 2 * (strlen_m(s
) + 1);
53 name
->name_size
= name
->name_len
;
60 static bool test_GetVersion(struct dcerpc_pipe
*p
,
61 struct torture_context
*tctx
,
62 struct policy_handle
*handle
)
64 struct winreg_GetVersion r
;
71 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_GetVersion(p
, tctx
, &r
),
74 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetVersion failed");
79 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe
*p
,
80 struct torture_context
*tctx
,
81 struct policy_handle
*handle
)
83 struct winreg_NotifyChangeKeyValue r
;
87 r
.in
.watch_subtree
= true;
88 r
.in
.notify_filter
= 0;
89 r
.in
.unknown
= r
.in
.unknown2
= 0;
90 init_winreg_String(&r
.in
.string1
, NULL
);
91 init_winreg_String(&r
.in
.string2
, NULL
);
93 torture_assert_ntstatus_ok(tctx
,
94 dcerpc_winreg_NotifyChangeKeyValue(p
, tctx
, &r
),
95 "NotifyChangeKeyValue failed");
97 if (!W_ERROR_IS_OK(r
.out
.result
)) {
99 "NotifyChangeKeyValue failed - %s - not considering\n",
100 win_errstr(r
.out
.result
));
107 static bool test_CreateKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
108 struct policy_handle
*handle
, const char *name
,
111 struct winreg_CreateKey r
;
112 struct policy_handle newhandle
;
113 enum winreg_CreateAction action_taken
= 0;
116 r
.in
.handle
= handle
;
117 r
.out
.new_handle
= &newhandle
;
118 init_winreg_String(&r
.in
.name
, name
);
119 init_winreg_String(&r
.in
.keyclass
, kclass
);
121 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
122 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
125 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey(p
, tctx
, &r
),
128 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey failed");
135 createkey testing with a SD
137 static bool test_CreateKey_sd(struct dcerpc_pipe
*p
,
138 struct torture_context
*tctx
,
139 struct policy_handle
*handle
, const char *name
,
141 struct policy_handle
*newhandle
)
143 struct winreg_CreateKey r
;
144 enum winreg_CreateAction action_taken
= 0;
145 struct security_descriptor
*sd
;
147 struct winreg_SecBuf secbuf
;
149 sd
= security_descriptor_dacl_create(tctx
,
152 SID_NT_AUTHENTICATED_USERS
,
153 SEC_ACE_TYPE_ACCESS_ALLOWED
,
155 SEC_ACE_FLAG_OBJECT_INHERIT
|
156 SEC_ACE_FLAG_CONTAINER_INHERIT
,
159 torture_assert_ndr_success(tctx
,
160 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
161 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
162 "Failed to push security_descriptor ?!\n");
164 secbuf
.sd
.data
= sdblob
.data
;
165 secbuf
.sd
.len
= sdblob
.length
;
166 secbuf
.sd
.size
= sdblob
.length
;
167 secbuf
.length
= sdblob
.length
-10;
171 r
.in
.handle
= handle
;
172 r
.out
.new_handle
= newhandle
;
173 init_winreg_String(&r
.in
.name
, name
);
174 init_winreg_String(&r
.in
.keyclass
, kclass
);
176 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
177 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
178 r
.in
.secdesc
= &secbuf
;
180 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey(p
, tctx
, &r
),
181 "CreateKey with sd failed");
183 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey with sd failed");
188 static bool _test_GetKeySecurity(struct dcerpc_pipe
*p
,
189 struct torture_context
*tctx
,
190 struct policy_handle
*handle
,
191 uint32_t *sec_info_ptr
,
193 struct security_descriptor
**sd_out
)
195 struct winreg_GetKeySecurity r
;
196 struct security_descriptor
*sd
= NULL
;
201 sec_info
= *sec_info_ptr
;
203 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
208 r
.in
.handle
= handle
;
209 r
.in
.sec_info
= sec_info
;
210 r
.in
.sd
= r
.out
.sd
= talloc_zero(tctx
, struct KeySecurityData
);
211 r
.in
.sd
->size
= 0x1000;
213 torture_assert_ntstatus_ok(tctx
,
214 dcerpc_winreg_GetKeySecurity(p
, tctx
, &r
),
215 "GetKeySecurity failed");
217 torture_assert_werr_equal(tctx
, r
.out
.result
, get_werr
,
218 "GetKeySecurity failed");
220 sdblob
.data
= r
.out
.sd
->data
;
221 sdblob
.length
= r
.out
.sd
->len
;
223 sd
= talloc_zero(tctx
, struct security_descriptor
);
225 torture_assert_ndr_success(tctx
,
226 ndr_pull_struct_blob(&sdblob
, tctx
, NULL
, sd
,
227 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
),
228 "pull_security_descriptor failed");
230 if (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
) {
231 NDR_PRINT_DEBUG(security_descriptor
, sd
);
243 static bool test_GetKeySecurity(struct dcerpc_pipe
*p
,
244 struct torture_context
*tctx
,
245 struct policy_handle
*handle
,
246 struct security_descriptor
**sd_out
)
248 return _test_GetKeySecurity(p
, tctx
, handle
, NULL
, WERR_OK
, sd_out
);
251 static bool _test_SetKeySecurity(struct dcerpc_pipe
*p
,
252 struct torture_context
*tctx
,
253 struct policy_handle
*handle
,
254 uint32_t *sec_info_ptr
,
255 struct security_descriptor
*sd
,
258 struct winreg_SetKeySecurity r
;
259 struct KeySecurityData
*sdata
= NULL
;
265 if (sd
&& (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
)) {
266 NDR_PRINT_DEBUG(security_descriptor
, sd
);
269 torture_assert_ndr_success(tctx
,
270 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
271 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
272 "push_security_descriptor failed");
274 sdata
= talloc_zero(tctx
, struct KeySecurityData
);
275 sdata
->data
= sdblob
.data
;
276 sdata
->size
= sdblob
.length
;
277 sdata
->len
= sdblob
.length
;
280 sec_info
= *sec_info_ptr
;
282 sec_info
= SECINFO_UNPROTECTED_SACL
|
283 SECINFO_UNPROTECTED_DACL
;
285 sec_info
|= SECINFO_OWNER
;
288 sec_info
|= SECINFO_GROUP
;
291 sec_info
|= SECINFO_SACL
;
294 sec_info
|= SECINFO_DACL
;
298 r
.in
.handle
= handle
;
299 r
.in
.sec_info
= sec_info
;
302 torture_assert_ntstatus_ok(tctx
,
303 dcerpc_winreg_SetKeySecurity(p
, tctx
, &r
),
304 "SetKeySecurity failed");
306 torture_assert_werr_equal(tctx
, r
.out
.result
, werr
,
307 "SetKeySecurity failed");
312 static bool test_SetKeySecurity(struct dcerpc_pipe
*p
,
313 struct torture_context
*tctx
,
314 struct policy_handle
*handle
,
315 struct security_descriptor
*sd
)
317 return _test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, WERR_OK
);
320 static bool test_CloseKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
321 struct policy_handle
*handle
)
323 struct winreg_CloseKey r
;
326 r
.in
.handle
= r
.out
.handle
= handle
;
328 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CloseKey(p
, tctx
, &r
),
331 torture_assert_werr_ok(tctx
, r
.out
.result
, "CloseKey failed");
336 static bool test_FlushKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
337 struct policy_handle
*handle
)
339 struct winreg_FlushKey r
;
342 r
.in
.handle
= handle
;
344 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_FlushKey(p
, tctx
, &r
),
347 torture_assert_werr_ok(tctx
, r
.out
.result
, "FlushKey failed");
352 static bool _test_OpenKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
353 struct policy_handle
*hive_handle
,
354 const char *keyname
, uint32_t access_mask
,
355 struct policy_handle
*key_handle
,
359 struct winreg_OpenKey r
;
362 r
.in
.parent_handle
= hive_handle
;
363 init_winreg_String(&r
.in
.keyname
, keyname
);
364 r
.in
.options
= REG_KEYTYPE_NON_VOLATILE
;
365 r
.in
.access_mask
= access_mask
;
366 r
.out
.handle
= key_handle
;
368 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenKey(p
, tctx
, &r
),
371 torture_assert_werr_equal(tctx
, r
.out
.result
, open_werr
,
374 if (success
&& W_ERROR_EQUAL(r
.out
.result
, WERR_OK
)) {
381 static bool test_OpenKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
382 struct policy_handle
*hive_handle
,
383 const char *keyname
, struct policy_handle
*key_handle
)
385 return _test_OpenKey(p
, tctx
, hive_handle
, keyname
,
386 SEC_FLAG_MAXIMUM_ALLOWED
, key_handle
,
390 static bool test_Cleanup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
391 struct policy_handle
*handle
, const char *key
)
393 struct winreg_DeleteKey r
;
396 r
.in
.handle
= handle
;
398 init_winreg_String(&r
.in
.key
, key
);
399 dcerpc_winreg_DeleteKey(p
, tctx
, &r
);
404 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe
*p
,
405 struct torture_context
*tctx
,
406 struct policy_handle
*handle
,
410 struct security_descriptor
*sd
= NULL
;
412 if (!_test_GetKeySecurity(p
, tctx
, handle
, NULL
, get_werr
, &sd
)) {
416 if (!_test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, set_werr
)) {
423 static bool test_SecurityDescriptor(struct dcerpc_pipe
*p
,
424 struct torture_context
*tctx
,
425 struct policy_handle
*handle
,
428 struct policy_handle new_handle
;
431 torture_comment(tctx
, "SecurityDescriptor get & set\n");
433 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
437 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
442 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
449 static bool _test_SecurityDescriptor(struct dcerpc_pipe
*p
,
450 struct torture_context
*tctx
,
451 struct policy_handle
*handle
,
452 uint32_t access_mask
,
458 struct policy_handle new_handle
;
460 bool got_key
= false;
462 if (!_test_OpenKey(p
, tctx
, handle
, key
, access_mask
, &new_handle
,
463 open_werr
, &got_key
)) {
471 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
472 get_werr
, set_werr
)) {
476 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
483 static bool test_dacl_trustee_present(struct dcerpc_pipe
*p
,
484 struct torture_context
*tctx
,
485 struct policy_handle
*handle
,
486 const struct dom_sid
*sid
)
488 struct security_descriptor
*sd
= NULL
;
491 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
495 if (!sd
|| !sd
->dacl
) {
499 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
500 if (dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) {
508 static bool _test_dacl_trustee_present(struct dcerpc_pipe
*p
,
509 struct torture_context
*tctx
,
510 struct policy_handle
*handle
,
512 const struct dom_sid
*sid
)
514 struct policy_handle new_handle
;
517 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
521 ret
= test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
);
523 test_CloseKey(p
, tctx
, &new_handle
);
528 static bool test_sacl_trustee_present(struct dcerpc_pipe
*p
,
529 struct torture_context
*tctx
,
530 struct policy_handle
*handle
,
531 const struct dom_sid
*sid
)
533 struct security_descriptor
*sd
= NULL
;
535 uint32_t sec_info
= SECINFO_SACL
;
537 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
541 if (!sd
|| !sd
->sacl
) {
545 for (i
= 0; i
< sd
->sacl
->num_aces
; i
++) {
546 if (dom_sid_equal(&sd
->sacl
->aces
[i
].trustee
, sid
)) {
554 static bool _test_sacl_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
;
563 if (!_test_OpenKey(p
, tctx
, handle
, key
, SEC_FLAG_SYSTEM_SECURITY
,
564 &new_handle
, WERR_OK
, NULL
)) {
568 ret
= test_sacl_trustee_present(p
, tctx
, &new_handle
, sid
);
570 test_CloseKey(p
, tctx
, &new_handle
);
575 static bool test_owner_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
;
581 uint32_t sec_info
= SECINFO_OWNER
;
583 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
587 if (!sd
|| !sd
->owner_sid
) {
591 return dom_sid_equal(sd
->owner_sid
, sid
);
594 static bool _test_owner_present(struct dcerpc_pipe
*p
,
595 struct torture_context
*tctx
,
596 struct policy_handle
*handle
,
598 const struct dom_sid
*sid
)
600 struct policy_handle new_handle
;
603 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
607 ret
= test_owner_present(p
, tctx
, &new_handle
, sid
);
609 test_CloseKey(p
, tctx
, &new_handle
);
614 static bool test_group_present(struct dcerpc_pipe
*p
,
615 struct torture_context
*tctx
,
616 struct policy_handle
*handle
,
617 const struct dom_sid
*sid
)
619 struct security_descriptor
*sd
= NULL
;
620 uint32_t sec_info
= SECINFO_GROUP
;
622 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
626 if (!sd
|| !sd
->group_sid
) {
630 return dom_sid_equal(sd
->group_sid
, sid
);
633 static bool _test_group_present(struct dcerpc_pipe
*p
,
634 struct torture_context
*tctx
,
635 struct policy_handle
*handle
,
637 const struct dom_sid
*sid
)
639 struct policy_handle new_handle
;
642 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
646 ret
= test_group_present(p
, tctx
, &new_handle
, sid
);
648 test_CloseKey(p
, tctx
, &new_handle
);
653 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe
*p
,
654 struct torture_context
*tctx
,
655 struct policy_handle
*handle
,
656 const struct dom_sid
*sid
,
659 struct security_descriptor
*sd
= NULL
;
662 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
666 if (!sd
|| !sd
->dacl
) {
670 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
671 if ((dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) &&
672 (sd
->dacl
->aces
[i
].flags
== flags
)) {
680 static bool test_dacl_ace_present(struct dcerpc_pipe
*p
,
681 struct torture_context
*tctx
,
682 struct policy_handle
*handle
,
683 const struct security_ace
*ace
)
685 struct security_descriptor
*sd
= NULL
;
688 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
692 if (!sd
|| !sd
->dacl
) {
696 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
697 if (security_ace_equal(&sd
->dacl
->aces
[i
], ace
)) {
705 static bool test_RestoreSecurity(struct dcerpc_pipe
*p
,
706 struct torture_context
*tctx
,
707 struct policy_handle
*handle
,
709 struct security_descriptor
*sd
)
711 struct policy_handle new_handle
;
714 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
718 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
722 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
729 static bool test_BackupSecurity(struct dcerpc_pipe
*p
,
730 struct torture_context
*tctx
,
731 struct policy_handle
*handle
,
733 struct security_descriptor
**sd
)
735 struct policy_handle new_handle
;
738 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
742 if (!test_GetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
746 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
753 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe
*p
,
754 struct torture_context
*tctx
,
755 struct policy_handle
*handle
,
759 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
774 struct security_descriptor
*sd
= NULL
;
775 struct security_descriptor
*sd_orig
= NULL
;
776 struct security_ace
*ace
= NULL
;
777 struct policy_handle new_handle
;
780 torture_comment(tctx
, "SecurityDescriptor inheritance\n");
782 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
786 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
790 sd_orig
= security_descriptor_copy(tctx
, sd
);
791 if (sd_orig
== NULL
) {
795 ace
= security_ace_create(tctx
,
797 SEC_ACE_TYPE_ACCESS_ALLOWED
,
799 SEC_ACE_FLAG_CONTAINER_INHERIT
);
801 torture_assert_ntstatus_ok(tctx
,
802 security_descriptor_dacl_add(sd
, ace
),
803 "failed to add ace");
805 /* FIXME: add further tests for these flags */
806 sd
->type
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
|
807 SEC_DESC_SACL_AUTO_INHERITED
;
809 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
814 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
815 "new ACE not present!");
817 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
821 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, NULL
)) {
826 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
831 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
832 torture_comment(tctx
, "inherited ACE not present!\n");
837 test_CloseKey(p
, tctx
, &new_handle
);
838 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
843 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
848 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
849 torture_comment(tctx
, "inherited ACE not present!\n");
855 test_CloseKey(p
, tctx
, &new_handle
);
856 test_Cleanup(p
, tctx
, handle
, TEST_SUBKEY_SD
);
857 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
862 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe
*p
,
863 struct torture_context
*tctx
,
864 struct policy_handle
*handle
,
868 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
880 struct security_descriptor
*sd
= NULL
;
881 struct security_descriptor
*sd_orig
= NULL
;
882 struct security_ace
*ace
= NULL
;
883 struct policy_handle new_handle
;
884 struct dom_sid
*sid
= NULL
;
886 uint8_t ace_flags
= 0x0;
888 torture_comment(tctx
, "SecurityDescriptor inheritance block\n");
890 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
894 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
898 sd_orig
= security_descriptor_copy(tctx
, sd
);
899 if (sd_orig
== NULL
) {
903 ace
= security_ace_create(tctx
,
905 SEC_ACE_TYPE_ACCESS_ALLOWED
,
907 SEC_ACE_FLAG_CONTAINER_INHERIT
|
908 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
);
910 torture_assert_ntstatus_ok(tctx
,
911 security_descriptor_dacl_add(sd
, ace
),
912 "failed to add ace");
914 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, NULL
, sd
, WERR_OK
)) {
919 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
920 "new ACE not present!");
922 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
926 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
930 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
935 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
936 torture_comment(tctx
, "inherited ACE present but should not!\n");
941 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
946 if (test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
)) {
947 torture_comment(tctx
, "inherited trustee SID present but should not!\n");
952 test_CloseKey(p
, tctx
, &new_handle
);
954 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
959 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
960 torture_comment(tctx
, "inherited ACE present but should not!\n");
965 if (!test_dacl_trustee_flags_present(p
, tctx
, &new_handle
, sid
, ace_flags
)) {
966 torture_comment(tctx
, "inherited trustee SID with flags 0x%02x not present!\n",
973 test_CloseKey(p
, tctx
, &new_handle
);
974 test_Cleanup(p
, tctx
, handle
, TEST_SUBKEY_SD
);
975 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
980 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe
*p
,
981 struct torture_context
*tctx
,
982 struct policy_handle
*handle
,
988 struct winreg_mask_result_table
{
989 uint32_t access_mask
;
993 } sd_mask_tests
[] = {
995 WERR_ACCESS_DENIED
, WERR_BADFILE
, WERR_FOOBAR
},
996 { SEC_FLAG_MAXIMUM_ALLOWED
,
997 WERR_OK
, WERR_OK
, WERR_OK
},
999 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
},
1000 { SEC_FLAG_SYSTEM_SECURITY
,
1001 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
}
1004 /* FIXME: before this test can ever run successfully we need a way to
1005 * correctly read a NULL security_descritpor in ndr, get the required
1006 * length, requery, etc.
1011 for (i
=0; i
< ARRAY_SIZE(sd_mask_tests
); i
++) {
1013 torture_comment(tctx
,
1014 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1015 sd_mask_tests
[i
].access_mask
);
1016 torture_comment(tctx
,
1017 "expecting: open %s, get: %s, set: %s\n",
1018 win_errstr(sd_mask_tests
[i
].open_werr
),
1019 win_errstr(sd_mask_tests
[i
].get_werr
),
1020 win_errstr(sd_mask_tests
[i
].set_werr
));
1022 if (_test_SecurityDescriptor(p
, tctx
, handle
,
1023 sd_mask_tests
[i
].access_mask
, key
,
1024 sd_mask_tests
[i
].open_werr
,
1025 sd_mask_tests
[i
].get_werr
,
1026 sd_mask_tests
[i
].set_werr
)) {
1034 typedef bool (*secinfo_verify_fn
)(struct dcerpc_pipe
*,
1035 struct torture_context
*,
1036 struct policy_handle
*,
1038 const struct dom_sid
*);
1040 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe
*p
,
1041 struct torture_context
*tctx
,
1042 struct policy_handle
*handle
,
1045 uint32_t access_mask
,
1047 struct security_descriptor
*sd
,
1049 bool expect_present
,
1050 bool (*fn
) (struct dcerpc_pipe
*,
1051 struct torture_context
*,
1052 struct policy_handle
*,
1054 const struct dom_sid
*),
1055 const struct dom_sid
*sid
)
1057 struct policy_handle new_handle
;
1058 bool open_success
= false;
1060 torture_comment(tctx
, "SecurityDescriptor (%s) sets for secinfo: "
1061 "0x%08x, access_mask: 0x%08x\n",
1062 test
, sec_info
, access_mask
);
1064 if (!_test_OpenKey(p
, tctx
, handle
, key
,
1072 if (!open_success
) {
1073 torture_comment(tctx
, "key did not open\n");
1074 test_CloseKey(p
, tctx
, &new_handle
);
1078 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, &sec_info
,
1081 torture_warning(tctx
,
1082 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1085 test_CloseKey(p
, tctx
, &new_handle
);
1089 test_CloseKey(p
, tctx
, &new_handle
);
1091 if (W_ERROR_IS_OK(set_werr
)) {
1093 present
= fn(p
, tctx
, handle
, key
, sid
);
1094 if ((expect_present
) && (!present
)) {
1095 torture_warning(tctx
,
1096 "%s sid is not present!\n",
1100 if ((!expect_present
) && (present
)) {
1101 torture_warning(tctx
,
1102 "%s sid is present but not expected!\n",
1111 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe
*p
,
1112 struct torture_context
*tctx
,
1113 struct policy_handle
*handle
,
1116 struct security_descriptor
*sd_orig
= NULL
;
1117 struct dom_sid
*sid
= NULL
;
1121 struct security_descriptor
*sd_owner
=
1122 security_descriptor_dacl_create(tctx
,
1124 TEST_SID
, NULL
, NULL
);
1126 struct security_descriptor
*sd_group
=
1127 security_descriptor_dacl_create(tctx
,
1129 NULL
, TEST_SID
, NULL
);
1131 struct security_descriptor
*sd_dacl
=
1132 security_descriptor_dacl_create(tctx
,
1136 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1139 SID_NT_AUTHENTICATED_USERS
,
1140 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1145 struct security_descriptor
*sd_sacl
=
1146 security_descriptor_sacl_create(tctx
,
1150 SEC_ACE_TYPE_SYSTEM_AUDIT
,
1152 SEC_ACE_FLAG_SUCCESSFUL_ACCESS
,
1155 struct winreg_secinfo_table
{
1156 struct security_descriptor
*sd
;
1160 secinfo_verify_fn fn
;
1163 struct winreg_secinfo_table sec_info_owner_tests
[] = {
1164 { sd_owner
, 0, WERR_OK
,
1165 false, (secinfo_verify_fn
)_test_owner_present
},
1166 { sd_owner
, SECINFO_OWNER
, WERR_OK
,
1167 true, (secinfo_verify_fn
)_test_owner_present
},
1168 { sd_owner
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1169 { sd_owner
, SECINFO_DACL
, WERR_OK
,
1170 true, (secinfo_verify_fn
)_test_owner_present
},
1171 { sd_owner
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1174 uint32_t sd_owner_good_access_masks
[] = {
1175 SEC_FLAG_MAXIMUM_ALLOWED
,
1176 /* SEC_STD_WRITE_OWNER, */
1179 struct winreg_secinfo_table sec_info_group_tests
[] = {
1180 { sd_group
, 0, WERR_OK
,
1181 false, (secinfo_verify_fn
)_test_group_present
},
1182 { sd_group
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1183 { sd_group
, SECINFO_GROUP
, WERR_OK
,
1184 true, (secinfo_verify_fn
)_test_group_present
},
1185 { sd_group
, SECINFO_DACL
, WERR_OK
,
1186 true, (secinfo_verify_fn
)_test_group_present
},
1187 { sd_group
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1190 uint32_t sd_group_good_access_masks
[] = {
1191 SEC_FLAG_MAXIMUM_ALLOWED
,
1194 struct winreg_secinfo_table sec_info_dacl_tests
[] = {
1195 { sd_dacl
, 0, WERR_OK
,
1196 false, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1197 { sd_dacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1198 { sd_dacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1199 { sd_dacl
, SECINFO_DACL
, WERR_OK
,
1200 true, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1201 { sd_dacl
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1204 uint32_t sd_dacl_good_access_masks
[] = {
1205 SEC_FLAG_MAXIMUM_ALLOWED
,
1209 struct winreg_secinfo_table sec_info_sacl_tests
[] = {
1210 { sd_sacl
, 0, WERR_OK
,
1211 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1212 { sd_sacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1213 { sd_sacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1214 { sd_sacl
, SECINFO_DACL
, WERR_OK
,
1215 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1216 { sd_sacl
, SECINFO_SACL
, WERR_OK
,
1217 true, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1220 uint32_t sd_sacl_good_access_masks
[] = {
1221 SEC_FLAG_MAXIMUM_ALLOWED
| SEC_FLAG_SYSTEM_SECURITY
,
1222 /* SEC_FLAG_SYSTEM_SECURITY, */
1225 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1230 if (!test_BackupSecurity(p
, tctx
, handle
, key
, &sd_orig
)) {
1236 for (i
=0; i
< ARRAY_SIZE(sec_info_owner_tests
); i
++) {
1238 for (a
=0; a
< ARRAY_SIZE(sd_owner_good_access_masks
); a
++) {
1240 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1243 sd_owner_good_access_masks
[a
],
1244 sec_info_owner_tests
[i
].sec_info
,
1245 sec_info_owner_tests
[i
].sd
,
1246 sec_info_owner_tests
[i
].set_werr
,
1247 sec_info_owner_tests
[i
].sid_present
,
1248 sec_info_owner_tests
[i
].fn
,
1251 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1260 for (i
=0; i
< ARRAY_SIZE(sec_info_group_tests
); i
++) {
1262 for (a
=0; a
< ARRAY_SIZE(sd_group_good_access_masks
); a
++) {
1264 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1267 sd_group_good_access_masks
[a
],
1268 sec_info_group_tests
[i
].sec_info
,
1269 sec_info_group_tests
[i
].sd
,
1270 sec_info_group_tests
[i
].set_werr
,
1271 sec_info_group_tests
[i
].sid_present
,
1272 sec_info_group_tests
[i
].fn
,
1275 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1284 for (i
=0; i
< ARRAY_SIZE(sec_info_dacl_tests
); i
++) {
1286 for (a
=0; a
< ARRAY_SIZE(sd_dacl_good_access_masks
); a
++) {
1288 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1291 sd_dacl_good_access_masks
[a
],
1292 sec_info_dacl_tests
[i
].sec_info
,
1293 sec_info_dacl_tests
[i
].sd
,
1294 sec_info_dacl_tests
[i
].set_werr
,
1295 sec_info_dacl_tests
[i
].sid_present
,
1296 sec_info_dacl_tests
[i
].fn
,
1299 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1308 for (i
=0; i
< ARRAY_SIZE(sec_info_sacl_tests
); i
++) {
1310 for (a
=0; a
< ARRAY_SIZE(sd_sacl_good_access_masks
); a
++) {
1312 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1315 sd_sacl_good_access_masks
[a
],
1316 sec_info_sacl_tests
[i
].sec_info
,
1317 sec_info_sacl_tests
[i
].sd
,
1318 sec_info_sacl_tests
[i
].set_werr
,
1319 sec_info_sacl_tests
[i
].sid_present
,
1320 sec_info_sacl_tests
[i
].fn
,
1323 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1331 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1336 static bool test_SecurityDescriptors(struct dcerpc_pipe
*p
,
1337 struct torture_context
*tctx
,
1338 struct policy_handle
*handle
,
1343 if (!test_SecurityDescriptor(p
, tctx
, handle
, key
)) {
1344 torture_comment(tctx
, "test_SecurityDescriptor failed\n");
1348 if (!test_SecurityDescriptorInheritance(p
, tctx
, handle
, key
)) {
1349 torture_comment(tctx
, "test_SecurityDescriptorInheritance failed\n");
1353 if (!test_SecurityDescriptorBlockInheritance(p
, tctx
, handle
, key
)) {
1354 torture_comment(tctx
, "test_SecurityDescriptorBlockInheritance failed\n");
1358 if (!test_SecurityDescriptorsSecInfo(p
, tctx
, handle
, key
)) {
1359 torture_comment(tctx
, "test_SecurityDescriptorsSecInfo failed\n");
1363 if (!test_SecurityDescriptorsMasks(p
, tctx
, handle
, key
)) {
1364 torture_comment(tctx
, "test_SecurityDescriptorsMasks failed\n");
1371 static bool test_DeleteKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1372 struct policy_handle
*handle
, const char *key
)
1375 struct winreg_DeleteKey r
;
1377 r
.in
.handle
= handle
;
1378 init_winreg_String(&r
.in
.key
, key
);
1380 status
= dcerpc_winreg_DeleteKey(p
, tctx
, &r
);
1382 torture_assert_ntstatus_ok(tctx
, status
, "DeleteKey failed");
1383 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeleteKey failed");
1388 static bool test_QueryInfoKey(struct dcerpc_pipe
*p
,
1389 struct torture_context
*tctx
,
1390 struct policy_handle
*handle
, char *kclass
)
1392 struct winreg_QueryInfoKey r
;
1393 uint32_t num_subkeys
, max_subkeylen
, max_classlen
,
1394 num_values
, max_valnamelen
, max_valbufsize
,
1396 NTTIME last_changed_time
;
1399 r
.in
.handle
= handle
;
1400 r
.out
.num_subkeys
= &num_subkeys
;
1401 r
.out
.max_subkeylen
= &max_subkeylen
;
1402 r
.out
.max_classlen
= &max_classlen
;
1403 r
.out
.num_values
= &num_values
;
1404 r
.out
.max_valnamelen
= &max_valnamelen
;
1405 r
.out
.max_valbufsize
= &max_valbufsize
;
1406 r
.out
.secdescsize
= &secdescsize
;
1407 r
.out
.last_changed_time
= &last_changed_time
;
1409 r
.out
.classname
= talloc(tctx
, struct winreg_String
);
1411 r
.in
.classname
= talloc(tctx
, struct winreg_String
);
1412 init_winreg_String(r
.in
.classname
, kclass
);
1414 torture_assert_ntstatus_ok(tctx
,
1415 dcerpc_winreg_QueryInfoKey(p
, tctx
, &r
),
1416 "QueryInfoKey failed");
1418 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryInfoKey failed");
1423 static bool test_SetValue(struct dcerpc_pipe
*p
,
1424 struct torture_context
*tctx
,
1425 struct policy_handle
*handle
,
1426 const char *value_name
,
1427 enum winreg_Type type
,
1431 struct winreg_SetValue r
;
1432 struct winreg_String name
;
1434 torture_comment(tctx
, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1435 value_name
, str_regtype(type
), size
);
1437 init_winreg_String(&name
, value_name
);
1439 r
.in
.handle
= handle
;
1445 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_SetValue(p
, tctx
, &r
),
1446 "winreg_SetValue failed");
1447 torture_assert_werr_ok(tctx
, r
.out
.result
,
1448 "winreg_SetValue failed");
1453 static bool test_DeleteValue(struct dcerpc_pipe
*p
,
1454 struct torture_context
*tctx
,
1455 struct policy_handle
*handle
,
1456 const char *value_name
)
1458 struct winreg_DeleteValue r
;
1459 struct winreg_String value
;
1461 torture_comment(tctx
, "Testing DeleteValue(%s)\n", value_name
);
1463 init_winreg_String(&value
, value_name
);
1465 r
.in
.handle
= handle
;
1468 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteValue(p
, tctx
, &r
),
1469 "winreg_DeleteValue failed");
1470 torture_assert_werr_ok(tctx
, r
.out
.result
,
1471 "winreg_DeleteValue failed");
1476 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1477 struct policy_handle
*handle
, int depth
,
1478 bool test_security
);
1480 static bool test_EnumKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1481 struct policy_handle
*handle
, int depth
,
1484 struct winreg_EnumKey r
;
1485 struct winreg_StringBuf kclass
, name
;
1493 r
.in
.handle
= handle
;
1494 r
.in
.enum_index
= 0;
1496 r
.in
.keyclass
= &kclass
;
1498 r
.in
.last_changed_time
= &t
;
1504 status
= dcerpc_winreg_EnumKey(p
, tctx
, &r
);
1506 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
1507 struct policy_handle key_handle
;
1509 torture_comment(tctx
, "EnumKey: %d: %s\n",
1513 if (!test_OpenKey(p
, tctx
, handle
, r
.out
.name
->name
,
1516 test_key(p
, tctx
, &key_handle
,
1517 depth
+ 1, test_security
);
1523 } while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
));
1525 torture_assert_ntstatus_ok(tctx
, status
, "EnumKey failed");
1527 if (!W_ERROR_IS_OK(r
.out
.result
) &&
1528 !W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
1529 torture_fail(tctx
, "EnumKey failed");
1535 static bool test_QueryMultipleValues(struct dcerpc_pipe
*p
,
1536 struct torture_context
*tctx
,
1537 struct policy_handle
*handle
,
1538 const char *valuename
)
1540 struct winreg_QueryMultipleValues r
;
1545 r
.in
.key_handle
= handle
;
1546 r
.in
.values
= r
.out
.values
= talloc_array(tctx
, struct QueryMultipleValue
, 1);
1547 r
.in
.values
[0].name
= talloc(tctx
, struct winreg_String
);
1548 r
.in
.values
[0].name
->name
= valuename
;
1549 r
.in
.values
[0].offset
= 0;
1550 r
.in
.values
[0].length
= 0;
1551 r
.in
.values
[0].type
= 0;
1553 r
.in
.num_values
= 1;
1554 r
.in
.buffer_size
= r
.out
.buffer_size
= talloc(tctx
, uint32_t);
1555 *r
.in
.buffer_size
= bufsize
;
1557 *r
.in
.buffer_size
= bufsize
;
1558 r
.in
.buffer
= r
.out
.buffer
= talloc_zero_array(tctx
, uint8_t,
1561 status
= dcerpc_winreg_QueryMultipleValues(p
, tctx
, &r
);
1563 if(NT_STATUS_IS_ERR(status
))
1564 torture_fail(tctx
, "QueryMultipleValues failed");
1566 talloc_free(r
.in
.buffer
);
1568 } while (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
));
1570 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryMultipleValues failed");
1575 static bool test_QueryValue(struct dcerpc_pipe
*p
,
1576 struct torture_context
*tctx
,
1577 struct policy_handle
*handle
,
1578 const char *valuename
)
1580 struct winreg_QueryValue r
;
1582 enum winreg_Type zero_type
= 0;
1583 uint32_t offered
= 0xfff;
1587 r
.in
.handle
= handle
;
1589 r
.in
.value_name
= talloc_zero(tctx
, struct winreg_String
);
1590 r
.in
.value_name
->name
= valuename
;
1591 r
.in
.type
= &zero_type
;
1592 r
.in
.data_size
= &offered
;
1593 r
.in
.data_length
= &zero
;
1595 status
= dcerpc_winreg_QueryValue(p
, tctx
, &r
);
1596 if (NT_STATUS_IS_ERR(status
)) {
1597 torture_fail(tctx
, "QueryValue failed");
1600 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
1605 static bool test_QueryValue_full(struct dcerpc_pipe
*p
,
1606 struct torture_context
*tctx
,
1607 struct policy_handle
*handle
,
1608 const char *valuename
,
1609 bool existing_value
)
1611 struct winreg_QueryValue r
;
1612 struct winreg_String value_name
;
1613 enum winreg_Type type
= REG_NONE
;
1614 uint32_t data_size
= 0;
1615 uint32_t real_data_size
= 0;
1616 uint32_t data_length
= 0;
1617 uint8_t *data
= NULL
;
1618 WERROR expected_error
= WERR_BADFILE
;
1620 if (valuename
== NULL
) {
1621 expected_error
= WERR_INVALID_PARAM
;
1626 init_winreg_String(&value_name
, NULL
);
1628 torture_comment(tctx
, "Testing QueryValue(%s)\n", valuename
);
1630 r
.in
.handle
= handle
;
1631 r
.in
.value_name
= &value_name
;
1633 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
), "QueryValue failed");
1634 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1635 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1637 init_winreg_String(&value_name
, valuename
);
1638 r
.in
.value_name
= &value_name
;
1640 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1641 "QueryValue failed");
1642 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1643 "QueryValue failed");
1647 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1648 "QueryValue failed");
1649 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1650 "QueryValue failed");
1652 r
.in
.data_length
= &data_length
;
1653 r
.out
.data_length
= &data_length
;
1654 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1655 "QueryValue failed");
1656 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1657 "QueryValue failed");
1659 r
.in
.data_size
= &data_size
;
1660 r
.out
.data_size
= &data_size
;
1661 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1662 "QueryValue failed");
1663 if (existing_value
) {
1664 torture_assert_werr_ok(tctx
, r
.out
.result
,
1665 "QueryValue failed");
1667 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1668 "QueryValue failed");
1671 real_data_size
= *r
.out
.data_size
;
1673 data
= talloc_zero_array(tctx
, uint8_t, 0);
1676 *r
.in
.data_size
= 0;
1677 *r
.out
.data_size
= 0;
1678 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1679 "QueryValue failed");
1680 if (existing_value
) {
1681 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_MORE_DATA
,
1682 "QueryValue failed");
1684 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1685 "QueryValue failed");
1688 data
= talloc_zero_array(tctx
, uint8_t, real_data_size
);
1691 r
.in
.data_size
= &real_data_size
;
1692 r
.out
.data_size
= &real_data_size
;
1693 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1694 "QueryValue failed");
1695 if (existing_value
) {
1696 torture_assert_werr_ok(tctx
, r
.out
.result
,
1697 "QueryValue failed");
1699 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1700 "QueryValue failed");
1706 static bool test_EnumValue(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1707 struct policy_handle
*handle
, int max_valnamelen
,
1710 struct winreg_EnumValue r
;
1711 enum winreg_Type type
= 0;
1712 uint32_t size
= max_valbufsize
, zero
= 0;
1715 struct winreg_ValNameBuf name
;
1721 r
.in
.handle
= handle
;
1722 r
.in
.enum_index
= 0;
1727 r
.in
.length
= &zero
;
1731 torture_assert_ntstatus_ok(tctx
,
1732 dcerpc_winreg_EnumValue(p
, tctx
, &r
),
1733 "EnumValue failed");
1735 if (W_ERROR_IS_OK(r
.out
.result
)) {
1736 ret
&= test_QueryValue(p
, tctx
, handle
,
1738 ret
&= test_QueryMultipleValues(p
, tctx
, handle
,
1743 } while (W_ERROR_IS_OK(r
.out
.result
));
1745 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NO_MORE_ITEMS
,
1746 "EnumValue failed");
1751 static bool test_AbortSystemShutdown(struct dcerpc_pipe
*p
,
1752 struct torture_context
*tctx
)
1754 struct winreg_AbortSystemShutdown r
;
1755 uint16_t server
= 0x0;
1758 r
.in
.server
= &server
;
1760 torture_assert_ntstatus_ok(tctx
,
1761 dcerpc_winreg_AbortSystemShutdown(p
, tctx
, &r
),
1762 "AbortSystemShutdown failed");
1764 torture_assert_werr_ok(tctx
, r
.out
.result
,
1765 "AbortSystemShutdown failed");
1770 static bool test_InitiateSystemShutdown(struct torture_context
*tctx
,
1771 struct dcerpc_pipe
*p
)
1773 struct winreg_InitiateSystemShutdown r
;
1774 uint16_t hostname
= 0x0;
1777 r
.in
.hostname
= &hostname
;
1778 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1779 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1780 r
.in
.force_apps
= 1;
1784 torture_assert_ntstatus_ok(tctx
,
1785 dcerpc_winreg_InitiateSystemShutdown(p
, tctx
, &r
),
1786 "InitiateSystemShutdown failed");
1788 torture_assert_werr_ok(tctx
, r
.out
.result
,
1789 "InitiateSystemShutdown failed");
1791 return test_AbortSystemShutdown(p
, tctx
);
1795 static bool test_InitiateSystemShutdownEx(struct torture_context
*tctx
,
1796 struct dcerpc_pipe
*p
)
1798 struct winreg_InitiateSystemShutdownEx r
;
1799 uint16_t hostname
= 0x0;
1802 r
.in
.hostname
= &hostname
;
1803 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1804 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1805 r
.in
.force_apps
= 1;
1810 torture_assert_ntstatus_ok(tctx
,
1811 dcerpc_winreg_InitiateSystemShutdownEx(p
, tctx
, &r
),
1812 "InitiateSystemShutdownEx failed");
1814 torture_assert_werr_ok(tctx
, r
.out
.result
,
1815 "InitiateSystemShutdownEx failed");
1817 return test_AbortSystemShutdown(p
, tctx
);
1819 #define MAX_DEPTH 2 /* Only go this far down the tree */
1821 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1822 struct policy_handle
*handle
, int depth
,
1825 if (depth
== MAX_DEPTH
)
1828 if (!test_QueryInfoKey(p
, tctx
, handle
, NULL
)) {
1831 if (!test_NotifyChangeKeyValue(p
, tctx
, handle
)) {
1834 if (test_security
&& !test_GetKeySecurity(p
, tctx
, handle
, NULL
)) {
1837 if (!test_EnumKey(p
, tctx
, handle
, depth
, test_security
)) {
1840 if (!test_EnumValue(p
, tctx
, handle
, 0xFF, 0xFFFF)) {
1843 test_CloseKey(p
, tctx
, handle
);
1848 static bool test_SetValue_simple(struct dcerpc_pipe
*p
,
1849 struct torture_context
*tctx
,
1850 struct policy_handle
*handle
)
1852 const char *value_name
= TEST_VALUE
;
1853 uint32_t value
= 0x12345678;
1854 const char *string
= "torture";
1856 enum winreg_Type types
[] = {
1864 torture_comment(tctx
, "Testing SetValue (standard formats)\n");
1866 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
1868 enum winreg_Type w_type
;
1869 uint32_t w_size
, w_length
;
1874 blob
= data_blob_talloc_zero(tctx
, 4);
1875 SIVAL(blob
.data
, 0, value
);
1878 blob
= data_blob_string_const("binary_blob");
1881 torture_assert(tctx
,
1882 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1886 (void **)&blob
.data
,
1891 torture_assert(tctx
,
1892 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1896 (void **)&blob
.data
,
1899 torture_assert(tctx
, data_blob_realloc(tctx
, &blob
, blob
.length
+ 2), "");
1900 memset(&blob
.data
[blob
.length
- 2], '\0', 2);
1906 torture_assert(tctx
,
1907 test_SetValue(p
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
1908 "test_SetValue failed");
1909 torture_assert(tctx
,
1910 test_QueryValue_full(p
, tctx
, handle
, value_name
, true),
1911 talloc_asprintf(tctx
, "test_QueryValue_full for %s value failed", value_name
));
1912 torture_assert(tctx
,
1913 test_winreg_QueryValue(tctx
, p
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
1914 "test_winreg_QueryValue failed");
1915 torture_assert(tctx
,
1916 test_DeleteValue(p
, tctx
, handle
, value_name
),
1917 "test_DeleteValue failed");
1919 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
1920 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
1921 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
1922 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
1925 torture_comment(tctx
, "Testing SetValue (standard formats) succeeded\n");
1930 typedef NTSTATUS (*winreg_open_fn
)(struct dcerpc_pipe
*, TALLOC_CTX
*, void *);
1932 static bool test_Open_Security(struct torture_context
*tctx
,
1933 struct dcerpc_pipe
*p
, void *userdata
)
1935 struct policy_handle handle
, newhandle
;
1936 bool ret
= true, created2
= false;
1937 bool created4
= false;
1938 struct winreg_OpenHKLM r
;
1940 winreg_open_fn open_fn
= userdata
;
1943 r
.in
.system_name
= 0;
1944 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1945 r
.out
.handle
= &handle
;
1947 torture_assert_ntstatus_ok(tctx
, open_fn(p
, tctx
, &r
),
1950 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
1952 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
1953 torture_comment(tctx
,
1954 "CreateKey (TEST_KEY_BASE) failed\n");
1957 if (test_CreateKey_sd(p
, tctx
, &handle
, TEST_KEY2
,
1958 NULL
, &newhandle
)) {
1962 if (created2
&& !test_CloseKey(p
, tctx
, &newhandle
)) {
1963 torture_comment(tctx
, "CloseKey failed\n");
1967 if (test_CreateKey_sd(p
, tctx
, &handle
, TEST_KEY4
, NULL
, &newhandle
)) {
1971 if (created4
&& !test_CloseKey(p
, tctx
, &newhandle
)) {
1972 torture_comment(tctx
, "CloseKey failed\n");
1976 if (created4
&& !test_SecurityDescriptors(p
, tctx
, &handle
, TEST_KEY4
)) {
1980 if (created4
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY4
)) {
1981 torture_comment(tctx
, "DeleteKey failed\n");
1985 if (created2
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY2
)) {
1986 torture_comment(tctx
, "DeleteKey failed\n");
1990 /* The HKCR hive has a very large fanout */
1991 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR
) {
1992 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, true)) {
1996 if (!test_key(p
, tctx
, &handle
, 0, true)) {
2001 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2006 static bool test_SetValue_extended(struct dcerpc_pipe
*p
,
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
;
2048 const char *string
= generate_random_str(tctx
, l
);
2049 DATA_BLOB blob
= data_blob_string_const(string
);
2051 torture_assert(tctx
,
2052 test_SetValue(p
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
2053 "test_SetValue failed");
2055 torture_assert(tctx
,
2056 test_winreg_QueryValue(tctx
, p
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2057 "test_winreg_QueryValue failed");
2059 torture_assert(tctx
,
2060 test_DeleteValue(p
, tctx
, handle
, value_name
),
2061 "test_DeleteValue failed");
2063 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
2064 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
2065 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
2066 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
2070 torture_comment(tctx
, "Testing SetValue (extended formats) succeeded\n");
2075 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2076 #define VALUE_CURRENT_VERSION "CurrentVersion"
2078 static bool test_Open(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2081 struct policy_handle handle
, newhandle
;
2082 bool ret
= true, created
= false, deleted
= false;
2083 bool created3
= false, created_subkey
= false;
2084 struct winreg_OpenHKLM r
;
2086 winreg_open_fn open_fn
= userdata
;
2089 r
.in
.system_name
= 0;
2090 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2091 r
.out
.handle
= &handle
;
2093 torture_assert_ntstatus_ok(tctx
, open_fn(p
, tctx
, &r
),
2096 if (open_fn
== (void *)dcerpc_winreg_OpenHKLM
) {
2098 torture_assert(tctx
, test_OpenKey(p
, tctx
, &handle
, KEY_CURRENT_VERSION
, &newhandle
),
2099 "failed to open current version key");
2101 torture_assert(tctx
, _test_OpenKey(p
, tctx
, &handle
, KEY_CURRENT_VERSION
, KEY_QUERY_VALUE
, &newhandle
, WERR_OK
, NULL
),
2102 "failed to open current version key");
2104 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, VALUE_CURRENT_VERSION
, true),
2105 "failed to query current version");
2106 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, "IDoNotExist", false),
2107 "failed to query current version");
2108 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, NULL
, false),
2109 "test_QueryValue_full for NULL value failed");
2110 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, "", false),
2111 "test_QueryValue_full for \"\" value failed");
2113 torture_assert(tctx
, test_CloseKey(p
, tctx
, &newhandle
),
2114 "failed to close current version key");
2117 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2119 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2120 torture_comment(tctx
,
2121 "CreateKey (TEST_KEY_BASE) failed\n");
2124 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY1
, NULL
)) {
2125 torture_comment(tctx
,
2126 "CreateKey failed - not considering a failure\n");
2131 if (created
&& !test_FlushKey(p
, tctx
, &handle
)) {
2132 torture_comment(tctx
, "FlushKey failed\n");
2136 if (created
&& !test_OpenKey(p
, tctx
, &handle
, TEST_KEY1
, &newhandle
))
2138 "CreateKey failed (OpenKey after Create didn't work)\n");
2141 torture_assert(tctx
, test_SetValue_simple(p
, tctx
, &newhandle
),
2142 "simple SetValue test failed");
2143 torture_assert(tctx
, test_SetValue_extended(p
, tctx
, &newhandle
),
2144 "extended SetValue test failed");
2147 if (created
&& !test_CloseKey(p
, tctx
, &newhandle
))
2149 "CreateKey failed (CloseKey after Open didn't work)\n");
2151 if (created
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY1
)) {
2152 torture_comment(tctx
, "DeleteKey failed\n");
2158 if (created
&& !test_FlushKey(p
, tctx
, &handle
)) {
2159 torture_comment(tctx
, "FlushKey failed\n");
2163 if (created
&& deleted
&&
2164 !_test_OpenKey(p
, tctx
, &handle
, TEST_KEY1
,
2165 SEC_FLAG_MAXIMUM_ALLOWED
, &newhandle
,
2166 WERR_BADFILE
, NULL
)) {
2167 torture_comment(tctx
,
2168 "DeleteKey failed (OpenKey after Delete "
2169 "did not return WERR_BADFILE)\n");
2173 if (!test_GetVersion(p
, tctx
, &handle
)) {
2174 torture_comment(tctx
, "GetVersion failed\n");
2178 if (created
&& test_CreateKey(p
, tctx
, &handle
, TEST_KEY3
, NULL
)) {
2183 test_CreateKey(p
, tctx
, &handle
, TEST_SUBKEY
, NULL
)) {
2184 created_subkey
= true;
2187 if (created_subkey
&&
2188 !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY3
)) {
2189 torture_comment(tctx
, "DeleteKey failed\n");
2193 /* The HKCR hive has a very large fanout */
2194 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR
) {
2195 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, false)) {
2199 if (!test_key(p
, tctx
, &handle
, 0, false)) {
2204 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2209 struct torture_suite
*torture_rpc_winreg(TALLOC_CTX
*mem_ctx
)
2211 struct torture_rpc_tcase
*tcase
;
2212 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WINREG");
2213 struct torture_test
*test
;
2215 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "winreg",
2218 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdown",
2219 test_InitiateSystemShutdown
);
2220 test
->dangerous
= true;
2222 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdownEx",
2223 test_InitiateSystemShutdownEx
);
2224 test
->dangerous
= true;
2226 /* Basic tests without security descriptors */
2227 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-basic",
2229 (winreg_open_fn
)dcerpc_winreg_OpenHKLM
);
2230 torture_rpc_tcase_add_test_ex(tcase
, "HKU-basic",
2232 (winreg_open_fn
)dcerpc_winreg_OpenHKU
);
2233 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-basic",
2235 (winreg_open_fn
)dcerpc_winreg_OpenHKCR
);
2236 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-basic",
2238 (winreg_open_fn
)dcerpc_winreg_OpenHKCU
);
2240 /* Security descriptor tests */
2241 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-security",
2243 (winreg_open_fn
)dcerpc_winreg_OpenHKLM
);
2244 torture_rpc_tcase_add_test_ex(tcase
, "HKU-security",
2246 (winreg_open_fn
)dcerpc_winreg_OpenHKU
);
2247 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-security",
2249 (winreg_open_fn
)dcerpc_winreg_OpenHKCR
);
2250 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-security",
2252 (winreg_open_fn
)dcerpc_winreg_OpenHKCU
);