2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "smbtorture test"
32 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
33 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
34 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
35 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
36 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
37 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
38 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
41 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
43 static void init_lsa_StringLarge(struct lsa_StringLarge
*name
, const char *s
)
48 static void init_winreg_String(struct winreg_String
*name
, const char *s
)
52 name
->name_len
= 2 * (strlen_m(s
) + 1);
53 name
->name_size
= name
->name_len
;
60 static bool test_GetVersion(struct dcerpc_pipe
*p
,
61 struct torture_context
*tctx
,
62 struct policy_handle
*handle
)
64 struct winreg_GetVersion r
;
71 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_GetVersion(p
, tctx
, &r
),
74 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetVersion failed");
79 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe
*p
,
80 struct torture_context
*tctx
,
81 struct policy_handle
*handle
)
83 struct winreg_NotifyChangeKeyValue r
;
87 r
.in
.watch_subtree
= true;
88 r
.in
.notify_filter
= 0;
89 r
.in
.unknown
= r
.in
.unknown2
= 0;
90 init_winreg_String(&r
.in
.string1
, NULL
);
91 init_winreg_String(&r
.in
.string2
, NULL
);
93 if (torture_setting_bool(tctx
, "samba3", false)) {
94 torture_skip(tctx
, "skipping NotifyChangeKeyValue test against Samba 3");
97 torture_assert_ntstatus_ok(tctx
,
98 dcerpc_winreg_NotifyChangeKeyValue(p
, tctx
, &r
),
99 "NotifyChangeKeyValue failed");
101 if (!W_ERROR_IS_OK(r
.out
.result
)) {
102 torture_comment(tctx
,
103 "NotifyChangeKeyValue failed - %s - not considering\n",
104 win_errstr(r
.out
.result
));
111 static bool test_CreateKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
112 struct policy_handle
*handle
, const char *name
,
115 struct winreg_CreateKey r
;
116 struct policy_handle newhandle
;
117 enum winreg_CreateAction action_taken
= 0;
120 r
.in
.handle
= handle
;
121 r
.out
.new_handle
= &newhandle
;
122 init_winreg_String(&r
.in
.name
, name
);
123 init_winreg_String(&r
.in
.keyclass
, kclass
);
125 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
126 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
129 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey(p
, tctx
, &r
),
132 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey failed");
139 createkey testing with a SD
141 static bool test_CreateKey_sd(struct dcerpc_pipe
*p
,
142 struct torture_context
*tctx
,
143 struct policy_handle
*handle
, const char *name
,
145 struct policy_handle
*newhandle
)
147 struct winreg_CreateKey r
;
148 enum winreg_CreateAction action_taken
= 0;
149 struct security_descriptor
*sd
;
151 struct winreg_SecBuf secbuf
;
153 sd
= security_descriptor_dacl_create(tctx
,
156 SID_NT_AUTHENTICATED_USERS
,
157 SEC_ACE_TYPE_ACCESS_ALLOWED
,
159 SEC_ACE_FLAG_OBJECT_INHERIT
|
160 SEC_ACE_FLAG_CONTAINER_INHERIT
,
163 torture_assert_ndr_success(tctx
,
164 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
165 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
166 "Failed to push security_descriptor ?!\n");
168 secbuf
.sd
.data
= sdblob
.data
;
169 secbuf
.sd
.len
= sdblob
.length
;
170 secbuf
.sd
.size
= sdblob
.length
;
171 secbuf
.length
= sdblob
.length
-10;
175 r
.in
.handle
= handle
;
176 r
.out
.new_handle
= newhandle
;
177 init_winreg_String(&r
.in
.name
, name
);
178 init_winreg_String(&r
.in
.keyclass
, kclass
);
180 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
181 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
182 r
.in
.secdesc
= &secbuf
;
184 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey(p
, tctx
, &r
),
185 "CreateKey with sd failed");
187 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey with sd failed");
192 static bool _test_GetKeySecurity(struct dcerpc_pipe
*p
,
193 struct torture_context
*tctx
,
194 struct policy_handle
*handle
,
195 uint32_t *sec_info_ptr
,
197 struct security_descriptor
**sd_out
)
199 struct winreg_GetKeySecurity r
;
200 struct security_descriptor
*sd
= NULL
;
205 sec_info
= *sec_info_ptr
;
207 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
212 r
.in
.handle
= handle
;
213 r
.in
.sec_info
= sec_info
;
214 r
.in
.sd
= r
.out
.sd
= talloc_zero(tctx
, struct KeySecurityData
);
215 r
.in
.sd
->size
= 0x1000;
217 torture_assert_ntstatus_ok(tctx
,
218 dcerpc_winreg_GetKeySecurity(p
, tctx
, &r
),
219 "GetKeySecurity failed");
221 torture_assert_werr_equal(tctx
, r
.out
.result
, get_werr
,
222 "GetKeySecurity failed");
224 sdblob
.data
= r
.out
.sd
->data
;
225 sdblob
.length
= r
.out
.sd
->len
;
227 sd
= talloc_zero(tctx
, struct security_descriptor
);
229 torture_assert_ndr_success(tctx
,
230 ndr_pull_struct_blob(&sdblob
, tctx
, NULL
, sd
,
231 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
),
232 "pull_security_descriptor failed");
234 if (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
) {
235 NDR_PRINT_DEBUG(security_descriptor
, sd
);
247 static bool test_GetKeySecurity(struct dcerpc_pipe
*p
,
248 struct torture_context
*tctx
,
249 struct policy_handle
*handle
,
250 struct security_descriptor
**sd_out
)
252 return _test_GetKeySecurity(p
, tctx
, handle
, NULL
, WERR_OK
, sd_out
);
255 static bool _test_SetKeySecurity(struct dcerpc_pipe
*p
,
256 struct torture_context
*tctx
,
257 struct policy_handle
*handle
,
258 uint32_t *sec_info_ptr
,
259 struct security_descriptor
*sd
,
262 struct winreg_SetKeySecurity r
;
263 struct KeySecurityData
*sdata
= NULL
;
269 if (sd
&& (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
)) {
270 NDR_PRINT_DEBUG(security_descriptor
, sd
);
273 torture_assert_ndr_success(tctx
,
274 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
275 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
276 "push_security_descriptor failed");
278 sdata
= talloc_zero(tctx
, struct KeySecurityData
);
279 sdata
->data
= sdblob
.data
;
280 sdata
->size
= sdblob
.length
;
281 sdata
->len
= sdblob
.length
;
284 sec_info
= *sec_info_ptr
;
286 sec_info
= SECINFO_UNPROTECTED_SACL
|
287 SECINFO_UNPROTECTED_DACL
;
289 sec_info
|= SECINFO_OWNER
;
292 sec_info
|= SECINFO_GROUP
;
295 sec_info
|= SECINFO_SACL
;
298 sec_info
|= SECINFO_DACL
;
302 r
.in
.handle
= handle
;
303 r
.in
.sec_info
= sec_info
;
306 torture_assert_ntstatus_ok(tctx
,
307 dcerpc_winreg_SetKeySecurity(p
, tctx
, &r
),
308 "SetKeySecurity failed");
310 torture_assert_werr_equal(tctx
, r
.out
.result
, werr
,
311 "SetKeySecurity failed");
316 static bool test_SetKeySecurity(struct dcerpc_pipe
*p
,
317 struct torture_context
*tctx
,
318 struct policy_handle
*handle
,
319 struct security_descriptor
*sd
)
321 return _test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, WERR_OK
);
324 static bool test_CloseKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
325 struct policy_handle
*handle
)
327 struct winreg_CloseKey r
;
330 r
.in
.handle
= r
.out
.handle
= handle
;
332 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CloseKey(p
, tctx
, &r
),
335 torture_assert_werr_ok(tctx
, r
.out
.result
, "CloseKey failed");
340 static bool test_FlushKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
341 struct policy_handle
*handle
)
343 struct winreg_FlushKey r
;
346 r
.in
.handle
= handle
;
348 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_FlushKey(p
, tctx
, &r
),
351 torture_assert_werr_ok(tctx
, r
.out
.result
, "FlushKey failed");
356 static bool _test_OpenKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
357 struct policy_handle
*hive_handle
,
358 const char *keyname
, uint32_t access_mask
,
359 struct policy_handle
*key_handle
,
363 struct winreg_OpenKey r
;
366 r
.in
.parent_handle
= hive_handle
;
367 init_winreg_String(&r
.in
.keyname
, keyname
);
368 r
.in
.options
= REG_KEYTYPE_NON_VOLATILE
;
369 r
.in
.access_mask
= access_mask
;
370 r
.out
.handle
= key_handle
;
372 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenKey(p
, tctx
, &r
),
375 torture_assert_werr_equal(tctx
, r
.out
.result
, open_werr
,
378 if (success
&& W_ERROR_EQUAL(r
.out
.result
, WERR_OK
)) {
385 static bool test_OpenKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
386 struct policy_handle
*hive_handle
,
387 const char *keyname
, struct policy_handle
*key_handle
)
389 return _test_OpenKey(p
, tctx
, hive_handle
, keyname
,
390 SEC_FLAG_MAXIMUM_ALLOWED
, key_handle
,
394 static bool test_Cleanup(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
395 struct policy_handle
*handle
, const char *key
)
397 struct winreg_DeleteKey r
;
400 r
.in
.handle
= handle
;
402 init_winreg_String(&r
.in
.key
, key
);
403 dcerpc_winreg_DeleteKey(p
, tctx
, &r
);
408 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe
*p
,
409 struct torture_context
*tctx
,
410 struct policy_handle
*handle
,
414 struct security_descriptor
*sd
= NULL
;
416 if (!_test_GetKeySecurity(p
, tctx
, handle
, NULL
, get_werr
, &sd
)) {
420 if (!_test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, set_werr
)) {
427 static bool test_SecurityDescriptor(struct dcerpc_pipe
*p
,
428 struct torture_context
*tctx
,
429 struct policy_handle
*handle
,
432 struct policy_handle new_handle
;
435 torture_comment(tctx
, "SecurityDescriptor get & set\n");
437 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
441 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
446 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
453 static bool _test_SecurityDescriptor(struct dcerpc_pipe
*p
,
454 struct torture_context
*tctx
,
455 struct policy_handle
*handle
,
456 uint32_t access_mask
,
462 struct policy_handle new_handle
;
464 bool got_key
= false;
466 if (!_test_OpenKey(p
, tctx
, handle
, key
, access_mask
, &new_handle
,
467 open_werr
, &got_key
)) {
475 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
476 get_werr
, set_werr
)) {
480 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
487 static bool test_dacl_trustee_present(struct dcerpc_pipe
*p
,
488 struct torture_context
*tctx
,
489 struct policy_handle
*handle
,
490 const struct dom_sid
*sid
)
492 struct security_descriptor
*sd
= NULL
;
495 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
499 if (!sd
|| !sd
->dacl
) {
503 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
504 if (dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) {
512 static bool _test_dacl_trustee_present(struct dcerpc_pipe
*p
,
513 struct torture_context
*tctx
,
514 struct policy_handle
*handle
,
516 const struct dom_sid
*sid
)
518 struct policy_handle new_handle
;
521 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
525 ret
= test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
);
527 test_CloseKey(p
, tctx
, &new_handle
);
532 static bool test_sacl_trustee_present(struct dcerpc_pipe
*p
,
533 struct torture_context
*tctx
,
534 struct policy_handle
*handle
,
535 const struct dom_sid
*sid
)
537 struct security_descriptor
*sd
= NULL
;
539 uint32_t sec_info
= SECINFO_SACL
;
541 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
545 if (!sd
|| !sd
->sacl
) {
549 for (i
= 0; i
< sd
->sacl
->num_aces
; i
++) {
550 if (dom_sid_equal(&sd
->sacl
->aces
[i
].trustee
, sid
)) {
558 static bool _test_sacl_trustee_present(struct dcerpc_pipe
*p
,
559 struct torture_context
*tctx
,
560 struct policy_handle
*handle
,
562 const struct dom_sid
*sid
)
564 struct policy_handle new_handle
;
567 if (!_test_OpenKey(p
, tctx
, handle
, key
, SEC_FLAG_SYSTEM_SECURITY
,
568 &new_handle
, WERR_OK
, NULL
)) {
572 ret
= test_sacl_trustee_present(p
, tctx
, &new_handle
, sid
);
574 test_CloseKey(p
, tctx
, &new_handle
);
579 static bool test_owner_present(struct dcerpc_pipe
*p
,
580 struct torture_context
*tctx
,
581 struct policy_handle
*handle
,
582 const struct dom_sid
*sid
)
584 struct security_descriptor
*sd
= NULL
;
585 uint32_t sec_info
= SECINFO_OWNER
;
587 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
591 if (!sd
|| !sd
->owner_sid
) {
595 return dom_sid_equal(sd
->owner_sid
, sid
);
598 static bool _test_owner_present(struct dcerpc_pipe
*p
,
599 struct torture_context
*tctx
,
600 struct policy_handle
*handle
,
602 const struct dom_sid
*sid
)
604 struct policy_handle new_handle
;
607 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
611 ret
= test_owner_present(p
, tctx
, &new_handle
, sid
);
613 test_CloseKey(p
, tctx
, &new_handle
);
618 static bool test_group_present(struct dcerpc_pipe
*p
,
619 struct torture_context
*tctx
,
620 struct policy_handle
*handle
,
621 const struct dom_sid
*sid
)
623 struct security_descriptor
*sd
= NULL
;
624 uint32_t sec_info
= SECINFO_GROUP
;
626 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
630 if (!sd
|| !sd
->group_sid
) {
634 return dom_sid_equal(sd
->group_sid
, sid
);
637 static bool _test_group_present(struct dcerpc_pipe
*p
,
638 struct torture_context
*tctx
,
639 struct policy_handle
*handle
,
641 const struct dom_sid
*sid
)
643 struct policy_handle new_handle
;
646 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
650 ret
= test_group_present(p
, tctx
, &new_handle
, sid
);
652 test_CloseKey(p
, tctx
, &new_handle
);
657 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe
*p
,
658 struct torture_context
*tctx
,
659 struct policy_handle
*handle
,
660 const struct dom_sid
*sid
,
663 struct security_descriptor
*sd
= NULL
;
666 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
670 if (!sd
|| !sd
->dacl
) {
674 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
675 if ((dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) &&
676 (sd
->dacl
->aces
[i
].flags
== flags
)) {
684 static bool test_dacl_ace_present(struct dcerpc_pipe
*p
,
685 struct torture_context
*tctx
,
686 struct policy_handle
*handle
,
687 const struct security_ace
*ace
)
689 struct security_descriptor
*sd
= NULL
;
692 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
696 if (!sd
|| !sd
->dacl
) {
700 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
701 if (security_ace_equal(&sd
->dacl
->aces
[i
], ace
)) {
709 static bool test_RestoreSecurity(struct dcerpc_pipe
*p
,
710 struct torture_context
*tctx
,
711 struct policy_handle
*handle
,
713 struct security_descriptor
*sd
)
715 struct policy_handle new_handle
;
718 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
722 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
726 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
733 static bool test_BackupSecurity(struct dcerpc_pipe
*p
,
734 struct torture_context
*tctx
,
735 struct policy_handle
*handle
,
737 struct security_descriptor
**sd
)
739 struct policy_handle new_handle
;
742 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
746 if (!test_GetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
750 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
757 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe
*p
,
758 struct torture_context
*tctx
,
759 struct policy_handle
*handle
,
763 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
778 struct security_descriptor
*sd
= NULL
;
779 struct security_descriptor
*sd_orig
= NULL
;
780 struct security_ace
*ace
= NULL
;
781 struct policy_handle new_handle
;
785 torture_comment(tctx
, "SecurityDescriptor inheritance\n");
787 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
791 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
795 sd_orig
= security_descriptor_copy(tctx
, sd
);
796 if (sd_orig
== NULL
) {
800 ace
= security_ace_create(tctx
,
802 SEC_ACE_TYPE_ACCESS_ALLOWED
,
804 SEC_ACE_FLAG_CONTAINER_INHERIT
);
806 status
= security_descriptor_dacl_add(sd
, ace
);
807 if (!NT_STATUS_IS_OK(status
)) {
808 printf("failed to add ace: %s\n", nt_errstr(status
));
812 /* FIXME: add further tests for these flags */
813 sd
->type
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
|
814 SEC_DESC_SACL_AUTO_INHERITED
;
816 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
820 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
821 printf("new ACE not present!\n");
825 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
829 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, NULL
)) {
834 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
839 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
840 printf("inherited ACE not present!\n");
845 test_CloseKey(p
, tctx
, &new_handle
);
846 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
851 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
856 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
857 printf("inherited ACE not present!\n");
863 test_CloseKey(p
, tctx
, &new_handle
);
864 test_Cleanup(p
, tctx
, handle
, TEST_SUBKEY_SD
);
865 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
870 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe
*p
,
871 struct torture_context
*tctx
,
872 struct policy_handle
*handle
,
876 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
888 struct security_descriptor
*sd
= NULL
;
889 struct security_descriptor
*sd_orig
= NULL
;
890 struct security_ace
*ace
= NULL
;
891 struct policy_handle new_handle
;
892 struct dom_sid
*sid
= NULL
;
895 uint8_t ace_flags
= 0x0;
897 torture_comment(tctx
, "SecurityDescriptor inheritance block\n");
899 if (!test_OpenKey(p
, tctx
, handle
, key
, &new_handle
)) {
903 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
907 sd_orig
= security_descriptor_copy(tctx
, sd
);
908 if (sd_orig
== NULL
) {
912 ace
= security_ace_create(tctx
,
914 SEC_ACE_TYPE_ACCESS_ALLOWED
,
916 SEC_ACE_FLAG_CONTAINER_INHERIT
|
917 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
);
919 status
= security_descriptor_dacl_add(sd
, ace
);
920 if (!NT_STATUS_IS_OK(status
)) {
921 printf("failed to add ace: %s\n", nt_errstr(status
));
925 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, NULL
, sd
, WERR_OK
)) {
929 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
930 printf("new ACE not present!\n");
934 if (!test_CloseKey(p
, tctx
, &new_handle
)) {
938 if (!test_CreateKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
942 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
947 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
948 printf("inherited ACE present but should not!\n");
953 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
958 if (test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
)) {
959 printf("inherited trustee SID present but should not!\n");
964 test_CloseKey(p
, tctx
, &new_handle
);
966 if (!test_OpenKey(p
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
971 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
972 printf("inherited ACE present but should not!\n");
977 if (!test_dacl_trustee_flags_present(p
, tctx
, &new_handle
, sid
, ace_flags
)) {
978 printf("inherited trustee SID with flags 0x%02x not present!\n",
985 test_CloseKey(p
, tctx
, &new_handle
);
986 test_Cleanup(p
, tctx
, handle
, TEST_SUBKEY_SD
);
987 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
992 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe
*p
,
993 struct torture_context
*tctx
,
994 struct policy_handle
*handle
,
1000 struct winreg_mask_result_table
{
1001 uint32_t access_mask
;
1005 } sd_mask_tests
[] = {
1007 WERR_ACCESS_DENIED
, WERR_BADFILE
, WERR_FOOBAR
},
1008 { SEC_FLAG_MAXIMUM_ALLOWED
,
1009 WERR_OK
, WERR_OK
, WERR_OK
},
1010 { SEC_STD_WRITE_DAC
,
1011 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
},
1012 { SEC_FLAG_SYSTEM_SECURITY
,
1013 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
}
1016 /* FIXME: before this test can ever run successfully we need a way to
1017 * correctly read a NULL security_descritpor in ndr, get the required
1018 * length, requery, etc.
1023 for (i
=0; i
< ARRAY_SIZE(sd_mask_tests
); i
++) {
1025 torture_comment(tctx
,
1026 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1027 sd_mask_tests
[i
].access_mask
);
1028 torture_comment(tctx
,
1029 "expecting: open %s, get: %s, set: %s\n",
1030 win_errstr(sd_mask_tests
[i
].open_werr
),
1031 win_errstr(sd_mask_tests
[i
].get_werr
),
1032 win_errstr(sd_mask_tests
[i
].set_werr
));
1034 if (_test_SecurityDescriptor(p
, tctx
, handle
,
1035 sd_mask_tests
[i
].access_mask
, key
,
1036 sd_mask_tests
[i
].open_werr
,
1037 sd_mask_tests
[i
].get_werr
,
1038 sd_mask_tests
[i
].set_werr
)) {
1046 typedef bool (*secinfo_verify_fn
)(struct dcerpc_pipe
*,
1047 struct torture_context
*,
1048 struct policy_handle
*,
1050 const struct dom_sid
*);
1052 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe
*p
,
1053 struct torture_context
*tctx
,
1054 struct policy_handle
*handle
,
1057 uint32_t access_mask
,
1059 struct security_descriptor
*sd
,
1061 bool expect_present
,
1062 bool (*fn
) (struct dcerpc_pipe
*,
1063 struct torture_context
*,
1064 struct policy_handle
*,
1066 const struct dom_sid
*),
1067 const struct dom_sid
*sid
)
1069 struct policy_handle new_handle
;
1070 bool open_success
= false;
1072 torture_comment(tctx
, "SecurityDescriptor (%s) sets for secinfo: "
1073 "0x%08x, access_mask: 0x%08x\n",
1074 test
, sec_info
, access_mask
);
1076 if (!_test_OpenKey(p
, tctx
, handle
, key
,
1084 if (!open_success
) {
1085 printf("key did not open\n");
1086 test_CloseKey(p
, tctx
, &new_handle
);
1090 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, &sec_info
,
1093 torture_warning(tctx
,
1094 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1097 test_CloseKey(p
, tctx
, &new_handle
);
1101 test_CloseKey(p
, tctx
, &new_handle
);
1103 if (W_ERROR_IS_OK(set_werr
)) {
1105 present
= fn(p
, tctx
, handle
, key
, sid
);
1106 if ((expect_present
) && (!present
)) {
1107 torture_warning(tctx
,
1108 "%s sid is not present!\n",
1112 if ((!expect_present
) && (present
)) {
1113 torture_warning(tctx
,
1114 "%s sid is present but not expected!\n",
1123 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe
*p
,
1124 struct torture_context
*tctx
,
1125 struct policy_handle
*handle
,
1128 struct security_descriptor
*sd_orig
= NULL
;
1129 struct dom_sid
*sid
= NULL
;
1133 struct security_descriptor
*sd_owner
=
1134 security_descriptor_dacl_create(tctx
,
1136 TEST_SID
, NULL
, NULL
);
1138 struct security_descriptor
*sd_group
=
1139 security_descriptor_dacl_create(tctx
,
1141 NULL
, TEST_SID
, NULL
);
1143 struct security_descriptor
*sd_dacl
=
1144 security_descriptor_dacl_create(tctx
,
1148 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1151 SID_NT_AUTHENTICATED_USERS
,
1152 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1157 struct security_descriptor
*sd_sacl
=
1158 security_descriptor_sacl_create(tctx
,
1162 SEC_ACE_TYPE_SYSTEM_AUDIT
,
1164 SEC_ACE_FLAG_SUCCESSFUL_ACCESS
,
1167 struct winreg_secinfo_table
{
1168 struct security_descriptor
*sd
;
1172 secinfo_verify_fn fn
;
1175 struct winreg_secinfo_table sec_info_owner_tests
[] = {
1176 { sd_owner
, 0, WERR_OK
,
1177 false, (secinfo_verify_fn
)_test_owner_present
},
1178 { sd_owner
, SECINFO_OWNER
, WERR_OK
,
1179 true, (secinfo_verify_fn
)_test_owner_present
},
1180 { sd_owner
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1181 { sd_owner
, SECINFO_DACL
, WERR_OK
,
1182 true, (secinfo_verify_fn
)_test_owner_present
},
1183 { sd_owner
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1186 uint32_t sd_owner_good_access_masks
[] = {
1187 SEC_FLAG_MAXIMUM_ALLOWED
,
1188 /* SEC_STD_WRITE_OWNER, */
1191 struct winreg_secinfo_table sec_info_group_tests
[] = {
1192 { sd_group
, 0, WERR_OK
,
1193 false, (secinfo_verify_fn
)_test_group_present
},
1194 { sd_group
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1195 { sd_group
, SECINFO_GROUP
, WERR_OK
,
1196 true, (secinfo_verify_fn
)_test_group_present
},
1197 { sd_group
, SECINFO_DACL
, WERR_OK
,
1198 true, (secinfo_verify_fn
)_test_group_present
},
1199 { sd_group
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1202 uint32_t sd_group_good_access_masks
[] = {
1203 SEC_FLAG_MAXIMUM_ALLOWED
,
1206 struct winreg_secinfo_table sec_info_dacl_tests
[] = {
1207 { sd_dacl
, 0, WERR_OK
,
1208 false, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1209 { sd_dacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1210 { sd_dacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1211 { sd_dacl
, SECINFO_DACL
, WERR_OK
,
1212 true, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1213 { sd_dacl
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1216 uint32_t sd_dacl_good_access_masks
[] = {
1217 SEC_FLAG_MAXIMUM_ALLOWED
,
1221 struct winreg_secinfo_table sec_info_sacl_tests
[] = {
1222 { sd_sacl
, 0, WERR_OK
,
1223 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1224 { sd_sacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1225 { sd_sacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1226 { sd_sacl
, SECINFO_DACL
, WERR_OK
,
1227 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1228 { sd_sacl
, SECINFO_SACL
, WERR_OK
,
1229 true, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1232 uint32_t sd_sacl_good_access_masks
[] = {
1233 SEC_FLAG_MAXIMUM_ALLOWED
| SEC_FLAG_SYSTEM_SECURITY
,
1234 /* SEC_FLAG_SYSTEM_SECURITY, */
1237 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1242 if (!test_BackupSecurity(p
, tctx
, handle
, key
, &sd_orig
)) {
1248 for (i
=0; i
< ARRAY_SIZE(sec_info_owner_tests
); i
++) {
1250 for (a
=0; a
< ARRAY_SIZE(sd_owner_good_access_masks
); a
++) {
1252 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1255 sd_owner_good_access_masks
[a
],
1256 sec_info_owner_tests
[i
].sec_info
,
1257 sec_info_owner_tests
[i
].sd
,
1258 sec_info_owner_tests
[i
].set_werr
,
1259 sec_info_owner_tests
[i
].sid_present
,
1260 sec_info_owner_tests
[i
].fn
,
1263 printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1272 for (i
=0; i
< ARRAY_SIZE(sec_info_group_tests
); i
++) {
1274 for (a
=0; a
< ARRAY_SIZE(sd_group_good_access_masks
); a
++) {
1276 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1279 sd_group_good_access_masks
[a
],
1280 sec_info_group_tests
[i
].sec_info
,
1281 sec_info_group_tests
[i
].sd
,
1282 sec_info_group_tests
[i
].set_werr
,
1283 sec_info_group_tests
[i
].sid_present
,
1284 sec_info_group_tests
[i
].fn
,
1287 printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1296 for (i
=0; i
< ARRAY_SIZE(sec_info_dacl_tests
); i
++) {
1298 for (a
=0; a
< ARRAY_SIZE(sd_dacl_good_access_masks
); a
++) {
1300 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1303 sd_dacl_good_access_masks
[a
],
1304 sec_info_dacl_tests
[i
].sec_info
,
1305 sec_info_dacl_tests
[i
].sd
,
1306 sec_info_dacl_tests
[i
].set_werr
,
1307 sec_info_dacl_tests
[i
].sid_present
,
1308 sec_info_dacl_tests
[i
].fn
,
1311 printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1320 for (i
=0; i
< ARRAY_SIZE(sec_info_sacl_tests
); i
++) {
1322 for (a
=0; a
< ARRAY_SIZE(sd_sacl_good_access_masks
); a
++) {
1324 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1327 sd_sacl_good_access_masks
[a
],
1328 sec_info_sacl_tests
[i
].sec_info
,
1329 sec_info_sacl_tests
[i
].sd
,
1330 sec_info_sacl_tests
[i
].set_werr
,
1331 sec_info_sacl_tests
[i
].sid_present
,
1332 sec_info_sacl_tests
[i
].fn
,
1335 printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1343 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1348 static bool test_SecurityDescriptors(struct dcerpc_pipe
*p
,
1349 struct torture_context
*tctx
,
1350 struct policy_handle
*handle
,
1355 if (!test_SecurityDescriptor(p
, tctx
, handle
, key
)) {
1356 printf("test_SecurityDescriptor failed\n");
1360 if (!test_SecurityDescriptorInheritance(p
, tctx
, handle
, key
)) {
1361 printf("test_SecurityDescriptorInheritance failed\n");
1365 if (!test_SecurityDescriptorBlockInheritance(p
, tctx
, handle
, key
)) {
1366 printf("test_SecurityDescriptorBlockInheritance failed\n");
1370 if (!test_SecurityDescriptorsSecInfo(p
, tctx
, handle
, key
)) {
1371 printf("test_SecurityDescriptorsSecInfo failed\n");
1375 if (!test_SecurityDescriptorsMasks(p
, tctx
, handle
, key
)) {
1376 printf("test_SecurityDescriptorsMasks failed\n");
1383 static bool test_DeleteKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1384 struct policy_handle
*handle
, const char *key
)
1387 struct winreg_DeleteKey r
;
1389 r
.in
.handle
= handle
;
1390 init_winreg_String(&r
.in
.key
, key
);
1392 status
= dcerpc_winreg_DeleteKey(p
, tctx
, &r
);
1394 torture_assert_ntstatus_ok(tctx
, status
, "DeleteKey failed");
1395 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeleteKey failed");
1400 static bool test_QueryInfoKey(struct dcerpc_pipe
*p
,
1401 struct torture_context
*tctx
,
1402 struct policy_handle
*handle
, char *kclass
)
1404 struct winreg_QueryInfoKey r
;
1405 uint32_t num_subkeys
, max_subkeylen
, max_classlen
,
1406 num_values
, max_valnamelen
, max_valbufsize
,
1408 NTTIME last_changed_time
;
1411 r
.in
.handle
= handle
;
1412 r
.out
.num_subkeys
= &num_subkeys
;
1413 r
.out
.max_subkeylen
= &max_subkeylen
;
1414 r
.out
.max_classlen
= &max_classlen
;
1415 r
.out
.num_values
= &num_values
;
1416 r
.out
.max_valnamelen
= &max_valnamelen
;
1417 r
.out
.max_valbufsize
= &max_valbufsize
;
1418 r
.out
.secdescsize
= &secdescsize
;
1419 r
.out
.last_changed_time
= &last_changed_time
;
1421 r
.out
.classname
= talloc(tctx
, struct winreg_String
);
1423 r
.in
.classname
= talloc(tctx
, struct winreg_String
);
1424 init_winreg_String(r
.in
.classname
, kclass
);
1426 torture_assert_ntstatus_ok(tctx
,
1427 dcerpc_winreg_QueryInfoKey(p
, tctx
, &r
),
1428 "QueryInfoKey failed");
1430 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryInfoKey failed");
1435 static bool test_SetValue(struct dcerpc_pipe
*p
,
1436 struct torture_context
*tctx
,
1437 struct policy_handle
*handle
,
1438 const char *value_name
,
1439 enum winreg_Type type
,
1443 struct winreg_SetValue r
;
1444 struct winreg_String name
;
1446 torture_comment(tctx
, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1447 value_name
, str_regtype(type
), size
);
1449 init_winreg_String(&name
, value_name
);
1451 r
.in
.handle
= handle
;
1457 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_SetValue(p
, tctx
, &r
),
1458 "winreg_SetValue failed");
1459 torture_assert_werr_ok(tctx
, r
.out
.result
,
1460 "winreg_SetValue failed");
1465 static bool test_DeleteValue(struct dcerpc_pipe
*p
,
1466 struct torture_context
*tctx
,
1467 struct policy_handle
*handle
,
1468 const char *value_name
)
1470 struct winreg_DeleteValue r
;
1471 struct winreg_String value
;
1473 torture_comment(tctx
, "Testing DeleteValue(%s)\n", value_name
);
1475 init_winreg_String(&value
, value_name
);
1477 r
.in
.handle
= handle
;
1480 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteValue(p
, tctx
, &r
),
1481 "winreg_DeleteValue failed");
1482 torture_assert_werr_ok(tctx
, r
.out
.result
,
1483 "winreg_DeleteValue failed");
1488 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1489 struct policy_handle
*handle
, int depth
,
1490 bool test_security
);
1492 static bool test_EnumKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1493 struct policy_handle
*handle
, int depth
,
1496 struct winreg_EnumKey r
;
1497 struct winreg_StringBuf kclass
, name
;
1505 r
.in
.handle
= handle
;
1506 r
.in
.enum_index
= 0;
1508 r
.in
.keyclass
= &kclass
;
1510 r
.in
.last_changed_time
= &t
;
1516 status
= dcerpc_winreg_EnumKey(p
, tctx
, &r
);
1518 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
1519 struct policy_handle key_handle
;
1521 torture_comment(tctx
, "EnumKey: %d: %s\n",
1525 if (!test_OpenKey(p
, tctx
, handle
, r
.out
.name
->name
,
1528 test_key(p
, tctx
, &key_handle
,
1529 depth
+ 1, test_security
);
1535 } while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
));
1537 torture_assert_ntstatus_ok(tctx
, status
, "EnumKey failed");
1539 if (!W_ERROR_IS_OK(r
.out
.result
) &&
1540 !W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
1541 torture_fail(tctx
, "EnumKey failed");
1547 static bool test_QueryMultipleValues(struct dcerpc_pipe
*p
,
1548 struct torture_context
*tctx
,
1549 struct policy_handle
*handle
,
1550 const char *valuename
)
1552 struct winreg_QueryMultipleValues r
;
1557 r
.in
.key_handle
= handle
;
1558 r
.in
.values
= r
.out
.values
= talloc_array(tctx
, struct QueryMultipleValue
, 1);
1559 r
.in
.values
[0].name
= talloc(tctx
, struct winreg_String
);
1560 r
.in
.values
[0].name
->name
= valuename
;
1561 r
.in
.values
[0].offset
= 0;
1562 r
.in
.values
[0].length
= 0;
1563 r
.in
.values
[0].type
= 0;
1565 r
.in
.num_values
= 1;
1566 r
.in
.buffer_size
= r
.out
.buffer_size
= talloc(tctx
, uint32_t);
1567 *r
.in
.buffer_size
= bufsize
;
1569 *r
.in
.buffer_size
= bufsize
;
1570 r
.in
.buffer
= r
.out
.buffer
= talloc_zero_array(tctx
, uint8_t,
1573 status
= dcerpc_winreg_QueryMultipleValues(p
, tctx
, &r
);
1575 if(NT_STATUS_IS_ERR(status
))
1576 torture_fail(tctx
, "QueryMultipleValues failed");
1578 talloc_free(r
.in
.buffer
);
1580 } while (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
));
1582 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryMultipleValues failed");
1587 static bool test_QueryValue(struct dcerpc_pipe
*p
,
1588 struct torture_context
*tctx
,
1589 struct policy_handle
*handle
,
1590 const char *valuename
)
1592 struct winreg_QueryValue r
;
1594 enum winreg_Type zero_type
= 0;
1595 uint32_t offered
= 0xfff;
1599 r
.in
.handle
= handle
;
1601 r
.in
.value_name
= talloc_zero(tctx
, struct winreg_String
);
1602 r
.in
.value_name
->name
= valuename
;
1603 r
.in
.type
= &zero_type
;
1604 r
.in
.data_size
= &offered
;
1605 r
.in
.data_length
= &zero
;
1607 status
= dcerpc_winreg_QueryValue(p
, tctx
, &r
);
1608 if (NT_STATUS_IS_ERR(status
)) {
1609 torture_fail(tctx
, "QueryValue failed");
1612 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
1617 static bool test_QueryValue_full(struct dcerpc_pipe
*p
,
1618 struct torture_context
*tctx
,
1619 struct policy_handle
*handle
,
1620 const char *valuename
,
1621 bool existing_value
)
1623 struct winreg_QueryValue r
;
1624 struct winreg_String value_name
;
1625 enum winreg_Type type
= REG_NONE
;
1626 uint32_t data_size
= 0;
1627 uint32_t real_data_size
= 0;
1628 uint32_t data_length
= 0;
1629 uint8_t *data
= NULL
;
1630 WERROR expected_error
= WERR_BADFILE
;
1632 if (valuename
== NULL
) {
1633 expected_error
= WERR_INVALID_PARAM
;
1638 init_winreg_String(&value_name
, NULL
);
1640 torture_comment(tctx
, "Testing QueryValue(%s)\n", valuename
);
1642 r
.in
.handle
= handle
;
1643 r
.in
.value_name
= &value_name
;
1645 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
), "QueryValue failed");
1646 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1647 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1649 init_winreg_String(&value_name
, valuename
);
1650 r
.in
.value_name
= &value_name
;
1652 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1653 "QueryValue failed");
1654 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1655 "QueryValue failed");
1659 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1660 "QueryValue failed");
1661 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1662 "QueryValue failed");
1664 r
.in
.data_length
= &data_length
;
1665 r
.out
.data_length
= &data_length
;
1666 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1667 "QueryValue failed");
1668 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1669 "QueryValue failed");
1671 r
.in
.data_size
= &data_size
;
1672 r
.out
.data_size
= &data_size
;
1673 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1674 "QueryValue failed");
1675 if (existing_value
) {
1676 torture_assert_werr_ok(tctx
, r
.out
.result
,
1677 "QueryValue failed");
1679 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1680 "QueryValue failed");
1683 real_data_size
= *r
.out
.data_size
;
1685 data
= talloc_zero_array(tctx
, uint8_t, 0);
1688 *r
.in
.data_size
= 0;
1689 *r
.out
.data_size
= 0;
1690 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1691 "QueryValue failed");
1692 if (existing_value
) {
1693 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_MORE_DATA
,
1694 "QueryValue failed");
1696 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1697 "QueryValue failed");
1700 data
= talloc_zero_array(tctx
, uint8_t, real_data_size
);
1703 r
.in
.data_size
= &real_data_size
;
1704 r
.out
.data_size
= &real_data_size
;
1705 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue(p
, tctx
, &r
),
1706 "QueryValue failed");
1707 if (existing_value
) {
1708 torture_assert_werr_ok(tctx
, r
.out
.result
,
1709 "QueryValue failed");
1711 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1712 "QueryValue failed");
1718 static bool test_EnumValue(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1719 struct policy_handle
*handle
, int max_valnamelen
,
1722 struct winreg_EnumValue r
;
1723 enum winreg_Type type
= 0;
1724 uint32_t size
= max_valbufsize
, zero
= 0;
1727 struct winreg_ValNameBuf name
;
1733 r
.in
.handle
= handle
;
1734 r
.in
.enum_index
= 0;
1739 r
.in
.length
= &zero
;
1743 torture_assert_ntstatus_ok(tctx
,
1744 dcerpc_winreg_EnumValue(p
, tctx
, &r
),
1745 "EnumValue failed");
1747 if (W_ERROR_IS_OK(r
.out
.result
)) {
1748 ret
&= test_QueryValue(p
, tctx
, handle
,
1750 ret
&= test_QueryMultipleValues(p
, tctx
, handle
,
1755 } while (W_ERROR_IS_OK(r
.out
.result
));
1757 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NO_MORE_ITEMS
,
1758 "EnumValue failed");
1763 static bool test_AbortSystemShutdown(struct dcerpc_pipe
*p
,
1764 struct torture_context
*tctx
)
1766 struct winreg_AbortSystemShutdown r
;
1767 uint16_t server
= 0x0;
1770 r
.in
.server
= &server
;
1772 torture_assert_ntstatus_ok(tctx
,
1773 dcerpc_winreg_AbortSystemShutdown(p
, tctx
, &r
),
1774 "AbortSystemShutdown failed");
1776 torture_assert_werr_ok(tctx
, r
.out
.result
,
1777 "AbortSystemShutdown failed");
1782 static bool test_InitiateSystemShutdown(struct torture_context
*tctx
,
1783 struct dcerpc_pipe
*p
)
1785 struct winreg_InitiateSystemShutdown r
;
1786 uint16_t hostname
= 0x0;
1789 r
.in
.hostname
= &hostname
;
1790 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1791 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1792 r
.in
.force_apps
= 1;
1796 torture_assert_ntstatus_ok(tctx
,
1797 dcerpc_winreg_InitiateSystemShutdown(p
, tctx
, &r
),
1798 "InitiateSystemShutdown failed");
1800 torture_assert_werr_ok(tctx
, r
.out
.result
,
1801 "InitiateSystemShutdown failed");
1803 return test_AbortSystemShutdown(p
, tctx
);
1807 static bool test_InitiateSystemShutdownEx(struct torture_context
*tctx
,
1808 struct dcerpc_pipe
*p
)
1810 struct winreg_InitiateSystemShutdownEx r
;
1811 uint16_t hostname
= 0x0;
1814 r
.in
.hostname
= &hostname
;
1815 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1816 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1817 r
.in
.force_apps
= 1;
1822 torture_assert_ntstatus_ok(tctx
,
1823 dcerpc_winreg_InitiateSystemShutdownEx(p
, tctx
, &r
),
1824 "InitiateSystemShutdownEx failed");
1826 torture_assert_werr_ok(tctx
, r
.out
.result
,
1827 "InitiateSystemShutdownEx failed");
1829 return test_AbortSystemShutdown(p
, tctx
);
1831 #define MAX_DEPTH 2 /* Only go this far down the tree */
1833 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1834 struct policy_handle
*handle
, int depth
,
1837 if (depth
== MAX_DEPTH
)
1840 if (!test_QueryInfoKey(p
, tctx
, handle
, NULL
)) {
1843 if (!test_NotifyChangeKeyValue(p
, tctx
, handle
)) {
1846 if (test_security
&& !test_GetKeySecurity(p
, tctx
, handle
, NULL
)) {
1849 if (!test_EnumKey(p
, tctx
, handle
, depth
, test_security
)) {
1852 if (!test_EnumValue(p
, tctx
, handle
, 0xFF, 0xFFFF)) {
1855 test_CloseKey(p
, tctx
, handle
);
1860 static bool test_SetValue_simple(struct dcerpc_pipe
*p
,
1861 struct torture_context
*tctx
,
1862 struct policy_handle
*handle
)
1864 const char *value_name
= TEST_VALUE
;
1865 uint32_t value
= 0x12345678;
1866 const char *string
= "torture";
1868 enum winreg_Type types
[] = {
1876 torture_comment(tctx
, "Testing SetValue (standard formats)\n");
1878 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
1880 enum winreg_Type w_type
;
1881 uint32_t w_size
, w_length
;
1886 blob
= data_blob_talloc_zero(tctx
, 4);
1887 SIVAL(blob
.data
, 0, value
);
1890 blob
= data_blob_string_const("binary_blob");
1893 torture_assert(tctx
,
1894 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1898 (void **)&blob
.data
,
1903 torture_assert(tctx
,
1904 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1908 (void **)&blob
.data
,
1911 torture_assert(tctx
, data_blob_realloc(tctx
, &blob
, blob
.length
+ 2), "");
1912 memset(&blob
.data
[blob
.length
- 2], '\0', 2);
1918 torture_assert(tctx
,
1919 test_SetValue(p
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
1920 "test_SetValue failed");
1921 torture_assert(tctx
,
1922 test_QueryValue_full(p
, tctx
, handle
, value_name
, true),
1923 talloc_asprintf(tctx
, "test_QueryValue_full for %s value failed", value_name
));
1924 torture_assert(tctx
,
1925 test_winreg_QueryValue(tctx
, p
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
1926 "test_winreg_QueryValue failed");
1927 torture_assert(tctx
,
1928 test_DeleteValue(p
, tctx
, handle
, value_name
),
1929 "test_DeleteValue failed");
1931 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
1932 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
1933 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
1934 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
1937 torture_comment(tctx
, "Testing SetValue (standard formats) succeeded\n");
1942 typedef NTSTATUS (*winreg_open_fn
)(struct dcerpc_pipe
*, TALLOC_CTX
*, void *);
1944 static bool test_Open_Security(struct torture_context
*tctx
,
1945 struct dcerpc_pipe
*p
, void *userdata
)
1947 struct policy_handle handle
, newhandle
;
1948 bool ret
= true, created2
= false;
1949 bool created4
= false;
1950 struct winreg_OpenHKLM r
;
1952 winreg_open_fn open_fn
= userdata
;
1955 r
.in
.system_name
= 0;
1956 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1957 r
.out
.handle
= &handle
;
1959 torture_assert_ntstatus_ok(tctx
, open_fn(p
, tctx
, &r
),
1962 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
1964 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
1965 torture_comment(tctx
,
1966 "CreateKey (TEST_KEY_BASE) failed\n");
1969 if (test_CreateKey_sd(p
, tctx
, &handle
, TEST_KEY2
,
1970 NULL
, &newhandle
)) {
1974 if (created2
&& !test_CloseKey(p
, tctx
, &newhandle
)) {
1975 printf("CloseKey failed\n");
1979 if (test_CreateKey_sd(p
, tctx
, &handle
, TEST_KEY4
, NULL
, &newhandle
)) {
1983 if (created4
&& !test_CloseKey(p
, tctx
, &newhandle
)) {
1984 printf("CloseKey failed\n");
1988 if (created4
&& !test_SecurityDescriptors(p
, tctx
, &handle
, TEST_KEY4
)) {
1992 if (created4
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY4
)) {
1993 printf("DeleteKey failed\n");
1997 if (created2
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY2
)) {
1998 printf("DeleteKey failed\n");
2002 /* The HKCR hive has a very large fanout */
2003 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR
) {
2004 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, true)) {
2008 if (!test_key(p
, tctx
, &handle
, 0, true)) {
2013 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2018 static bool test_SetValue_extended(struct dcerpc_pipe
*p
,
2019 struct torture_context
*tctx
,
2020 struct policy_handle
*handle
)
2022 const char *value_name
= TEST_VALUE
;
2023 enum winreg_Type types
[] = {
2029 REG_DWORD_BIG_ENDIAN
,
2033 REG_FULL_RESOURCE_DESCRIPTOR
,
2034 REG_RESOURCE_REQUIREMENTS_LIST
,
2046 if (torture_setting_bool(tctx
, "samba3", false)) {
2047 torture_skip(tctx
, "skipping extended SetValue test against Samba 3");
2050 torture_comment(tctx
, "Testing SetValue (extended formats)\n");
2052 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
2053 for (l
=0; l
< 32; l
++) {
2055 enum winreg_Type w_type
;
2056 uint32_t w_size
, w_length
;
2059 const char *string
= generate_random_str(tctx
, l
);
2060 DATA_BLOB blob
= data_blob_string_const(string
);
2062 torture_assert(tctx
,
2063 test_SetValue(p
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
2064 "test_SetValue failed");
2066 torture_assert(tctx
,
2067 test_winreg_QueryValue(tctx
, p
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2068 "test_winreg_QueryValue failed");
2070 torture_assert(tctx
,
2071 test_DeleteValue(p
, tctx
, handle
, value_name
),
2072 "test_DeleteValue failed");
2074 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
2075 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
2076 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
2077 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
2081 torture_comment(tctx
, "Testing SetValue (extended formats) succeeded\n");
2086 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2087 #define VALUE_CURRENT_VERSION "CurrentVersion"
2089 static bool test_Open(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2092 struct policy_handle handle
, newhandle
;
2093 bool ret
= true, created
= false, deleted
= false;
2094 bool created3
= false, created_subkey
= false;
2095 struct winreg_OpenHKLM r
;
2097 winreg_open_fn open_fn
= userdata
;
2100 r
.in
.system_name
= 0;
2101 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2102 r
.out
.handle
= &handle
;
2104 torture_assert_ntstatus_ok(tctx
, open_fn(p
, tctx
, &r
),
2107 if (open_fn
== (void *)dcerpc_winreg_OpenHKLM
) {
2109 torture_assert(tctx
, test_OpenKey(p
, tctx
, &handle
, KEY_CURRENT_VERSION
, &newhandle
),
2110 "failed to open current version key");
2112 torture_assert(tctx
, _test_OpenKey(p
, tctx
, &handle
, KEY_CURRENT_VERSION
, KEY_QUERY_VALUE
, &newhandle
, WERR_OK
, NULL
),
2113 "failed to open current version key");
2115 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, VALUE_CURRENT_VERSION
, true),
2116 "failed to query current version");
2117 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, "IDoNotExist", false),
2118 "failed to query current version");
2119 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, NULL
, false),
2120 "test_QueryValue_full for NULL value failed");
2121 torture_assert(tctx
, test_QueryValue_full(p
, tctx
, &newhandle
, "", false),
2122 "test_QueryValue_full for \"\" value failed");
2124 torture_assert(tctx
, test_CloseKey(p
, tctx
, &newhandle
),
2125 "failed to close current version key");
2128 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2130 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2131 torture_comment(tctx
,
2132 "CreateKey (TEST_KEY_BASE) failed\n");
2135 if (!test_CreateKey(p
, tctx
, &handle
, TEST_KEY1
, NULL
)) {
2136 torture_comment(tctx
,
2137 "CreateKey failed - not considering a failure\n");
2142 if (created
&& !test_FlushKey(p
, tctx
, &handle
)) {
2143 torture_comment(tctx
, "FlushKey failed\n");
2147 if (created
&& !test_OpenKey(p
, tctx
, &handle
, TEST_KEY1
, &newhandle
))
2149 "CreateKey failed (OpenKey after Create didn't work)\n");
2152 torture_assert(tctx
, test_SetValue_simple(p
, tctx
, &newhandle
),
2153 "simple SetValue test failed");
2154 if (!test_SetValue_extended(p
, tctx
, &newhandle
)) {
2155 if (torture_setting_bool(tctx
, "samba3", false)) {
2156 torture_warning(tctx
, "extended SetValue test failed");
2158 torture_fail(tctx
, "extended SetValue test failed");
2163 if (created
&& !test_CloseKey(p
, tctx
, &newhandle
))
2165 "CreateKey failed (CloseKey after Open didn't work)\n");
2167 if (created
&& !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY1
)) {
2168 torture_comment(tctx
, "DeleteKey failed\n");
2174 if (created
&& !test_FlushKey(p
, tctx
, &handle
)) {
2175 torture_comment(tctx
, "FlushKey failed\n");
2179 if (created
&& deleted
&&
2180 !_test_OpenKey(p
, tctx
, &handle
, TEST_KEY1
,
2181 SEC_FLAG_MAXIMUM_ALLOWED
, &newhandle
,
2182 WERR_BADFILE
, NULL
)) {
2183 torture_comment(tctx
,
2184 "DeleteKey failed (OpenKey after Delete "
2185 "did not return WERR_BADFILE)\n");
2189 if (!test_GetVersion(p
, tctx
, &handle
)) {
2190 torture_comment(tctx
, "GetVersion failed\n");
2194 if (created
&& test_CreateKey(p
, tctx
, &handle
, TEST_KEY3
, NULL
)) {
2199 test_CreateKey(p
, tctx
, &handle
, TEST_SUBKEY
, NULL
)) {
2200 created_subkey
= true;
2203 if (created_subkey
&&
2204 !test_DeleteKey(p
, tctx
, &handle
, TEST_KEY3
)) {
2205 printf("DeleteKey failed\n");
2209 /* The HKCR hive has a very large fanout */
2210 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR
) {
2211 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, false)) {
2215 if (!test_key(p
, tctx
, &handle
, 0, false)) {
2220 test_Cleanup(p
, tctx
, &handle
, TEST_KEY_BASE
);
2225 struct torture_suite
*torture_rpc_winreg(TALLOC_CTX
*mem_ctx
)
2227 struct torture_rpc_tcase
*tcase
;
2228 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WINREG");
2229 struct torture_test
*test
;
2231 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "winreg",
2234 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdown",
2235 test_InitiateSystemShutdown
);
2236 test
->dangerous
= true;
2238 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdownEx",
2239 test_InitiateSystemShutdownEx
);
2240 test
->dangerous
= true;
2242 /* Basic tests without security descriptors */
2243 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-basic",
2245 (winreg_open_fn
)dcerpc_winreg_OpenHKLM
);
2246 torture_rpc_tcase_add_test_ex(tcase
, "HKU-basic",
2248 (winreg_open_fn
)dcerpc_winreg_OpenHKU
);
2249 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-basic",
2251 (winreg_open_fn
)dcerpc_winreg_OpenHKCR
);
2252 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-basic",
2254 (winreg_open_fn
)dcerpc_winreg_OpenHKCU
);
2256 /* Security descriptor tests */
2257 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-security",
2259 (winreg_open_fn
)dcerpc_winreg_OpenHKLM
);
2260 torture_rpc_tcase_add_test_ex(tcase
, "HKU-security",
2262 (winreg_open_fn
)dcerpc_winreg_OpenHKU
);
2263 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-security",
2265 (winreg_open_fn
)dcerpc_winreg_OpenHKCR
);
2266 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-security",
2268 (winreg_open_fn
)dcerpc_winreg_OpenHKCU
);