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_binding_handle
*b
,
61 struct torture_context
*tctx
,
62 struct policy_handle
*handle
)
64 struct winreg_GetVersion r
;
71 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_GetVersion_r(b
, tctx
, &r
),
74 torture_assert_werr_ok(tctx
, r
.out
.result
, "GetVersion failed");
79 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle
*b
,
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_r(b
, 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_opts(struct torture_context
*tctx
,
108 struct dcerpc_binding_handle
*b
,
109 struct policy_handle
*handle
,
112 enum winreg_KeyType options
,
113 uint32_t access_mask
,
114 struct winreg_SecBuf
*secdesc
,
115 enum winreg_CreateAction
*action_taken_p
,
116 struct policy_handle
*new_handle_p
)
118 struct winreg_CreateKey r
;
119 struct policy_handle newhandle
;
120 enum winreg_CreateAction action_taken
= 0;
123 r
.in
.handle
= handle
;
124 init_winreg_String(&r
.in
.name
, name
);
125 init_winreg_String(&r
.in
.keyclass
, kclass
);
126 r
.in
.options
= options
;
127 r
.in
.access_mask
= access_mask
;
128 r
.in
.action_taken
= &action_taken
;
129 r
.in
.secdesc
= secdesc
;
130 r
.out
.new_handle
= &newhandle
;
131 r
.out
.action_taken
= &action_taken
;
133 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey_r(b
, tctx
, &r
),
136 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey failed");
139 *new_handle_p
= newhandle
;
141 if (action_taken_p
) {
142 *action_taken_p
= action_taken
;
148 static bool test_CreateKey(struct dcerpc_binding_handle
*b
,
149 struct torture_context
*tctx
,
150 struct policy_handle
*handle
, const char *name
,
153 return test_CreateKey_opts(tctx
, b
, handle
, name
, kclass
,
154 REG_KEYTYPE_NON_VOLATILE
,
155 SEC_FLAG_MAXIMUM_ALLOWED
,
157 NULL
, /* action_taken */
158 NULL
/* new_handle */);
162 createkey testing with a SD
164 static bool test_CreateKey_sd(struct dcerpc_binding_handle
*b
,
165 struct torture_context
*tctx
,
166 struct policy_handle
*handle
, const char *name
,
168 struct policy_handle
*newhandle
)
170 struct winreg_CreateKey r
;
171 enum winreg_CreateAction action_taken
= 0;
172 struct security_descriptor
*sd
;
174 struct winreg_SecBuf secbuf
;
176 sd
= security_descriptor_dacl_create(tctx
,
179 SID_NT_AUTHENTICATED_USERS
,
180 SEC_ACE_TYPE_ACCESS_ALLOWED
,
182 SEC_ACE_FLAG_OBJECT_INHERIT
|
183 SEC_ACE_FLAG_CONTAINER_INHERIT
,
186 torture_assert_ndr_success(tctx
,
187 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
188 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
189 "Failed to push security_descriptor ?!\n");
191 secbuf
.sd
.data
= sdblob
.data
;
192 secbuf
.sd
.len
= sdblob
.length
;
193 secbuf
.sd
.size
= sdblob
.length
;
194 secbuf
.length
= sdblob
.length
-10;
198 r
.in
.handle
= handle
;
199 r
.out
.new_handle
= newhandle
;
200 init_winreg_String(&r
.in
.name
, name
);
201 init_winreg_String(&r
.in
.keyclass
, kclass
);
203 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
204 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
205 r
.in
.secdesc
= &secbuf
;
207 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey_r(b
, tctx
, &r
),
208 "CreateKey with sd failed");
210 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey with sd failed");
215 static bool _test_GetKeySecurity(struct dcerpc_pipe
*p
,
216 struct torture_context
*tctx
,
217 struct policy_handle
*handle
,
218 uint32_t *sec_info_ptr
,
220 struct security_descriptor
**sd_out
)
222 struct winreg_GetKeySecurity r
;
223 struct security_descriptor
*sd
= NULL
;
226 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
229 sec_info
= *sec_info_ptr
;
231 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
236 r
.in
.handle
= handle
;
237 r
.in
.sec_info
= sec_info
;
238 r
.in
.sd
= r
.out
.sd
= talloc_zero(tctx
, struct KeySecurityData
);
239 r
.in
.sd
->size
= 0x1000;
241 torture_assert_ntstatus_ok(tctx
,
242 dcerpc_winreg_GetKeySecurity_r(b
, tctx
, &r
),
243 "GetKeySecurity failed");
245 torture_assert_werr_equal(tctx
, r
.out
.result
, get_werr
,
246 "GetKeySecurity failed");
248 sdblob
.data
= r
.out
.sd
->data
;
249 sdblob
.length
= r
.out
.sd
->len
;
251 sd
= talloc_zero(tctx
, struct security_descriptor
);
253 torture_assert_ndr_success(tctx
,
254 ndr_pull_struct_blob(&sdblob
, tctx
, NULL
, sd
,
255 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
),
256 "pull_security_descriptor failed");
258 if (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
) {
259 NDR_PRINT_DEBUG(security_descriptor
, sd
);
271 static bool test_GetKeySecurity(struct dcerpc_pipe
*p
,
272 struct torture_context
*tctx
,
273 struct policy_handle
*handle
,
274 struct security_descriptor
**sd_out
)
276 return _test_GetKeySecurity(p
, tctx
, handle
, NULL
, WERR_OK
, sd_out
);
279 static bool _test_SetKeySecurity(struct dcerpc_pipe
*p
,
280 struct torture_context
*tctx
,
281 struct policy_handle
*handle
,
282 uint32_t *sec_info_ptr
,
283 struct security_descriptor
*sd
,
286 struct winreg_SetKeySecurity r
;
287 struct KeySecurityData
*sdata
= NULL
;
290 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
294 if (sd
&& (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
)) {
295 NDR_PRINT_DEBUG(security_descriptor
, sd
);
298 torture_assert_ndr_success(tctx
,
299 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
300 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
301 "push_security_descriptor failed");
303 sdata
= talloc_zero(tctx
, struct KeySecurityData
);
304 sdata
->data
= sdblob
.data
;
305 sdata
->size
= sdblob
.length
;
306 sdata
->len
= sdblob
.length
;
309 sec_info
= *sec_info_ptr
;
311 sec_info
= SECINFO_UNPROTECTED_SACL
|
312 SECINFO_UNPROTECTED_DACL
;
314 sec_info
|= SECINFO_OWNER
;
317 sec_info
|= SECINFO_GROUP
;
320 sec_info
|= SECINFO_SACL
;
323 sec_info
|= SECINFO_DACL
;
327 r
.in
.handle
= handle
;
328 r
.in
.sec_info
= sec_info
;
331 torture_assert_ntstatus_ok(tctx
,
332 dcerpc_winreg_SetKeySecurity_r(b
, tctx
, &r
),
333 "SetKeySecurity failed");
335 torture_assert_werr_equal(tctx
, r
.out
.result
, werr
,
336 "SetKeySecurity failed");
341 static bool test_SetKeySecurity(struct dcerpc_pipe
*p
,
342 struct torture_context
*tctx
,
343 struct policy_handle
*handle
,
344 struct security_descriptor
*sd
)
346 return _test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, WERR_OK
);
349 static bool test_CloseKey(struct dcerpc_binding_handle
*b
,
350 struct torture_context
*tctx
,
351 struct policy_handle
*handle
)
353 struct winreg_CloseKey r
;
356 r
.in
.handle
= r
.out
.handle
= handle
;
358 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CloseKey_r(b
, tctx
, &r
),
361 torture_assert_werr_ok(tctx
, r
.out
.result
, "CloseKey failed");
366 static bool test_FlushKey(struct dcerpc_binding_handle
*b
,
367 struct torture_context
*tctx
,
368 struct policy_handle
*handle
)
370 struct winreg_FlushKey r
;
373 r
.in
.handle
= handle
;
375 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_FlushKey_r(b
, tctx
, &r
),
378 torture_assert_werr_ok(tctx
, r
.out
.result
, "FlushKey failed");
383 static bool _test_OpenKey(struct dcerpc_binding_handle
*b
,
384 struct torture_context
*tctx
,
385 struct policy_handle
*hive_handle
,
386 const char *keyname
, uint32_t access_mask
,
387 struct policy_handle
*key_handle
,
391 struct winreg_OpenKey r
;
394 r
.in
.parent_handle
= hive_handle
;
395 init_winreg_String(&r
.in
.keyname
, keyname
);
396 r
.in
.options
= REG_KEYTYPE_NON_VOLATILE
;
397 r
.in
.access_mask
= access_mask
;
398 r
.out
.handle
= key_handle
;
400 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenKey_r(b
, tctx
, &r
),
403 torture_assert_werr_equal(tctx
, r
.out
.result
, open_werr
,
406 if (success
&& W_ERROR_EQUAL(r
.out
.result
, WERR_OK
)) {
413 static bool test_OpenKey(struct dcerpc_binding_handle
*b
,
414 struct torture_context
*tctx
,
415 struct policy_handle
*hive_handle
,
416 const char *keyname
, struct policy_handle
*key_handle
)
418 return _test_OpenKey(b
, tctx
, hive_handle
, keyname
,
419 SEC_FLAG_MAXIMUM_ALLOWED
, key_handle
,
423 static bool test_Cleanup(struct dcerpc_binding_handle
*b
,
424 struct torture_context
*tctx
,
425 struct policy_handle
*handle
, const char *key
)
427 struct winreg_DeleteKey r
;
430 r
.in
.handle
= handle
;
432 init_winreg_String(&r
.in
.key
, key
);
433 dcerpc_winreg_DeleteKey_r(b
, tctx
, &r
);
438 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe
*p
,
439 struct torture_context
*tctx
,
440 struct policy_handle
*handle
,
444 struct security_descriptor
*sd
= NULL
;
446 if (!_test_GetKeySecurity(p
, tctx
, handle
, NULL
, get_werr
, &sd
)) {
450 if (!_test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, set_werr
)) {
457 static bool test_SecurityDescriptor(struct dcerpc_pipe
*p
,
458 struct torture_context
*tctx
,
459 struct policy_handle
*handle
,
462 struct policy_handle new_handle
;
464 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
466 torture_comment(tctx
, "SecurityDescriptor get & set\n");
468 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
472 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
477 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
484 static bool _test_SecurityDescriptor(struct dcerpc_pipe
*p
,
485 struct torture_context
*tctx
,
486 struct policy_handle
*handle
,
487 uint32_t access_mask
,
493 struct policy_handle new_handle
;
495 bool got_key
= false;
496 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
498 if (!_test_OpenKey(b
, tctx
, handle
, key
, access_mask
, &new_handle
,
499 open_werr
, &got_key
)) {
507 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
508 get_werr
, set_werr
)) {
512 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
519 static bool test_dacl_trustee_present(struct dcerpc_pipe
*p
,
520 struct torture_context
*tctx
,
521 struct policy_handle
*handle
,
522 const struct dom_sid
*sid
)
524 struct security_descriptor
*sd
= NULL
;
527 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
531 if (!sd
|| !sd
->dacl
) {
535 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
536 if (dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) {
544 static bool _test_dacl_trustee_present(struct dcerpc_pipe
*p
,
545 struct torture_context
*tctx
,
546 struct policy_handle
*handle
,
548 const struct dom_sid
*sid
)
550 struct policy_handle new_handle
;
552 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
554 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
558 ret
= test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
);
560 test_CloseKey(b
, tctx
, &new_handle
);
565 static bool test_sacl_trustee_present(struct dcerpc_pipe
*p
,
566 struct torture_context
*tctx
,
567 struct policy_handle
*handle
,
568 const struct dom_sid
*sid
)
570 struct security_descriptor
*sd
= NULL
;
572 uint32_t sec_info
= SECINFO_SACL
;
574 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
578 if (!sd
|| !sd
->sacl
) {
582 for (i
= 0; i
< sd
->sacl
->num_aces
; i
++) {
583 if (dom_sid_equal(&sd
->sacl
->aces
[i
].trustee
, sid
)) {
591 static bool _test_sacl_trustee_present(struct dcerpc_pipe
*p
,
592 struct torture_context
*tctx
,
593 struct policy_handle
*handle
,
595 const struct dom_sid
*sid
)
597 struct policy_handle new_handle
;
599 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
601 if (!_test_OpenKey(b
, tctx
, handle
, key
, SEC_FLAG_SYSTEM_SECURITY
,
602 &new_handle
, WERR_OK
, NULL
)) {
606 ret
= test_sacl_trustee_present(p
, tctx
, &new_handle
, sid
);
608 test_CloseKey(b
, tctx
, &new_handle
);
613 static bool test_owner_present(struct dcerpc_pipe
*p
,
614 struct torture_context
*tctx
,
615 struct policy_handle
*handle
,
616 const struct dom_sid
*sid
)
618 struct security_descriptor
*sd
= NULL
;
619 uint32_t sec_info
= SECINFO_OWNER
;
621 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
625 if (!sd
|| !sd
->owner_sid
) {
629 return dom_sid_equal(sd
->owner_sid
, sid
);
632 static bool _test_owner_present(struct dcerpc_pipe
*p
,
633 struct torture_context
*tctx
,
634 struct policy_handle
*handle
,
636 const struct dom_sid
*sid
)
638 struct policy_handle new_handle
;
640 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
642 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
646 ret
= test_owner_present(p
, tctx
, &new_handle
, sid
);
648 test_CloseKey(b
, tctx
, &new_handle
);
653 static bool test_group_present(struct dcerpc_pipe
*p
,
654 struct torture_context
*tctx
,
655 struct policy_handle
*handle
,
656 const struct dom_sid
*sid
)
658 struct security_descriptor
*sd
= NULL
;
659 uint32_t sec_info
= SECINFO_GROUP
;
661 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
665 if (!sd
|| !sd
->group_sid
) {
669 return dom_sid_equal(sd
->group_sid
, sid
);
672 static bool _test_group_present(struct dcerpc_pipe
*p
,
673 struct torture_context
*tctx
,
674 struct policy_handle
*handle
,
676 const struct dom_sid
*sid
)
678 struct policy_handle new_handle
;
680 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
682 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
686 ret
= test_group_present(p
, tctx
, &new_handle
, sid
);
688 test_CloseKey(b
, tctx
, &new_handle
);
693 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe
*p
,
694 struct torture_context
*tctx
,
695 struct policy_handle
*handle
,
696 const struct dom_sid
*sid
,
699 struct security_descriptor
*sd
= NULL
;
702 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
706 if (!sd
|| !sd
->dacl
) {
710 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
711 if ((dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) &&
712 (sd
->dacl
->aces
[i
].flags
== flags
)) {
720 static bool test_dacl_ace_present(struct dcerpc_pipe
*p
,
721 struct torture_context
*tctx
,
722 struct policy_handle
*handle
,
723 const struct security_ace
*ace
)
725 struct security_descriptor
*sd
= NULL
;
728 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
732 if (!sd
|| !sd
->dacl
) {
736 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
737 if (security_ace_equal(&sd
->dacl
->aces
[i
], ace
)) {
745 static bool test_RestoreSecurity(struct dcerpc_pipe
*p
,
746 struct torture_context
*tctx
,
747 struct policy_handle
*handle
,
749 struct security_descriptor
*sd
)
751 struct policy_handle new_handle
;
753 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
755 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
759 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
763 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
770 static bool test_BackupSecurity(struct dcerpc_pipe
*p
,
771 struct torture_context
*tctx
,
772 struct policy_handle
*handle
,
774 struct security_descriptor
**sd
)
776 struct policy_handle new_handle
;
778 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
780 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
784 if (!test_GetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
788 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
795 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe
*p
,
796 struct torture_context
*tctx
,
797 struct policy_handle
*handle
,
801 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816 struct security_descriptor
*sd
= NULL
;
817 struct security_descriptor
*sd_orig
= NULL
;
818 struct security_ace
*ace
= NULL
;
819 struct policy_handle new_handle
;
821 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
823 torture_comment(tctx
, "SecurityDescriptor inheritance\n");
825 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
829 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
833 sd_orig
= security_descriptor_copy(tctx
, sd
);
834 if (sd_orig
== NULL
) {
838 ace
= security_ace_create(tctx
,
840 SEC_ACE_TYPE_ACCESS_ALLOWED
,
842 SEC_ACE_FLAG_CONTAINER_INHERIT
);
844 torture_assert_ntstatus_ok(tctx
,
845 security_descriptor_dacl_add(sd
, ace
),
846 "failed to add ace");
848 /* FIXME: add further tests for these flags */
849 sd
->type
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
|
850 SEC_DESC_SACL_AUTO_INHERITED
;
852 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
857 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
858 "new ACE not present!");
860 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
864 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, NULL
)) {
869 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
874 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
875 torture_comment(tctx
, "inherited ACE not present!\n");
880 test_CloseKey(b
, tctx
, &new_handle
);
881 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
886 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
891 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
892 torture_comment(tctx
, "inherited ACE not present!\n");
898 test_CloseKey(b
, tctx
, &new_handle
);
899 test_Cleanup(b
, tctx
, handle
, TEST_SUBKEY_SD
);
900 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
905 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe
*p
,
906 struct torture_context
*tctx
,
907 struct policy_handle
*handle
,
911 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
923 struct security_descriptor
*sd
= NULL
;
924 struct security_descriptor
*sd_orig
= NULL
;
925 struct security_ace
*ace
= NULL
;
926 struct policy_handle new_handle
;
927 struct dom_sid
*sid
= NULL
;
929 uint8_t ace_flags
= 0x0;
930 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
932 torture_comment(tctx
, "SecurityDescriptor inheritance block\n");
934 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
938 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
942 sd_orig
= security_descriptor_copy(tctx
, sd
);
943 if (sd_orig
== NULL
) {
947 ace
= security_ace_create(tctx
,
949 SEC_ACE_TYPE_ACCESS_ALLOWED
,
951 SEC_ACE_FLAG_CONTAINER_INHERIT
|
952 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
);
954 torture_assert_ntstatus_ok(tctx
,
955 security_descriptor_dacl_add(sd
, ace
),
956 "failed to add ace");
958 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, NULL
, sd
, WERR_OK
)) {
963 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
964 "new ACE not present!");
966 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
970 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
974 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
979 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
980 torture_comment(tctx
, "inherited ACE present but should not!\n");
985 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
990 if (test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
)) {
991 torture_comment(tctx
, "inherited trustee SID present but should not!\n");
996 test_CloseKey(b
, tctx
, &new_handle
);
998 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
1003 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
1004 torture_comment(tctx
, "inherited ACE present but should not!\n");
1009 if (!test_dacl_trustee_flags_present(p
, tctx
, &new_handle
, sid
, ace_flags
)) {
1010 torture_comment(tctx
, "inherited trustee SID with flags 0x%02x not present!\n",
1017 test_CloseKey(b
, tctx
, &new_handle
);
1018 test_Cleanup(b
, tctx
, handle
, TEST_SUBKEY_SD
);
1019 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1024 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe
*p
,
1025 struct torture_context
*tctx
,
1026 struct policy_handle
*handle
,
1032 struct winreg_mask_result_table
{
1033 uint32_t access_mask
;
1037 } sd_mask_tests
[] = {
1039 WERR_ACCESS_DENIED
, WERR_BADFILE
, WERR_FOOBAR
},
1040 { SEC_FLAG_MAXIMUM_ALLOWED
,
1041 WERR_OK
, WERR_OK
, WERR_OK
},
1042 { SEC_STD_WRITE_DAC
,
1043 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
},
1044 { SEC_FLAG_SYSTEM_SECURITY
,
1045 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
}
1048 /* FIXME: before this test can ever run successfully we need a way to
1049 * correctly read a NULL security_descritpor in ndr, get the required
1050 * length, requery, etc.
1055 for (i
=0; i
< ARRAY_SIZE(sd_mask_tests
); i
++) {
1057 torture_comment(tctx
,
1058 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1059 sd_mask_tests
[i
].access_mask
);
1060 torture_comment(tctx
,
1061 "expecting: open %s, get: %s, set: %s\n",
1062 win_errstr(sd_mask_tests
[i
].open_werr
),
1063 win_errstr(sd_mask_tests
[i
].get_werr
),
1064 win_errstr(sd_mask_tests
[i
].set_werr
));
1066 if (_test_SecurityDescriptor(p
, tctx
, handle
,
1067 sd_mask_tests
[i
].access_mask
, key
,
1068 sd_mask_tests
[i
].open_werr
,
1069 sd_mask_tests
[i
].get_werr
,
1070 sd_mask_tests
[i
].set_werr
)) {
1078 typedef bool (*secinfo_verify_fn
)(struct dcerpc_pipe
*,
1079 struct torture_context
*,
1080 struct policy_handle
*,
1082 const struct dom_sid
*);
1084 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe
*p
,
1085 struct torture_context
*tctx
,
1086 struct policy_handle
*handle
,
1089 uint32_t access_mask
,
1091 struct security_descriptor
*sd
,
1093 bool expect_present
,
1094 bool (*fn
) (struct dcerpc_pipe
*,
1095 struct torture_context
*,
1096 struct policy_handle
*,
1098 const struct dom_sid
*),
1099 const struct dom_sid
*sid
)
1101 struct policy_handle new_handle
;
1102 bool open_success
= false;
1103 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1105 torture_comment(tctx
, "SecurityDescriptor (%s) sets for secinfo: "
1106 "0x%08x, access_mask: 0x%08x\n",
1107 test
, sec_info
, access_mask
);
1109 if (!_test_OpenKey(b
, tctx
, handle
, key
,
1117 if (!open_success
) {
1118 torture_comment(tctx
, "key did not open\n");
1119 test_CloseKey(b
, tctx
, &new_handle
);
1123 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, &sec_info
,
1126 torture_warning(tctx
,
1127 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1130 test_CloseKey(b
, tctx
, &new_handle
);
1134 test_CloseKey(b
, tctx
, &new_handle
);
1136 if (W_ERROR_IS_OK(set_werr
)) {
1138 present
= fn(p
, tctx
, handle
, key
, sid
);
1139 if ((expect_present
) && (!present
)) {
1140 torture_warning(tctx
,
1141 "%s sid is not present!\n",
1145 if ((!expect_present
) && (present
)) {
1146 torture_warning(tctx
,
1147 "%s sid is present but not expected!\n",
1156 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe
*p
,
1157 struct torture_context
*tctx
,
1158 struct policy_handle
*handle
,
1161 struct security_descriptor
*sd_orig
= NULL
;
1162 struct dom_sid
*sid
= NULL
;
1166 struct security_descriptor
*sd_owner
=
1167 security_descriptor_dacl_create(tctx
,
1169 TEST_SID
, NULL
, NULL
);
1171 struct security_descriptor
*sd_group
=
1172 security_descriptor_dacl_create(tctx
,
1174 NULL
, TEST_SID
, NULL
);
1176 struct security_descriptor
*sd_dacl
=
1177 security_descriptor_dacl_create(tctx
,
1181 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1184 SID_NT_AUTHENTICATED_USERS
,
1185 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1190 struct security_descriptor
*sd_sacl
=
1191 security_descriptor_sacl_create(tctx
,
1195 SEC_ACE_TYPE_SYSTEM_AUDIT
,
1197 SEC_ACE_FLAG_SUCCESSFUL_ACCESS
,
1200 struct winreg_secinfo_table
{
1201 struct security_descriptor
*sd
;
1205 secinfo_verify_fn fn
;
1208 struct winreg_secinfo_table sec_info_owner_tests
[] = {
1209 { sd_owner
, 0, WERR_OK
,
1210 false, (secinfo_verify_fn
)_test_owner_present
},
1211 { sd_owner
, SECINFO_OWNER
, WERR_OK
,
1212 true, (secinfo_verify_fn
)_test_owner_present
},
1213 { sd_owner
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1214 { sd_owner
, SECINFO_DACL
, WERR_OK
,
1215 true, (secinfo_verify_fn
)_test_owner_present
},
1216 { sd_owner
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1219 uint32_t sd_owner_good_access_masks
[] = {
1220 SEC_FLAG_MAXIMUM_ALLOWED
,
1221 /* SEC_STD_WRITE_OWNER, */
1224 struct winreg_secinfo_table sec_info_group_tests
[] = {
1225 { sd_group
, 0, WERR_OK
,
1226 false, (secinfo_verify_fn
)_test_group_present
},
1227 { sd_group
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1228 { sd_group
, SECINFO_GROUP
, WERR_OK
,
1229 true, (secinfo_verify_fn
)_test_group_present
},
1230 { sd_group
, SECINFO_DACL
, WERR_OK
,
1231 true, (secinfo_verify_fn
)_test_group_present
},
1232 { sd_group
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1235 uint32_t sd_group_good_access_masks
[] = {
1236 SEC_FLAG_MAXIMUM_ALLOWED
,
1239 struct winreg_secinfo_table sec_info_dacl_tests
[] = {
1240 { sd_dacl
, 0, WERR_OK
,
1241 false, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1242 { sd_dacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1243 { sd_dacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1244 { sd_dacl
, SECINFO_DACL
, WERR_OK
,
1245 true, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1246 { sd_dacl
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1249 uint32_t sd_dacl_good_access_masks
[] = {
1250 SEC_FLAG_MAXIMUM_ALLOWED
,
1254 struct winreg_secinfo_table sec_info_sacl_tests
[] = {
1255 { sd_sacl
, 0, WERR_OK
,
1256 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1257 { sd_sacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1258 { sd_sacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1259 { sd_sacl
, SECINFO_DACL
, WERR_OK
,
1260 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1261 { sd_sacl
, SECINFO_SACL
, WERR_OK
,
1262 true, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1265 uint32_t sd_sacl_good_access_masks
[] = {
1266 SEC_FLAG_MAXIMUM_ALLOWED
| SEC_FLAG_SYSTEM_SECURITY
,
1267 /* SEC_FLAG_SYSTEM_SECURITY, */
1270 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1275 if (!test_BackupSecurity(p
, tctx
, handle
, key
, &sd_orig
)) {
1281 for (i
=0; i
< ARRAY_SIZE(sec_info_owner_tests
); i
++) {
1283 for (a
=0; a
< ARRAY_SIZE(sd_owner_good_access_masks
); a
++) {
1285 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1288 sd_owner_good_access_masks
[a
],
1289 sec_info_owner_tests
[i
].sec_info
,
1290 sec_info_owner_tests
[i
].sd
,
1291 sec_info_owner_tests
[i
].set_werr
,
1292 sec_info_owner_tests
[i
].sid_present
,
1293 sec_info_owner_tests
[i
].fn
,
1296 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1305 for (i
=0; i
< ARRAY_SIZE(sec_info_group_tests
); i
++) {
1307 for (a
=0; a
< ARRAY_SIZE(sd_group_good_access_masks
); a
++) {
1309 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1312 sd_group_good_access_masks
[a
],
1313 sec_info_group_tests
[i
].sec_info
,
1314 sec_info_group_tests
[i
].sd
,
1315 sec_info_group_tests
[i
].set_werr
,
1316 sec_info_group_tests
[i
].sid_present
,
1317 sec_info_group_tests
[i
].fn
,
1320 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1329 for (i
=0; i
< ARRAY_SIZE(sec_info_dacl_tests
); i
++) {
1331 for (a
=0; a
< ARRAY_SIZE(sd_dacl_good_access_masks
); a
++) {
1333 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1336 sd_dacl_good_access_masks
[a
],
1337 sec_info_dacl_tests
[i
].sec_info
,
1338 sec_info_dacl_tests
[i
].sd
,
1339 sec_info_dacl_tests
[i
].set_werr
,
1340 sec_info_dacl_tests
[i
].sid_present
,
1341 sec_info_dacl_tests
[i
].fn
,
1344 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1353 for (i
=0; i
< ARRAY_SIZE(sec_info_sacl_tests
); i
++) {
1355 for (a
=0; a
< ARRAY_SIZE(sd_sacl_good_access_masks
); a
++) {
1357 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1360 sd_sacl_good_access_masks
[a
],
1361 sec_info_sacl_tests
[i
].sec_info
,
1362 sec_info_sacl_tests
[i
].sd
,
1363 sec_info_sacl_tests
[i
].set_werr
,
1364 sec_info_sacl_tests
[i
].sid_present
,
1365 sec_info_sacl_tests
[i
].fn
,
1368 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1376 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1381 static bool test_SecurityDescriptors(struct dcerpc_pipe
*p
,
1382 struct torture_context
*tctx
,
1383 struct policy_handle
*handle
,
1388 if (!test_SecurityDescriptor(p
, tctx
, handle
, key
)) {
1389 torture_comment(tctx
, "test_SecurityDescriptor failed\n");
1393 if (!test_SecurityDescriptorInheritance(p
, tctx
, handle
, key
)) {
1394 torture_comment(tctx
, "test_SecurityDescriptorInheritance failed\n");
1398 if (!test_SecurityDescriptorBlockInheritance(p
, tctx
, handle
, key
)) {
1399 torture_comment(tctx
, "test_SecurityDescriptorBlockInheritance failed\n");
1403 if (!test_SecurityDescriptorsSecInfo(p
, tctx
, handle
, key
)) {
1404 torture_comment(tctx
, "test_SecurityDescriptorsSecInfo failed\n");
1408 if (!test_SecurityDescriptorsMasks(p
, tctx
, handle
, key
)) {
1409 torture_comment(tctx
, "test_SecurityDescriptorsMasks failed\n");
1416 static bool test_DeleteKey(struct dcerpc_binding_handle
*b
,
1417 struct torture_context
*tctx
,
1418 struct policy_handle
*handle
, const char *key
)
1421 struct winreg_DeleteKey r
;
1423 r
.in
.handle
= handle
;
1424 init_winreg_String(&r
.in
.key
, key
);
1426 status
= dcerpc_winreg_DeleteKey_r(b
, tctx
, &r
);
1428 torture_assert_ntstatus_ok(tctx
, status
, "DeleteKey failed");
1429 torture_assert_werr_ok(tctx
, r
.out
.result
, "DeleteKey failed");
1434 static bool test_QueryInfoKey(struct dcerpc_binding_handle
*b
,
1435 struct torture_context
*tctx
,
1436 struct policy_handle
*handle
, char *kclass
)
1438 struct winreg_QueryInfoKey r
;
1439 uint32_t num_subkeys
, max_subkeylen
, max_classlen
,
1440 num_values
, max_valnamelen
, max_valbufsize
,
1442 NTTIME last_changed_time
;
1445 r
.in
.handle
= handle
;
1446 r
.out
.num_subkeys
= &num_subkeys
;
1447 r
.out
.max_subkeylen
= &max_subkeylen
;
1448 r
.out
.max_classlen
= &max_classlen
;
1449 r
.out
.num_values
= &num_values
;
1450 r
.out
.max_valnamelen
= &max_valnamelen
;
1451 r
.out
.max_valbufsize
= &max_valbufsize
;
1452 r
.out
.secdescsize
= &secdescsize
;
1453 r
.out
.last_changed_time
= &last_changed_time
;
1455 r
.out
.classname
= talloc(tctx
, struct winreg_String
);
1457 r
.in
.classname
= talloc(tctx
, struct winreg_String
);
1458 init_winreg_String(r
.in
.classname
, kclass
);
1460 torture_assert_ntstatus_ok(tctx
,
1461 dcerpc_winreg_QueryInfoKey_r(b
, tctx
, &r
),
1462 "QueryInfoKey failed");
1464 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryInfoKey failed");
1469 static bool test_SetValue(struct dcerpc_binding_handle
*b
,
1470 struct torture_context
*tctx
,
1471 struct policy_handle
*handle
,
1472 const char *value_name
,
1473 enum winreg_Type type
,
1477 struct winreg_SetValue r
;
1478 struct winreg_String name
;
1480 torture_comment(tctx
, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1481 value_name
, str_regtype(type
), size
);
1483 init_winreg_String(&name
, value_name
);
1485 r
.in
.handle
= handle
;
1491 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_SetValue_r(b
, tctx
, &r
),
1492 "winreg_SetValue failed");
1493 torture_assert_werr_ok(tctx
, r
.out
.result
,
1494 "winreg_SetValue failed");
1499 static bool test_DeleteValue(struct dcerpc_binding_handle
*b
,
1500 struct torture_context
*tctx
,
1501 struct policy_handle
*handle
,
1502 const char *value_name
)
1504 struct winreg_DeleteValue r
;
1505 struct winreg_String value
;
1507 torture_comment(tctx
, "Testing DeleteValue(%s)\n", value_name
);
1509 init_winreg_String(&value
, value_name
);
1511 r
.in
.handle
= handle
;
1514 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteValue_r(b
, tctx
, &r
),
1515 "winreg_DeleteValue failed");
1516 torture_assert_werr_ok(tctx
, r
.out
.result
,
1517 "winreg_DeleteValue failed");
1522 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1523 struct policy_handle
*handle
, int depth
,
1524 bool test_security
);
1526 static bool test_EnumKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1527 struct policy_handle
*handle
, int depth
,
1530 struct winreg_EnumKey r
;
1531 struct winreg_StringBuf kclass
, name
;
1534 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1540 r
.in
.handle
= handle
;
1541 r
.in
.enum_index
= 0;
1543 r
.in
.keyclass
= &kclass
;
1545 r
.in
.last_changed_time
= &t
;
1551 status
= dcerpc_winreg_EnumKey_r(b
, tctx
, &r
);
1553 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
1554 struct policy_handle key_handle
;
1556 torture_comment(tctx
, "EnumKey: %d: %s\n",
1560 if (!test_OpenKey(b
, tctx
, handle
, r
.out
.name
->name
,
1563 test_key(p
, tctx
, &key_handle
,
1564 depth
+ 1, test_security
);
1570 } while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
));
1572 torture_assert_ntstatus_ok(tctx
, status
, "EnumKey failed");
1574 if (!W_ERROR_IS_OK(r
.out
.result
) &&
1575 !W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
1576 torture_fail(tctx
, "EnumKey failed");
1582 static bool test_QueryMultipleValues(struct dcerpc_binding_handle
*b
,
1583 struct torture_context
*tctx
,
1584 struct policy_handle
*handle
,
1585 const char *valuename
)
1587 struct winreg_QueryMultipleValues r
;
1592 r
.in
.key_handle
= handle
;
1593 r
.in
.values
= r
.out
.values
= talloc_array(tctx
, struct QueryMultipleValue
, 1);
1594 r
.in
.values
[0].name
= talloc(tctx
, struct winreg_String
);
1595 r
.in
.values
[0].name
->name
= valuename
;
1596 r
.in
.values
[0].offset
= 0;
1597 r
.in
.values
[0].length
= 0;
1598 r
.in
.values
[0].type
= 0;
1600 r
.in
.num_values
= 1;
1601 r
.in
.buffer_size
= r
.out
.buffer_size
= talloc(tctx
, uint32_t);
1602 *r
.in
.buffer_size
= bufsize
;
1604 *r
.in
.buffer_size
= bufsize
;
1605 r
.in
.buffer
= r
.out
.buffer
= talloc_zero_array(tctx
, uint8_t,
1608 status
= dcerpc_winreg_QueryMultipleValues_r(b
, tctx
, &r
);
1610 if(NT_STATUS_IS_ERR(status
))
1611 torture_fail(tctx
, "QueryMultipleValues failed");
1613 talloc_free(r
.in
.buffer
);
1615 } while (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
));
1617 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryMultipleValues failed");
1622 static bool test_QueryValue(struct dcerpc_binding_handle
*b
,
1623 struct torture_context
*tctx
,
1624 struct policy_handle
*handle
,
1625 const char *valuename
)
1627 struct winreg_QueryValue r
;
1629 enum winreg_Type zero_type
= 0;
1630 uint32_t offered
= 0xfff;
1634 r
.in
.handle
= handle
;
1636 r
.in
.value_name
= talloc_zero(tctx
, struct winreg_String
);
1637 r
.in
.value_name
->name
= valuename
;
1638 r
.in
.type
= &zero_type
;
1639 r
.in
.data_size
= &offered
;
1640 r
.in
.data_length
= &zero
;
1642 status
= dcerpc_winreg_QueryValue_r(b
, tctx
, &r
);
1643 if (NT_STATUS_IS_ERR(status
)) {
1644 torture_fail(tctx
, "QueryValue failed");
1647 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
1652 static bool test_QueryValue_full(struct dcerpc_binding_handle
*b
,
1653 struct torture_context
*tctx
,
1654 struct policy_handle
*handle
,
1655 const char *valuename
,
1656 bool existing_value
)
1658 struct winreg_QueryValue r
;
1659 struct winreg_String value_name
;
1660 enum winreg_Type type
= REG_NONE
;
1661 uint32_t data_size
= 0;
1662 uint32_t real_data_size
= 0;
1663 uint32_t data_length
= 0;
1664 uint8_t *data
= NULL
;
1665 WERROR expected_error
= WERR_BADFILE
;
1667 if (valuename
== NULL
) {
1668 expected_error
= WERR_INVALID_PARAM
;
1673 init_winreg_String(&value_name
, NULL
);
1675 torture_comment(tctx
, "Testing QueryValue(%s)\n", valuename
);
1677 r
.in
.handle
= handle
;
1678 r
.in
.value_name
= &value_name
;
1680 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
), "QueryValue failed");
1681 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1682 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1684 init_winreg_String(&value_name
, valuename
);
1685 r
.in
.value_name
= &value_name
;
1687 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1688 "QueryValue failed");
1689 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1690 "QueryValue failed");
1694 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1695 "QueryValue failed");
1696 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1697 "QueryValue failed");
1699 r
.in
.data_length
= &data_length
;
1700 r
.out
.data_length
= &data_length
;
1701 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1702 "QueryValue failed");
1703 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1704 "QueryValue failed");
1706 r
.in
.data_size
= &data_size
;
1707 r
.out
.data_size
= &data_size
;
1708 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1709 "QueryValue failed");
1710 if (existing_value
) {
1711 torture_assert_werr_ok(tctx
, r
.out
.result
,
1712 "QueryValue failed");
1714 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1715 "QueryValue failed");
1718 real_data_size
= *r
.out
.data_size
;
1720 data
= talloc_zero_array(tctx
, uint8_t, 0);
1723 *r
.in
.data_size
= 0;
1724 *r
.out
.data_size
= 0;
1725 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1726 "QueryValue failed");
1727 if (existing_value
) {
1728 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_MORE_DATA
,
1729 "QueryValue failed");
1731 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1732 "QueryValue failed");
1735 data
= talloc_zero_array(tctx
, uint8_t, real_data_size
);
1738 r
.in
.data_size
= &real_data_size
;
1739 r
.out
.data_size
= &real_data_size
;
1740 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1741 "QueryValue failed");
1742 if (existing_value
) {
1743 torture_assert_werr_ok(tctx
, r
.out
.result
,
1744 "QueryValue failed");
1746 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1747 "QueryValue failed");
1753 static bool test_EnumValue(struct dcerpc_binding_handle
*b
,
1754 struct torture_context
*tctx
,
1755 struct policy_handle
*handle
, int max_valnamelen
,
1758 struct winreg_EnumValue r
;
1759 enum winreg_Type type
= 0;
1760 uint32_t size
= max_valbufsize
, zero
= 0;
1763 struct winreg_ValNameBuf name
;
1769 r
.in
.handle
= handle
;
1770 r
.in
.enum_index
= 0;
1775 r
.in
.length
= &zero
;
1779 torture_assert_ntstatus_ok(tctx
,
1780 dcerpc_winreg_EnumValue_r(b
, tctx
, &r
),
1781 "EnumValue failed");
1783 if (W_ERROR_IS_OK(r
.out
.result
)) {
1784 ret
&= test_QueryValue(b
, tctx
, handle
,
1786 ret
&= test_QueryMultipleValues(b
, tctx
, handle
,
1791 } while (W_ERROR_IS_OK(r
.out
.result
));
1793 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NO_MORE_ITEMS
,
1794 "EnumValue failed");
1799 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle
*b
,
1800 struct torture_context
*tctx
)
1802 struct winreg_AbortSystemShutdown r
;
1803 uint16_t server
= 0x0;
1806 r
.in
.server
= &server
;
1808 torture_assert_ntstatus_ok(tctx
,
1809 dcerpc_winreg_AbortSystemShutdown_r(b
, tctx
, &r
),
1810 "AbortSystemShutdown failed");
1812 torture_assert_werr_ok(tctx
, r
.out
.result
,
1813 "AbortSystemShutdown failed");
1818 static bool test_InitiateSystemShutdown(struct torture_context
*tctx
,
1819 struct dcerpc_pipe
*p
)
1821 struct winreg_InitiateSystemShutdown r
;
1822 uint16_t hostname
= 0x0;
1823 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1826 r
.in
.hostname
= &hostname
;
1827 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1828 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1829 r
.in
.force_apps
= 1;
1833 torture_assert_ntstatus_ok(tctx
,
1834 dcerpc_winreg_InitiateSystemShutdown_r(b
, tctx
, &r
),
1835 "InitiateSystemShutdown failed");
1837 torture_assert_werr_ok(tctx
, r
.out
.result
,
1838 "InitiateSystemShutdown failed");
1840 return test_AbortSystemShutdown(b
, tctx
);
1844 static bool test_InitiateSystemShutdownEx(struct torture_context
*tctx
,
1845 struct dcerpc_pipe
*p
)
1847 struct winreg_InitiateSystemShutdownEx r
;
1848 uint16_t hostname
= 0x0;
1849 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1852 r
.in
.hostname
= &hostname
;
1853 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1854 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1855 r
.in
.force_apps
= 1;
1860 torture_assert_ntstatus_ok(tctx
,
1861 dcerpc_winreg_InitiateSystemShutdownEx_r(b
, tctx
, &r
),
1862 "InitiateSystemShutdownEx failed");
1864 torture_assert_werr_ok(tctx
, r
.out
.result
,
1865 "InitiateSystemShutdownEx failed");
1867 return test_AbortSystemShutdown(b
, tctx
);
1869 #define MAX_DEPTH 2 /* Only go this far down the tree */
1871 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1872 struct policy_handle
*handle
, int depth
,
1875 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1877 if (depth
== MAX_DEPTH
)
1880 if (!test_QueryInfoKey(b
, tctx
, handle
, NULL
)) {
1883 if (!test_NotifyChangeKeyValue(b
, tctx
, handle
)) {
1886 if (test_security
&& !test_GetKeySecurity(p
, tctx
, handle
, NULL
)) {
1889 if (!test_EnumKey(p
, tctx
, handle
, depth
, test_security
)) {
1892 if (!test_EnumValue(b
, tctx
, handle
, 0xFF, 0xFFFF)) {
1895 test_CloseKey(b
, tctx
, handle
);
1900 static bool test_SetValue_simple(struct dcerpc_binding_handle
*b
,
1901 struct torture_context
*tctx
,
1902 struct policy_handle
*handle
)
1904 const char *value_name
= TEST_VALUE
;
1905 uint32_t value
= 0x12345678;
1906 const char *string
= "torture";
1908 enum winreg_Type types
[] = {
1916 torture_comment(tctx
, "Testing SetValue (standard formats)\n");
1918 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
1920 enum winreg_Type w_type
;
1921 uint32_t w_size
, w_length
;
1926 blob
= data_blob_talloc_zero(tctx
, 4);
1927 SIVAL(blob
.data
, 0, value
);
1930 blob
= data_blob_string_const("binary_blob");
1933 torture_assert(tctx
,
1934 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1938 (void **)&blob
.data
,
1943 torture_assert(tctx
,
1944 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1948 (void **)&blob
.data
,
1951 torture_assert(tctx
, data_blob_realloc(tctx
, &blob
, blob
.length
+ 2), "");
1952 memset(&blob
.data
[blob
.length
- 2], '\0', 2);
1958 torture_assert(tctx
,
1959 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
1960 "test_SetValue failed");
1961 torture_assert(tctx
,
1962 test_QueryValue_full(b
, tctx
, handle
, value_name
, true),
1963 talloc_asprintf(tctx
, "test_QueryValue_full for %s value failed", value_name
));
1964 torture_assert(tctx
,
1965 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
1966 "test_winreg_QueryValue failed");
1967 torture_assert(tctx
,
1968 test_DeleteValue(b
, tctx
, handle
, value_name
),
1969 "test_DeleteValue failed");
1971 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
1972 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
1973 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
1974 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
1977 torture_comment(tctx
, "Testing SetValue (standard formats) succeeded\n");
1982 typedef NTSTATUS (*winreg_open_fn
)(struct dcerpc_binding_handle
*, TALLOC_CTX
*, void *);
1984 static bool test_Open_Security(struct torture_context
*tctx
,
1985 struct dcerpc_pipe
*p
, void *userdata
)
1987 struct policy_handle handle
, newhandle
;
1988 bool ret
= true, created2
= false;
1989 bool created4
= false;
1990 struct winreg_OpenHKLM r
;
1991 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1993 winreg_open_fn open_fn
= userdata
;
1996 r
.in
.system_name
= 0;
1997 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1998 r
.out
.handle
= &handle
;
2000 torture_assert_ntstatus_ok(tctx
, open_fn(b
, tctx
, &r
),
2003 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2005 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2006 torture_comment(tctx
,
2007 "CreateKey (TEST_KEY_BASE) failed\n");
2010 if (test_CreateKey_sd(b
, tctx
, &handle
, TEST_KEY2
,
2011 NULL
, &newhandle
)) {
2015 if (created2
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2016 torture_comment(tctx
, "CloseKey failed\n");
2020 if (test_CreateKey_sd(b
, tctx
, &handle
, TEST_KEY4
, NULL
, &newhandle
)) {
2024 if (created4
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2025 torture_comment(tctx
, "CloseKey failed\n");
2029 if (created4
&& !test_SecurityDescriptors(p
, tctx
, &handle
, TEST_KEY4
)) {
2033 if (created4
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY4
)) {
2034 torture_comment(tctx
, "DeleteKey failed\n");
2038 if (created2
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY2
)) {
2039 torture_comment(tctx
, "DeleteKey failed\n");
2043 /* The HKCR hive has a very large fanout */
2044 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR_r
) {
2045 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, true)) {
2049 if (!test_key(p
, tctx
, &handle
, 0, true)) {
2054 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2059 static bool test_SetValue_extended(struct dcerpc_binding_handle
*b
,
2060 struct torture_context
*tctx
,
2061 struct policy_handle
*handle
)
2063 const char *value_name
= TEST_VALUE
;
2064 enum winreg_Type types
[] = {
2070 REG_DWORD_BIG_ENDIAN
,
2074 REG_FULL_RESOURCE_DESCRIPTOR
,
2075 REG_RESOURCE_REQUIREMENTS_LIST
,
2087 if (torture_setting_bool(tctx
, "samba3", false) ||
2088 torture_setting_bool(tctx
, "samba4", false)) {
2089 torture_skip(tctx
, "skipping extended SetValue test against Samba");
2092 torture_comment(tctx
, "Testing SetValue (extended formats)\n");
2094 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
2095 for (l
=0; l
< 32; l
++) {
2097 enum winreg_Type w_type
;
2098 uint32_t w_size
, w_length
;
2105 data
= talloc_array(tctx
, uint8_t, size
);
2107 generate_random_buffer(data
, size
);
2109 torture_assert(tctx
,
2110 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], data
, size
),
2111 "test_SetValue failed");
2113 torture_assert(tctx
,
2114 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2115 "test_winreg_QueryValue failed");
2117 torture_assert(tctx
,
2118 test_DeleteValue(b
, tctx
, handle
, value_name
),
2119 "test_DeleteValue failed");
2121 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
2122 torture_assert_int_equal(tctx
, w_size
, size
, "winreg size mismatch");
2123 torture_assert_int_equal(tctx
, w_length
, size
, "winreg length mismatch");
2124 torture_assert_mem_equal(tctx
, w_data
, data
, size
, "winreg buffer mismatch");
2128 torture_comment(tctx
, "Testing SetValue (extended formats) succeeded\n");
2133 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2134 #define VALUE_CURRENT_VERSION "CurrentVersion"
2136 static bool test_HKLM_wellknown(struct torture_context
*tctx
,
2137 struct dcerpc_binding_handle
*b
,
2138 struct policy_handle
*handle
)
2140 struct policy_handle newhandle
;
2142 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2143 if (torture_setting_bool(tctx
, "samba3", false)) {
2144 torture_assert(tctx
, _test_OpenKey(b
, tctx
, handle
, KEY_CURRENT_VERSION
, KEY_QUERY_VALUE
, &newhandle
, WERR_OK
, NULL
),
2145 "failed to open current version key");
2147 torture_assert(tctx
, test_OpenKey(b
, tctx
, handle
, KEY_CURRENT_VERSION
, &newhandle
),
2148 "failed to open current version key");
2151 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, VALUE_CURRENT_VERSION
, true),
2152 "failed to query current version");
2153 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "IDoNotExist", false),
2154 "failed to query current version");
2155 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, NULL
, false),
2156 "test_QueryValue_full for NULL value failed");
2157 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "", false),
2158 "test_QueryValue_full for \"\" value failed");
2160 torture_assert(tctx
, test_CloseKey(b
, tctx
, &newhandle
),
2161 "failed to close current version key");
2166 static bool test_Open(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2169 struct policy_handle handle
, newhandle
;
2170 bool ret
= true, created
= false, deleted
= false;
2171 bool created3
= false, created_subkey
= false;
2172 struct winreg_OpenHKLM r
;
2173 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2175 winreg_open_fn open_fn
= userdata
;
2178 r
.in
.system_name
= 0;
2179 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2180 r
.out
.handle
= &handle
;
2182 torture_assert_ntstatus_ok(tctx
, open_fn(b
, tctx
, &r
),
2185 if (open_fn
== (void *)dcerpc_winreg_OpenHKLM_r
) {
2186 torture_assert(tctx
,
2187 test_HKLM_wellknown(tctx
, b
, &handle
),
2188 "failed to test HKLM wellknown keys");
2191 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2193 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2194 torture_comment(tctx
,
2195 "CreateKey (TEST_KEY_BASE) failed\n");
2198 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY1
, NULL
)) {
2199 torture_comment(tctx
,
2200 "CreateKey failed - not considering a failure\n");
2205 if (created
&& !test_FlushKey(b
, tctx
, &handle
)) {
2206 torture_comment(tctx
, "FlushKey failed\n");
2210 if (created
&& !test_OpenKey(b
, tctx
, &handle
, TEST_KEY1
, &newhandle
))
2212 "CreateKey failed (OpenKey after Create didn't work)\n");
2215 torture_assert(tctx
, test_SetValue_simple(b
, tctx
, &newhandle
),
2216 "simple SetValue test failed");
2217 torture_assert(tctx
, test_SetValue_extended(b
, tctx
, &newhandle
),
2218 "extended SetValue test failed");
2221 if (created
&& !test_CloseKey(b
, tctx
, &newhandle
))
2223 "CreateKey failed (CloseKey after Open didn't work)\n");
2225 if (created
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY1
)) {
2226 torture_comment(tctx
, "DeleteKey failed\n");
2232 if (created
&& !test_FlushKey(b
, tctx
, &handle
)) {
2233 torture_comment(tctx
, "FlushKey failed\n");
2237 if (created
&& deleted
&&
2238 !_test_OpenKey(b
, tctx
, &handle
, TEST_KEY1
,
2239 SEC_FLAG_MAXIMUM_ALLOWED
, &newhandle
,
2240 WERR_BADFILE
, NULL
)) {
2241 torture_comment(tctx
,
2242 "DeleteKey failed (OpenKey after Delete "
2243 "did not return WERR_BADFILE)\n");
2247 if (!test_GetVersion(b
, tctx
, &handle
)) {
2248 torture_comment(tctx
, "GetVersion failed\n");
2252 if (created
&& test_CreateKey(b
, tctx
, &handle
, TEST_KEY3
, NULL
)) {
2257 test_CreateKey(b
, tctx
, &handle
, TEST_SUBKEY
, NULL
)) {
2258 created_subkey
= true;
2261 if (created_subkey
&&
2262 !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY3
)) {
2263 torture_comment(tctx
, "DeleteKey failed\n");
2267 /* The HKCR hive has a very large fanout */
2268 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR_r
) {
2269 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, false)) {
2273 if (!test_key(p
, tctx
, &handle
, 0, false)) {
2278 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2283 struct torture_suite
*torture_rpc_winreg(TALLOC_CTX
*mem_ctx
)
2285 struct torture_rpc_tcase
*tcase
;
2286 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WINREG");
2287 struct torture_test
*test
;
2289 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "winreg",
2292 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdown",
2293 test_InitiateSystemShutdown
);
2294 test
->dangerous
= true;
2296 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdownEx",
2297 test_InitiateSystemShutdownEx
);
2298 test
->dangerous
= true;
2300 /* Basic tests without security descriptors */
2301 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-basic",
2303 (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
);
2304 torture_rpc_tcase_add_test_ex(tcase
, "HKU-basic",
2306 (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
);
2307 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-basic",
2309 (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
);
2310 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-basic",
2312 (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
);
2314 /* Security descriptor tests */
2315 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-security",
2317 (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
);
2318 torture_rpc_tcase_add_test_ex(tcase
, "HKU-security",
2320 (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
);
2321 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-security",
2323 (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
);
2324 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-security",
2326 (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
);