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 WERROR expected_result
,
116 enum winreg_CreateAction
*action_taken_p
,
117 struct policy_handle
*new_handle_p
)
119 struct winreg_CreateKey r
;
120 struct policy_handle newhandle
;
121 enum winreg_CreateAction action_taken
= 0;
123 torture_comment(tctx
, "Testing CreateKey(%s)\n", name
);
126 r
.in
.handle
= handle
;
127 init_winreg_String(&r
.in
.name
, name
);
128 init_winreg_String(&r
.in
.keyclass
, kclass
);
129 r
.in
.options
= options
;
130 r
.in
.access_mask
= access_mask
;
131 r
.in
.action_taken
= &action_taken
;
132 r
.in
.secdesc
= secdesc
;
133 r
.out
.new_handle
= &newhandle
;
134 r
.out
.action_taken
= &action_taken
;
136 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey_r(b
, tctx
, &r
),
139 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
, "CreateKey failed");
142 *new_handle_p
= newhandle
;
144 if (action_taken_p
) {
145 *action_taken_p
= *r
.out
.action_taken
;
151 static bool test_CreateKey(struct dcerpc_binding_handle
*b
,
152 struct torture_context
*tctx
,
153 struct policy_handle
*handle
, const char *name
,
156 return test_CreateKey_opts(tctx
, b
, handle
, name
, kclass
,
157 REG_KEYTYPE_NON_VOLATILE
,
158 SEC_FLAG_MAXIMUM_ALLOWED
,
161 NULL
, /* action_taken */
162 NULL
/* new_handle */);
166 createkey testing with a SD
168 static bool test_CreateKey_sd(struct dcerpc_binding_handle
*b
,
169 struct torture_context
*tctx
,
170 struct policy_handle
*handle
, const char *name
,
172 struct policy_handle
*newhandle
)
174 struct winreg_CreateKey r
;
175 enum winreg_CreateAction action_taken
= 0;
176 struct security_descriptor
*sd
;
178 struct winreg_SecBuf secbuf
;
180 sd
= security_descriptor_dacl_create(tctx
,
183 SID_NT_AUTHENTICATED_USERS
,
184 SEC_ACE_TYPE_ACCESS_ALLOWED
,
186 SEC_ACE_FLAG_OBJECT_INHERIT
|
187 SEC_ACE_FLAG_CONTAINER_INHERIT
,
190 torture_assert_ndr_success(tctx
,
191 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
192 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
193 "Failed to push security_descriptor ?!\n");
195 secbuf
.sd
.data
= sdblob
.data
;
196 secbuf
.sd
.len
= sdblob
.length
;
197 secbuf
.sd
.size
= sdblob
.length
;
198 secbuf
.length
= sdblob
.length
-10;
202 r
.in
.handle
= handle
;
203 r
.out
.new_handle
= newhandle
;
204 init_winreg_String(&r
.in
.name
, name
);
205 init_winreg_String(&r
.in
.keyclass
, kclass
);
207 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
208 r
.in
.action_taken
= r
.out
.action_taken
= &action_taken
;
209 r
.in
.secdesc
= &secbuf
;
211 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CreateKey_r(b
, tctx
, &r
),
212 "CreateKey with sd failed");
214 torture_assert_werr_ok(tctx
, r
.out
.result
, "CreateKey with sd failed");
219 static bool _test_GetKeySecurity(struct dcerpc_pipe
*p
,
220 struct torture_context
*tctx
,
221 struct policy_handle
*handle
,
222 uint32_t *sec_info_ptr
,
224 struct security_descriptor
**sd_out
)
226 struct winreg_GetKeySecurity r
;
227 struct security_descriptor
*sd
= NULL
;
230 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
233 sec_info
= *sec_info_ptr
;
235 sec_info
= SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
;
240 r
.in
.handle
= handle
;
241 r
.in
.sec_info
= sec_info
;
242 r
.in
.sd
= r
.out
.sd
= talloc_zero(tctx
, struct KeySecurityData
);
243 r
.in
.sd
->size
= 0x1000;
245 torture_assert_ntstatus_ok(tctx
,
246 dcerpc_winreg_GetKeySecurity_r(b
, tctx
, &r
),
247 "GetKeySecurity failed");
249 torture_assert_werr_equal(tctx
, r
.out
.result
, get_werr
,
250 "GetKeySecurity failed");
252 sdblob
.data
= r
.out
.sd
->data
;
253 sdblob
.length
= r
.out
.sd
->len
;
255 sd
= talloc_zero(tctx
, struct security_descriptor
);
257 torture_assert_ndr_success(tctx
,
258 ndr_pull_struct_blob(&sdblob
, tctx
, NULL
, sd
,
259 (ndr_pull_flags_fn_t
)ndr_pull_security_descriptor
),
260 "pull_security_descriptor failed");
262 if (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
) {
263 NDR_PRINT_DEBUG(security_descriptor
, sd
);
275 static bool test_GetKeySecurity(struct dcerpc_pipe
*p
,
276 struct torture_context
*tctx
,
277 struct policy_handle
*handle
,
278 struct security_descriptor
**sd_out
)
280 return _test_GetKeySecurity(p
, tctx
, handle
, NULL
, WERR_OK
, sd_out
);
283 static bool _test_SetKeySecurity(struct dcerpc_pipe
*p
,
284 struct torture_context
*tctx
,
285 struct policy_handle
*handle
,
286 uint32_t *sec_info_ptr
,
287 struct security_descriptor
*sd
,
290 struct winreg_SetKeySecurity r
;
291 struct KeySecurityData
*sdata
= NULL
;
294 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
298 if (sd
&& (p
->conn
->flags
& DCERPC_DEBUG_PRINT_OUT
)) {
299 NDR_PRINT_DEBUG(security_descriptor
, sd
);
302 torture_assert_ndr_success(tctx
,
303 ndr_push_struct_blob(&sdblob
, tctx
, NULL
, sd
,
304 (ndr_push_flags_fn_t
)ndr_push_security_descriptor
),
305 "push_security_descriptor failed");
307 sdata
= talloc_zero(tctx
, struct KeySecurityData
);
308 sdata
->data
= sdblob
.data
;
309 sdata
->size
= sdblob
.length
;
310 sdata
->len
= sdblob
.length
;
313 sec_info
= *sec_info_ptr
;
315 sec_info
= SECINFO_UNPROTECTED_SACL
|
316 SECINFO_UNPROTECTED_DACL
;
318 sec_info
|= SECINFO_OWNER
;
321 sec_info
|= SECINFO_GROUP
;
324 sec_info
|= SECINFO_SACL
;
327 sec_info
|= SECINFO_DACL
;
331 r
.in
.handle
= handle
;
332 r
.in
.sec_info
= sec_info
;
335 torture_assert_ntstatus_ok(tctx
,
336 dcerpc_winreg_SetKeySecurity_r(b
, tctx
, &r
),
337 "SetKeySecurity failed");
339 torture_assert_werr_equal(tctx
, r
.out
.result
, werr
,
340 "SetKeySecurity failed");
345 static bool test_SetKeySecurity(struct dcerpc_pipe
*p
,
346 struct torture_context
*tctx
,
347 struct policy_handle
*handle
,
348 struct security_descriptor
*sd
)
350 return _test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, WERR_OK
);
353 static bool test_CloseKey(struct dcerpc_binding_handle
*b
,
354 struct torture_context
*tctx
,
355 struct policy_handle
*handle
)
357 struct winreg_CloseKey r
;
360 r
.in
.handle
= r
.out
.handle
= handle
;
362 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_CloseKey_r(b
, tctx
, &r
),
365 torture_assert_werr_ok(tctx
, r
.out
.result
, "CloseKey failed");
370 static bool test_FlushKey(struct dcerpc_binding_handle
*b
,
371 struct torture_context
*tctx
,
372 struct policy_handle
*handle
)
374 struct winreg_FlushKey r
;
377 r
.in
.handle
= handle
;
379 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_FlushKey_r(b
, tctx
, &r
),
382 torture_assert_werr_ok(tctx
, r
.out
.result
, "FlushKey failed");
387 static bool test_OpenKey_opts(struct torture_context
*tctx
,
388 struct dcerpc_binding_handle
*b
,
389 struct policy_handle
*hive_handle
,
391 enum winreg_KeyType options
,
392 uint32_t access_mask
,
393 struct policy_handle
*key_handle
,
394 WERROR expected_result
)
396 struct winreg_OpenKey r
;
399 r
.in
.parent_handle
= hive_handle
;
400 init_winreg_String(&r
.in
.keyname
, keyname
);
401 r
.in
.options
= options
;
402 r
.in
.access_mask
= access_mask
;
403 r
.out
.handle
= key_handle
;
405 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_OpenKey_r(b
, tctx
, &r
),
408 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
414 static bool test_OpenKey(struct dcerpc_binding_handle
*b
,
415 struct torture_context
*tctx
,
416 struct policy_handle
*hive_handle
,
417 const char *keyname
, struct policy_handle
*key_handle
)
419 return test_OpenKey_opts(tctx
, b
, hive_handle
, keyname
,
420 REG_KEYTYPE_NON_VOLATILE
,
421 SEC_FLAG_MAXIMUM_ALLOWED
,
426 static bool test_Cleanup(struct dcerpc_binding_handle
*b
,
427 struct torture_context
*tctx
,
428 struct policy_handle
*handle
, const char *key
)
430 struct winreg_DeleteKey r
;
433 r
.in
.handle
= handle
;
435 init_winreg_String(&r
.in
.key
, key
);
436 dcerpc_winreg_DeleteKey_r(b
, tctx
, &r
);
441 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe
*p
,
442 struct torture_context
*tctx
,
443 struct policy_handle
*handle
,
447 struct security_descriptor
*sd
= NULL
;
449 if (!_test_GetKeySecurity(p
, tctx
, handle
, NULL
, get_werr
, &sd
)) {
453 if (!_test_SetKeySecurity(p
, tctx
, handle
, NULL
, sd
, set_werr
)) {
460 static bool test_SecurityDescriptor(struct dcerpc_pipe
*p
,
461 struct torture_context
*tctx
,
462 struct policy_handle
*handle
,
465 struct policy_handle new_handle
;
467 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
469 torture_comment(tctx
, "SecurityDescriptor get & set\n");
471 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
475 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
480 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
487 static bool _test_SecurityDescriptor(struct dcerpc_pipe
*p
,
488 struct torture_context
*tctx
,
489 struct policy_handle
*handle
,
490 uint32_t access_mask
,
496 struct policy_handle new_handle
;
498 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
501 test_OpenKey_opts(tctx
, b
, handle
, key
,
502 REG_KEYTYPE_NON_VOLATILE
,
506 "failed to open key");
508 if (!W_ERROR_IS_OK(open_werr
)) {
512 if (!_test_GetSetSecurityDescriptor(p
, tctx
, &new_handle
,
513 get_werr
, set_werr
)) {
517 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
524 static bool test_dacl_trustee_present(struct dcerpc_pipe
*p
,
525 struct torture_context
*tctx
,
526 struct policy_handle
*handle
,
527 const struct dom_sid
*sid
)
529 struct security_descriptor
*sd
= NULL
;
532 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
536 if (!sd
|| !sd
->dacl
) {
540 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
541 if (dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) {
549 static bool _test_dacl_trustee_present(struct dcerpc_pipe
*p
,
550 struct torture_context
*tctx
,
551 struct policy_handle
*handle
,
553 const struct dom_sid
*sid
)
555 struct policy_handle new_handle
;
557 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
559 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
563 ret
= test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
);
565 test_CloseKey(b
, tctx
, &new_handle
);
570 static bool test_sacl_trustee_present(struct dcerpc_pipe
*p
,
571 struct torture_context
*tctx
,
572 struct policy_handle
*handle
,
573 const struct dom_sid
*sid
)
575 struct security_descriptor
*sd
= NULL
;
577 uint32_t sec_info
= SECINFO_SACL
;
579 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
583 if (!sd
|| !sd
->sacl
) {
587 for (i
= 0; i
< sd
->sacl
->num_aces
; i
++) {
588 if (dom_sid_equal(&sd
->sacl
->aces
[i
].trustee
, sid
)) {
596 static bool _test_sacl_trustee_present(struct dcerpc_pipe
*p
,
597 struct torture_context
*tctx
,
598 struct policy_handle
*handle
,
600 const struct dom_sid
*sid
)
602 struct policy_handle new_handle
;
604 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
607 test_OpenKey_opts(tctx
, b
, handle
, key
,
608 REG_KEYTYPE_NON_VOLATILE
,
609 SEC_FLAG_SYSTEM_SECURITY
,
612 "failed to open key");
614 ret
= test_sacl_trustee_present(p
, tctx
, &new_handle
, sid
);
616 test_CloseKey(b
, tctx
, &new_handle
);
621 static bool test_owner_present(struct dcerpc_pipe
*p
,
622 struct torture_context
*tctx
,
623 struct policy_handle
*handle
,
624 const struct dom_sid
*sid
)
626 struct security_descriptor
*sd
= NULL
;
627 uint32_t sec_info
= SECINFO_OWNER
;
629 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
633 if (!sd
|| !sd
->owner_sid
) {
637 return dom_sid_equal(sd
->owner_sid
, sid
);
640 static bool _test_owner_present(struct dcerpc_pipe
*p
,
641 struct torture_context
*tctx
,
642 struct policy_handle
*handle
,
644 const struct dom_sid
*sid
)
646 struct policy_handle new_handle
;
648 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
650 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
654 ret
= test_owner_present(p
, tctx
, &new_handle
, sid
);
656 test_CloseKey(b
, tctx
, &new_handle
);
661 static bool test_group_present(struct dcerpc_pipe
*p
,
662 struct torture_context
*tctx
,
663 struct policy_handle
*handle
,
664 const struct dom_sid
*sid
)
666 struct security_descriptor
*sd
= NULL
;
667 uint32_t sec_info
= SECINFO_GROUP
;
669 if (!_test_GetKeySecurity(p
, tctx
, handle
, &sec_info
, WERR_OK
, &sd
)) {
673 if (!sd
|| !sd
->group_sid
) {
677 return dom_sid_equal(sd
->group_sid
, sid
);
680 static bool _test_group_present(struct dcerpc_pipe
*p
,
681 struct torture_context
*tctx
,
682 struct policy_handle
*handle
,
684 const struct dom_sid
*sid
)
686 struct policy_handle new_handle
;
688 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
690 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
694 ret
= test_group_present(p
, tctx
, &new_handle
, sid
);
696 test_CloseKey(b
, tctx
, &new_handle
);
701 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe
*p
,
702 struct torture_context
*tctx
,
703 struct policy_handle
*handle
,
704 const struct dom_sid
*sid
,
707 struct security_descriptor
*sd
= NULL
;
710 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
714 if (!sd
|| !sd
->dacl
) {
718 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
719 if ((dom_sid_equal(&sd
->dacl
->aces
[i
].trustee
, sid
)) &&
720 (sd
->dacl
->aces
[i
].flags
== flags
)) {
728 static bool test_dacl_ace_present(struct dcerpc_pipe
*p
,
729 struct torture_context
*tctx
,
730 struct policy_handle
*handle
,
731 const struct security_ace
*ace
)
733 struct security_descriptor
*sd
= NULL
;
736 if (!test_GetKeySecurity(p
, tctx
, handle
, &sd
)) {
740 if (!sd
|| !sd
->dacl
) {
744 for (i
= 0; i
< sd
->dacl
->num_aces
; i
++) {
745 if (security_ace_equal(&sd
->dacl
->aces
[i
], ace
)) {
753 static bool test_RestoreSecurity(struct dcerpc_pipe
*p
,
754 struct torture_context
*tctx
,
755 struct policy_handle
*handle
,
757 struct security_descriptor
*sd
)
759 struct policy_handle new_handle
;
761 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
763 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
767 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
771 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
778 static bool test_BackupSecurity(struct dcerpc_pipe
*p
,
779 struct torture_context
*tctx
,
780 struct policy_handle
*handle
,
782 struct security_descriptor
**sd
)
784 struct policy_handle new_handle
;
786 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
788 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
792 if (!test_GetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
796 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
803 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe
*p
,
804 struct torture_context
*tctx
,
805 struct policy_handle
*handle
,
809 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
824 struct security_descriptor
*sd
= NULL
;
825 struct security_descriptor
*sd_orig
= NULL
;
826 struct security_ace
*ace
= NULL
;
827 struct policy_handle new_handle
;
829 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
831 torture_comment(tctx
, "SecurityDescriptor inheritance\n");
833 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
837 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
841 sd_orig
= security_descriptor_copy(tctx
, sd
);
842 if (sd_orig
== NULL
) {
846 ace
= security_ace_create(tctx
,
848 SEC_ACE_TYPE_ACCESS_ALLOWED
,
850 SEC_ACE_FLAG_CONTAINER_INHERIT
);
852 torture_assert_ntstatus_ok(tctx
,
853 security_descriptor_dacl_add(sd
, ace
),
854 "failed to add ace");
856 /* FIXME: add further tests for these flags */
857 sd
->type
|= SEC_DESC_DACL_AUTO_INHERIT_REQ
|
858 SEC_DESC_SACL_AUTO_INHERITED
;
860 if (!test_SetKeySecurity(p
, tctx
, &new_handle
, sd
)) {
865 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
866 "new ACE not present!");
868 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
872 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, NULL
)) {
877 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
882 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
883 torture_comment(tctx
, "inherited ACE not present!\n");
888 test_CloseKey(b
, tctx
, &new_handle
);
889 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
894 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
899 if (!test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
900 torture_comment(tctx
, "inherited ACE not present!\n");
906 test_CloseKey(b
, tctx
, &new_handle
);
907 test_Cleanup(b
, tctx
, handle
, TEST_SUBKEY_SD
);
908 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
913 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe
*p
,
914 struct torture_context
*tctx
,
915 struct policy_handle
*handle
,
919 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
931 struct security_descriptor
*sd
= NULL
;
932 struct security_descriptor
*sd_orig
= NULL
;
933 struct security_ace
*ace
= NULL
;
934 struct policy_handle new_handle
;
935 struct dom_sid
*sid
= NULL
;
937 uint8_t ace_flags
= 0x0;
938 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
940 torture_comment(tctx
, "SecurityDescriptor inheritance block\n");
942 if (!test_OpenKey(b
, tctx
, handle
, key
, &new_handle
)) {
946 if (!_test_GetKeySecurity(p
, tctx
, &new_handle
, NULL
, WERR_OK
, &sd
)) {
950 sd_orig
= security_descriptor_copy(tctx
, sd
);
951 if (sd_orig
== NULL
) {
955 ace
= security_ace_create(tctx
,
957 SEC_ACE_TYPE_ACCESS_ALLOWED
,
959 SEC_ACE_FLAG_CONTAINER_INHERIT
|
960 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
);
962 torture_assert_ntstatus_ok(tctx
,
963 security_descriptor_dacl_add(sd
, ace
),
964 "failed to add ace");
966 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, NULL
, sd
, WERR_OK
)) {
971 test_dacl_ace_present(p
, tctx
, &new_handle
, ace
),
972 "new ACE not present!");
974 if (!test_CloseKey(b
, tctx
, &new_handle
)) {
978 if (!test_CreateKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, NULL
)) {
982 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBSUBKEY_SD
, &new_handle
)) {
987 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
988 torture_comment(tctx
, "inherited ACE present but should not!\n");
993 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
998 if (test_dacl_trustee_present(p
, tctx
, &new_handle
, sid
)) {
999 torture_comment(tctx
, "inherited trustee SID present but should not!\n");
1004 test_CloseKey(b
, tctx
, &new_handle
);
1006 if (!test_OpenKey(b
, tctx
, handle
, TEST_SUBKEY_SD
, &new_handle
)) {
1011 if (test_dacl_ace_present(p
, tctx
, &new_handle
, ace
)) {
1012 torture_comment(tctx
, "inherited ACE present but should not!\n");
1017 if (!test_dacl_trustee_flags_present(p
, tctx
, &new_handle
, sid
, ace_flags
)) {
1018 torture_comment(tctx
, "inherited trustee SID with flags 0x%02x not present!\n",
1025 test_CloseKey(b
, tctx
, &new_handle
);
1026 test_Cleanup(b
, tctx
, handle
, TEST_SUBKEY_SD
);
1027 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1032 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe
*p
,
1033 struct torture_context
*tctx
,
1034 struct policy_handle
*handle
,
1040 struct winreg_mask_result_table
{
1041 uint32_t access_mask
;
1045 } sd_mask_tests
[] = {
1047 WERR_ACCESS_DENIED
, WERR_BADFILE
, WERR_FOOBAR
},
1048 { SEC_FLAG_MAXIMUM_ALLOWED
,
1049 WERR_OK
, WERR_OK
, WERR_OK
},
1050 { SEC_STD_WRITE_DAC
,
1051 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
},
1052 { SEC_FLAG_SYSTEM_SECURITY
,
1053 WERR_OK
, WERR_ACCESS_DENIED
, WERR_FOOBAR
}
1056 /* FIXME: before this test can ever run successfully we need a way to
1057 * correctly read a NULL security_descritpor in ndr, get the required
1058 * length, requery, etc.
1063 for (i
=0; i
< ARRAY_SIZE(sd_mask_tests
); i
++) {
1065 torture_comment(tctx
,
1066 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1067 sd_mask_tests
[i
].access_mask
);
1068 torture_comment(tctx
,
1069 "expecting: open %s, get: %s, set: %s\n",
1070 win_errstr(sd_mask_tests
[i
].open_werr
),
1071 win_errstr(sd_mask_tests
[i
].get_werr
),
1072 win_errstr(sd_mask_tests
[i
].set_werr
));
1074 if (_test_SecurityDescriptor(p
, tctx
, handle
,
1075 sd_mask_tests
[i
].access_mask
, key
,
1076 sd_mask_tests
[i
].open_werr
,
1077 sd_mask_tests
[i
].get_werr
,
1078 sd_mask_tests
[i
].set_werr
)) {
1086 typedef bool (*secinfo_verify_fn
)(struct dcerpc_pipe
*,
1087 struct torture_context
*,
1088 struct policy_handle
*,
1090 const struct dom_sid
*);
1092 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe
*p
,
1093 struct torture_context
*tctx
,
1094 struct policy_handle
*handle
,
1097 uint32_t access_mask
,
1099 struct security_descriptor
*sd
,
1101 bool expect_present
,
1102 bool (*fn
) (struct dcerpc_pipe
*,
1103 struct torture_context
*,
1104 struct policy_handle
*,
1106 const struct dom_sid
*),
1107 const struct dom_sid
*sid
)
1109 struct policy_handle new_handle
;
1110 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1112 torture_comment(tctx
, "SecurityDescriptor (%s) sets for secinfo: "
1113 "0x%08x, access_mask: 0x%08x\n",
1114 test
, sec_info
, access_mask
);
1116 torture_assert(tctx
,
1117 test_OpenKey_opts(tctx
, b
, handle
, key
,
1118 REG_KEYTYPE_NON_VOLATILE
,
1122 "failed to open key");
1124 if (!_test_SetKeySecurity(p
, tctx
, &new_handle
, &sec_info
,
1127 torture_warning(tctx
,
1128 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1131 test_CloseKey(b
, tctx
, &new_handle
);
1135 test_CloseKey(b
, tctx
, &new_handle
);
1137 if (W_ERROR_IS_OK(set_werr
)) {
1139 present
= fn(p
, tctx
, handle
, key
, sid
);
1140 if ((expect_present
) && (!present
)) {
1141 torture_warning(tctx
,
1142 "%s sid is not present!\n",
1146 if ((!expect_present
) && (present
)) {
1147 torture_warning(tctx
,
1148 "%s sid is present but not expected!\n",
1157 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe
*p
,
1158 struct torture_context
*tctx
,
1159 struct policy_handle
*handle
,
1162 struct security_descriptor
*sd_orig
= NULL
;
1163 struct dom_sid
*sid
= NULL
;
1167 struct security_descriptor
*sd_owner
=
1168 security_descriptor_dacl_create(tctx
,
1170 TEST_SID
, NULL
, NULL
);
1172 struct security_descriptor
*sd_group
=
1173 security_descriptor_dacl_create(tctx
,
1175 NULL
, TEST_SID
, NULL
);
1177 struct security_descriptor
*sd_dacl
=
1178 security_descriptor_dacl_create(tctx
,
1182 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1185 SID_NT_AUTHENTICATED_USERS
,
1186 SEC_ACE_TYPE_ACCESS_ALLOWED
,
1191 struct security_descriptor
*sd_sacl
=
1192 security_descriptor_sacl_create(tctx
,
1196 SEC_ACE_TYPE_SYSTEM_AUDIT
,
1198 SEC_ACE_FLAG_SUCCESSFUL_ACCESS
,
1201 struct winreg_secinfo_table
{
1202 struct security_descriptor
*sd
;
1206 secinfo_verify_fn fn
;
1209 struct winreg_secinfo_table sec_info_owner_tests
[] = {
1210 { sd_owner
, 0, WERR_OK
,
1211 false, (secinfo_verify_fn
)_test_owner_present
},
1212 { sd_owner
, SECINFO_OWNER
, WERR_OK
,
1213 true, (secinfo_verify_fn
)_test_owner_present
},
1214 { sd_owner
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1215 { sd_owner
, SECINFO_DACL
, WERR_OK
,
1216 true, (secinfo_verify_fn
)_test_owner_present
},
1217 { sd_owner
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1220 uint32_t sd_owner_good_access_masks
[] = {
1221 SEC_FLAG_MAXIMUM_ALLOWED
,
1222 /* SEC_STD_WRITE_OWNER, */
1225 struct winreg_secinfo_table sec_info_group_tests
[] = {
1226 { sd_group
, 0, WERR_OK
,
1227 false, (secinfo_verify_fn
)_test_group_present
},
1228 { sd_group
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1229 { sd_group
, SECINFO_GROUP
, WERR_OK
,
1230 true, (secinfo_verify_fn
)_test_group_present
},
1231 { sd_group
, SECINFO_DACL
, WERR_OK
,
1232 true, (secinfo_verify_fn
)_test_group_present
},
1233 { sd_group
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1236 uint32_t sd_group_good_access_masks
[] = {
1237 SEC_FLAG_MAXIMUM_ALLOWED
,
1240 struct winreg_secinfo_table sec_info_dacl_tests
[] = {
1241 { sd_dacl
, 0, WERR_OK
,
1242 false, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1243 { sd_dacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1244 { sd_dacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1245 { sd_dacl
, SECINFO_DACL
, WERR_OK
,
1246 true, (secinfo_verify_fn
)_test_dacl_trustee_present
},
1247 { sd_dacl
, SECINFO_SACL
, WERR_ACCESS_DENIED
},
1250 uint32_t sd_dacl_good_access_masks
[] = {
1251 SEC_FLAG_MAXIMUM_ALLOWED
,
1255 struct winreg_secinfo_table sec_info_sacl_tests
[] = {
1256 { sd_sacl
, 0, WERR_OK
,
1257 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1258 { sd_sacl
, SECINFO_OWNER
, WERR_INVALID_PARAM
},
1259 { sd_sacl
, SECINFO_GROUP
, WERR_INVALID_PARAM
},
1260 { sd_sacl
, SECINFO_DACL
, WERR_OK
,
1261 false, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1262 { sd_sacl
, SECINFO_SACL
, WERR_OK
,
1263 true, (secinfo_verify_fn
)_test_sacl_trustee_present
},
1266 uint32_t sd_sacl_good_access_masks
[] = {
1267 SEC_FLAG_MAXIMUM_ALLOWED
| SEC_FLAG_SYSTEM_SECURITY
,
1268 /* SEC_FLAG_SYSTEM_SECURITY, */
1271 sid
= dom_sid_parse_talloc(tctx
, TEST_SID
);
1276 if (!test_BackupSecurity(p
, tctx
, handle
, key
, &sd_orig
)) {
1282 for (i
=0; i
< ARRAY_SIZE(sec_info_owner_tests
); i
++) {
1284 for (a
=0; a
< ARRAY_SIZE(sd_owner_good_access_masks
); a
++) {
1286 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1289 sd_owner_good_access_masks
[a
],
1290 sec_info_owner_tests
[i
].sec_info
,
1291 sec_info_owner_tests
[i
].sd
,
1292 sec_info_owner_tests
[i
].set_werr
,
1293 sec_info_owner_tests
[i
].sid_present
,
1294 sec_info_owner_tests
[i
].fn
,
1297 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1306 for (i
=0; i
< ARRAY_SIZE(sec_info_group_tests
); i
++) {
1308 for (a
=0; a
< ARRAY_SIZE(sd_group_good_access_masks
); a
++) {
1310 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1313 sd_group_good_access_masks
[a
],
1314 sec_info_group_tests
[i
].sec_info
,
1315 sec_info_group_tests
[i
].sd
,
1316 sec_info_group_tests
[i
].set_werr
,
1317 sec_info_group_tests
[i
].sid_present
,
1318 sec_info_group_tests
[i
].fn
,
1321 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1330 for (i
=0; i
< ARRAY_SIZE(sec_info_dacl_tests
); i
++) {
1332 for (a
=0; a
< ARRAY_SIZE(sd_dacl_good_access_masks
); a
++) {
1334 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1337 sd_dacl_good_access_masks
[a
],
1338 sec_info_dacl_tests
[i
].sec_info
,
1339 sec_info_dacl_tests
[i
].sd
,
1340 sec_info_dacl_tests
[i
].set_werr
,
1341 sec_info_dacl_tests
[i
].sid_present
,
1342 sec_info_dacl_tests
[i
].fn
,
1345 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1354 for (i
=0; i
< ARRAY_SIZE(sec_info_sacl_tests
); i
++) {
1356 for (a
=0; a
< ARRAY_SIZE(sd_sacl_good_access_masks
); a
++) {
1358 if (!test_SetSecurityDescriptor_SecInfo(p
, tctx
, handle
,
1361 sd_sacl_good_access_masks
[a
],
1362 sec_info_sacl_tests
[i
].sec_info
,
1363 sec_info_sacl_tests
[i
].sd
,
1364 sec_info_sacl_tests
[i
].set_werr
,
1365 sec_info_sacl_tests
[i
].sid_present
,
1366 sec_info_sacl_tests
[i
].fn
,
1369 torture_comment(tctx
, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1377 test_RestoreSecurity(p
, tctx
, handle
, key
, sd_orig
);
1382 static bool test_SecurityDescriptors(struct dcerpc_pipe
*p
,
1383 struct torture_context
*tctx
,
1384 struct policy_handle
*handle
,
1389 if (!test_SecurityDescriptor(p
, tctx
, handle
, key
)) {
1390 torture_comment(tctx
, "test_SecurityDescriptor failed\n");
1394 if (!test_SecurityDescriptorInheritance(p
, tctx
, handle
, key
)) {
1395 torture_comment(tctx
, "test_SecurityDescriptorInheritance failed\n");
1399 if (!test_SecurityDescriptorBlockInheritance(p
, tctx
, handle
, key
)) {
1400 torture_comment(tctx
, "test_SecurityDescriptorBlockInheritance failed\n");
1404 if (!test_SecurityDescriptorsSecInfo(p
, tctx
, handle
, key
)) {
1405 torture_comment(tctx
, "test_SecurityDescriptorsSecInfo failed\n");
1409 if (!test_SecurityDescriptorsMasks(p
, tctx
, handle
, key
)) {
1410 torture_comment(tctx
, "test_SecurityDescriptorsMasks failed\n");
1417 static bool test_DeleteKey_opts(struct dcerpc_binding_handle
*b
,
1418 struct torture_context
*tctx
,
1419 struct policy_handle
*handle
,
1421 WERROR expected_result
)
1423 struct winreg_DeleteKey r
;
1425 torture_comment(tctx
, "Testing DeleteKey(%s)\n", key
);
1427 r
.in
.handle
= handle
;
1428 init_winreg_String(&r
.in
.key
, key
);
1430 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteKey_r(b
, tctx
, &r
),
1431 "Delete Key failed");
1432 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_result
,
1433 "DeleteKey failed");
1438 static bool test_DeleteKey(struct dcerpc_binding_handle
*b
,
1439 struct torture_context
*tctx
,
1440 struct policy_handle
*handle
, const char *key
)
1442 return test_DeleteKey_opts(b
, tctx
, handle
, key
, WERR_OK
);
1445 static bool test_QueryInfoKey(struct dcerpc_binding_handle
*b
,
1446 struct torture_context
*tctx
,
1447 struct policy_handle
*handle
, char *kclass
)
1449 struct winreg_QueryInfoKey r
;
1450 uint32_t num_subkeys
, max_subkeylen
, max_classlen
,
1451 num_values
, max_valnamelen
, max_valbufsize
,
1453 NTTIME last_changed_time
;
1456 r
.in
.handle
= handle
;
1457 r
.out
.num_subkeys
= &num_subkeys
;
1458 r
.out
.max_subkeylen
= &max_subkeylen
;
1459 r
.out
.max_classlen
= &max_classlen
;
1460 r
.out
.num_values
= &num_values
;
1461 r
.out
.max_valnamelen
= &max_valnamelen
;
1462 r
.out
.max_valbufsize
= &max_valbufsize
;
1463 r
.out
.secdescsize
= &secdescsize
;
1464 r
.out
.last_changed_time
= &last_changed_time
;
1466 r
.out
.classname
= talloc(tctx
, struct winreg_String
);
1468 r
.in
.classname
= talloc(tctx
, struct winreg_String
);
1469 init_winreg_String(r
.in
.classname
, kclass
);
1471 torture_assert_ntstatus_ok(tctx
,
1472 dcerpc_winreg_QueryInfoKey_r(b
, tctx
, &r
),
1473 "QueryInfoKey failed");
1475 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryInfoKey failed");
1480 static bool test_SetValue(struct dcerpc_binding_handle
*b
,
1481 struct torture_context
*tctx
,
1482 struct policy_handle
*handle
,
1483 const char *value_name
,
1484 enum winreg_Type type
,
1488 struct winreg_SetValue r
;
1489 struct winreg_String name
;
1491 torture_comment(tctx
, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1492 value_name
, str_regtype(type
), size
);
1494 init_winreg_String(&name
, value_name
);
1496 r
.in
.handle
= handle
;
1502 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_SetValue_r(b
, tctx
, &r
),
1503 "winreg_SetValue failed");
1504 torture_assert_werr_ok(tctx
, r
.out
.result
,
1505 "winreg_SetValue failed");
1510 static bool test_DeleteValue(struct dcerpc_binding_handle
*b
,
1511 struct torture_context
*tctx
,
1512 struct policy_handle
*handle
,
1513 const char *value_name
)
1515 struct winreg_DeleteValue r
;
1516 struct winreg_String value
;
1518 torture_comment(tctx
, "Testing DeleteValue(%s)\n", value_name
);
1520 init_winreg_String(&value
, value_name
);
1522 r
.in
.handle
= handle
;
1525 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_DeleteValue_r(b
, tctx
, &r
),
1526 "winreg_DeleteValue failed");
1527 torture_assert_werr_ok(tctx
, r
.out
.result
,
1528 "winreg_DeleteValue failed");
1533 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1534 struct policy_handle
*handle
, int depth
,
1535 bool test_security
);
1537 static bool test_EnumKey(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1538 struct policy_handle
*handle
, int depth
,
1541 struct winreg_EnumKey r
;
1542 struct winreg_StringBuf kclass
, name
;
1545 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1551 r
.in
.handle
= handle
;
1552 r
.in
.enum_index
= 0;
1554 r
.in
.keyclass
= &kclass
;
1556 r
.in
.last_changed_time
= &t
;
1562 status
= dcerpc_winreg_EnumKey_r(b
, tctx
, &r
);
1564 if (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
1565 struct policy_handle key_handle
;
1567 torture_comment(tctx
, "EnumKey: %d: %s\n",
1571 if (!test_OpenKey(b
, tctx
, handle
, r
.out
.name
->name
,
1574 test_key(p
, tctx
, &key_handle
,
1575 depth
+ 1, test_security
);
1581 } while (NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
));
1583 torture_assert_ntstatus_ok(tctx
, status
, "EnumKey failed");
1585 if (!W_ERROR_IS_OK(r
.out
.result
) &&
1586 !W_ERROR_EQUAL(r
.out
.result
, WERR_NO_MORE_ITEMS
)) {
1587 torture_fail(tctx
, "EnumKey failed");
1593 static bool test_QueryMultipleValues(struct dcerpc_binding_handle
*b
,
1594 struct torture_context
*tctx
,
1595 struct policy_handle
*handle
,
1596 const char *valuename
)
1598 struct winreg_QueryMultipleValues r
;
1603 r
.in
.key_handle
= handle
;
1604 r
.in
.values
= r
.out
.values
= talloc_array(tctx
, struct QueryMultipleValue
, 1);
1605 r
.in
.values
[0].name
= talloc(tctx
, struct winreg_String
);
1606 r
.in
.values
[0].name
->name
= valuename
;
1607 r
.in
.values
[0].offset
= 0;
1608 r
.in
.values
[0].length
= 0;
1609 r
.in
.values
[0].type
= 0;
1611 r
.in
.num_values
= 1;
1612 r
.in
.buffer_size
= r
.out
.buffer_size
= talloc(tctx
, uint32_t);
1613 *r
.in
.buffer_size
= bufsize
;
1615 *r
.in
.buffer_size
= bufsize
;
1616 r
.in
.buffer
= r
.out
.buffer
= talloc_zero_array(tctx
, uint8_t,
1619 status
= dcerpc_winreg_QueryMultipleValues_r(b
, tctx
, &r
);
1621 if(NT_STATUS_IS_ERR(status
))
1622 torture_fail(tctx
, "QueryMultipleValues failed");
1624 talloc_free(r
.in
.buffer
);
1626 } while (W_ERROR_EQUAL(r
.out
.result
, WERR_MORE_DATA
));
1628 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryMultipleValues failed");
1633 static bool test_QueryValue(struct dcerpc_binding_handle
*b
,
1634 struct torture_context
*tctx
,
1635 struct policy_handle
*handle
,
1636 const char *valuename
)
1638 struct winreg_QueryValue r
;
1640 enum winreg_Type zero_type
= 0;
1641 uint32_t offered
= 0xfff;
1645 r
.in
.handle
= handle
;
1647 r
.in
.value_name
= talloc_zero(tctx
, struct winreg_String
);
1648 r
.in
.value_name
->name
= valuename
;
1649 r
.in
.type
= &zero_type
;
1650 r
.in
.data_size
= &offered
;
1651 r
.in
.data_length
= &zero
;
1653 status
= dcerpc_winreg_QueryValue_r(b
, tctx
, &r
);
1654 if (NT_STATUS_IS_ERR(status
)) {
1655 torture_fail(tctx
, "QueryValue failed");
1658 torture_assert_werr_ok(tctx
, r
.out
.result
, "QueryValue failed");
1663 static bool test_QueryValue_full(struct dcerpc_binding_handle
*b
,
1664 struct torture_context
*tctx
,
1665 struct policy_handle
*handle
,
1666 const char *valuename
,
1667 bool existing_value
)
1669 struct winreg_QueryValue r
;
1670 struct winreg_String value_name
;
1671 enum winreg_Type type
= REG_NONE
;
1672 uint32_t data_size
= 0;
1673 uint32_t real_data_size
= 0;
1674 uint32_t data_length
= 0;
1675 uint8_t *data
= NULL
;
1676 WERROR expected_error
= WERR_BADFILE
;
1678 if (valuename
== NULL
) {
1679 expected_error
= WERR_INVALID_PARAM
;
1684 init_winreg_String(&value_name
, NULL
);
1686 torture_comment(tctx
, "Testing QueryValue(%s)\n", valuename
);
1688 r
.in
.handle
= handle
;
1689 r
.in
.value_name
= &value_name
;
1691 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
), "QueryValue failed");
1692 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1693 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1695 init_winreg_String(&value_name
, valuename
);
1696 r
.in
.value_name
= &value_name
;
1698 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1699 "QueryValue failed");
1700 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1701 "QueryValue failed");
1705 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1706 "QueryValue failed");
1707 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1708 "QueryValue failed");
1710 r
.in
.data_length
= &data_length
;
1711 r
.out
.data_length
= &data_length
;
1712 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1713 "QueryValue failed");
1714 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_INVALID_PARAM
,
1715 "QueryValue failed");
1717 r
.in
.data_size
= &data_size
;
1718 r
.out
.data_size
= &data_size
;
1719 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1720 "QueryValue failed");
1721 if (existing_value
) {
1722 torture_assert_werr_ok(tctx
, r
.out
.result
,
1723 "QueryValue failed");
1725 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1726 "QueryValue failed");
1729 real_data_size
= *r
.out
.data_size
;
1731 data
= talloc_zero_array(tctx
, uint8_t, 0);
1734 *r
.in
.data_size
= 0;
1735 *r
.out
.data_size
= 0;
1736 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1737 "QueryValue failed");
1738 if (existing_value
) {
1739 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_MORE_DATA
,
1740 "QueryValue failed");
1742 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1743 "QueryValue failed");
1746 data
= talloc_zero_array(tctx
, uint8_t, real_data_size
);
1749 r
.in
.data_size
= &real_data_size
;
1750 r
.out
.data_size
= &real_data_size
;
1751 torture_assert_ntstatus_ok(tctx
, dcerpc_winreg_QueryValue_r(b
, tctx
, &r
),
1752 "QueryValue failed");
1753 if (existing_value
) {
1754 torture_assert_werr_ok(tctx
, r
.out
.result
,
1755 "QueryValue failed");
1757 torture_assert_werr_equal(tctx
, r
.out
.result
, expected_error
,
1758 "QueryValue failed");
1764 static bool test_EnumValue(struct dcerpc_binding_handle
*b
,
1765 struct torture_context
*tctx
,
1766 struct policy_handle
*handle
, int max_valnamelen
,
1769 struct winreg_EnumValue r
;
1770 enum winreg_Type type
= 0;
1771 uint32_t size
= max_valbufsize
, zero
= 0;
1774 struct winreg_ValNameBuf name
;
1780 r
.in
.handle
= handle
;
1781 r
.in
.enum_index
= 0;
1786 r
.in
.length
= &zero
;
1790 torture_assert_ntstatus_ok(tctx
,
1791 dcerpc_winreg_EnumValue_r(b
, tctx
, &r
),
1792 "EnumValue failed");
1794 if (W_ERROR_IS_OK(r
.out
.result
)) {
1795 ret
&= test_QueryValue(b
, tctx
, handle
,
1797 ret
&= test_QueryMultipleValues(b
, tctx
, handle
,
1802 } while (W_ERROR_IS_OK(r
.out
.result
));
1804 torture_assert_werr_equal(tctx
, r
.out
.result
, WERR_NO_MORE_ITEMS
,
1805 "EnumValue failed");
1810 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle
*b
,
1811 struct torture_context
*tctx
)
1813 struct winreg_AbortSystemShutdown r
;
1814 uint16_t server
= 0x0;
1817 r
.in
.server
= &server
;
1819 torture_assert_ntstatus_ok(tctx
,
1820 dcerpc_winreg_AbortSystemShutdown_r(b
, tctx
, &r
),
1821 "AbortSystemShutdown failed");
1823 torture_assert_werr_ok(tctx
, r
.out
.result
,
1824 "AbortSystemShutdown failed");
1829 static bool test_InitiateSystemShutdown(struct torture_context
*tctx
,
1830 struct dcerpc_pipe
*p
)
1832 struct winreg_InitiateSystemShutdown r
;
1833 uint16_t hostname
= 0x0;
1834 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1837 r
.in
.hostname
= &hostname
;
1838 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1839 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1840 r
.in
.force_apps
= 1;
1844 torture_assert_ntstatus_ok(tctx
,
1845 dcerpc_winreg_InitiateSystemShutdown_r(b
, tctx
, &r
),
1846 "InitiateSystemShutdown failed");
1848 torture_assert_werr_ok(tctx
, r
.out
.result
,
1849 "InitiateSystemShutdown failed");
1851 return test_AbortSystemShutdown(b
, tctx
);
1855 static bool test_InitiateSystemShutdownEx(struct torture_context
*tctx
,
1856 struct dcerpc_pipe
*p
)
1858 struct winreg_InitiateSystemShutdownEx r
;
1859 uint16_t hostname
= 0x0;
1860 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1863 r
.in
.hostname
= &hostname
;
1864 r
.in
.message
= talloc(tctx
, struct lsa_StringLarge
);
1865 init_lsa_StringLarge(r
.in
.message
, "spottyfood");
1866 r
.in
.force_apps
= 1;
1871 torture_assert_ntstatus_ok(tctx
,
1872 dcerpc_winreg_InitiateSystemShutdownEx_r(b
, tctx
, &r
),
1873 "InitiateSystemShutdownEx failed");
1875 torture_assert_werr_ok(tctx
, r
.out
.result
,
1876 "InitiateSystemShutdownEx failed");
1878 return test_AbortSystemShutdown(b
, tctx
);
1880 #define MAX_DEPTH 2 /* Only go this far down the tree */
1882 static bool test_key(struct dcerpc_pipe
*p
, struct torture_context
*tctx
,
1883 struct policy_handle
*handle
, int depth
,
1886 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
1888 if (depth
== MAX_DEPTH
)
1891 if (!test_QueryInfoKey(b
, tctx
, handle
, NULL
)) {
1894 if (!test_NotifyChangeKeyValue(b
, tctx
, handle
)) {
1897 if (test_security
&& !test_GetKeySecurity(p
, tctx
, handle
, NULL
)) {
1900 if (!test_EnumKey(p
, tctx
, handle
, depth
, test_security
)) {
1903 if (!test_EnumValue(b
, tctx
, handle
, 0xFF, 0xFFFF)) {
1906 test_CloseKey(b
, tctx
, handle
);
1911 static bool test_SetValue_simple(struct dcerpc_binding_handle
*b
,
1912 struct torture_context
*tctx
,
1913 struct policy_handle
*handle
)
1915 const char *value_name
= TEST_VALUE
;
1916 uint32_t value
= 0x12345678;
1917 const char *string
= "torture";
1919 enum winreg_Type types
[] = {
1927 torture_comment(tctx
, "Testing SetValue (standard formats)\n");
1929 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
1931 enum winreg_Type w_type
;
1932 uint32_t w_size
, w_length
;
1937 blob
= data_blob_talloc_zero(tctx
, 4);
1938 SIVAL(blob
.data
, 0, value
);
1941 blob
= data_blob_string_const("binary_blob");
1944 torture_assert(tctx
,
1945 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1949 (void **)&blob
.data
,
1954 torture_assert(tctx
,
1955 convert_string_talloc_convenience(tctx
, lp_iconv_convenience(tctx
->lp_ctx
),
1959 (void **)&blob
.data
,
1962 torture_assert(tctx
, data_blob_realloc(tctx
, &blob
, blob
.length
+ 2), "");
1963 memset(&blob
.data
[blob
.length
- 2], '\0', 2);
1969 torture_assert(tctx
,
1970 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], blob
.data
, blob
.length
),
1971 "test_SetValue failed");
1972 torture_assert(tctx
,
1973 test_QueryValue_full(b
, tctx
, handle
, value_name
, true),
1974 talloc_asprintf(tctx
, "test_QueryValue_full for %s value failed", value_name
));
1975 torture_assert(tctx
,
1976 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
1977 "test_winreg_QueryValue failed");
1978 torture_assert(tctx
,
1979 test_DeleteValue(b
, tctx
, handle
, value_name
),
1980 "test_DeleteValue failed");
1982 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
1983 torture_assert_int_equal(tctx
, w_size
, blob
.length
, "winreg size mismatch");
1984 torture_assert_int_equal(tctx
, w_length
, blob
.length
, "winreg length mismatch");
1985 torture_assert_mem_equal(tctx
, w_data
, blob
.data
, blob
.length
, "winreg buffer mismatch");
1988 torture_comment(tctx
, "Testing SetValue (standard formats) succeeded\n");
1993 typedef NTSTATUS (*winreg_open_fn
)(struct dcerpc_binding_handle
*, TALLOC_CTX
*, void *);
1995 static bool test_Open_Security(struct torture_context
*tctx
,
1996 struct dcerpc_pipe
*p
, void *userdata
)
1998 struct policy_handle handle
, newhandle
;
1999 bool ret
= true, created2
= false;
2000 bool created4
= false;
2001 struct winreg_OpenHKLM r
;
2002 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2004 winreg_open_fn open_fn
= userdata
;
2007 r
.in
.system_name
= 0;
2008 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2009 r
.out
.handle
= &handle
;
2011 torture_assert_ntstatus_ok(tctx
, open_fn(b
, tctx
, &r
),
2014 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2016 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2017 torture_comment(tctx
,
2018 "CreateKey (TEST_KEY_BASE) failed\n");
2021 if (test_CreateKey_sd(b
, tctx
, &handle
, TEST_KEY2
,
2022 NULL
, &newhandle
)) {
2026 if (created2
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2027 torture_comment(tctx
, "CloseKey failed\n");
2031 if (test_CreateKey_sd(b
, tctx
, &handle
, TEST_KEY4
, NULL
, &newhandle
)) {
2035 if (created4
&& !test_CloseKey(b
, tctx
, &newhandle
)) {
2036 torture_comment(tctx
, "CloseKey failed\n");
2040 if (created4
&& !test_SecurityDescriptors(p
, tctx
, &handle
, TEST_KEY4
)) {
2044 if (created4
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY4
)) {
2045 torture_comment(tctx
, "DeleteKey failed\n");
2049 if (created2
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY2
)) {
2050 torture_comment(tctx
, "DeleteKey failed\n");
2054 /* The HKCR hive has a very large fanout */
2055 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR_r
) {
2056 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, true)) {
2060 if (!test_key(p
, tctx
, &handle
, 0, true)) {
2065 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2070 static bool test_SetValue_extended(struct dcerpc_binding_handle
*b
,
2071 struct torture_context
*tctx
,
2072 struct policy_handle
*handle
)
2074 const char *value_name
= TEST_VALUE
;
2075 enum winreg_Type types
[] = {
2081 REG_DWORD_BIG_ENDIAN
,
2085 REG_FULL_RESOURCE_DESCRIPTOR
,
2086 REG_RESOURCE_REQUIREMENTS_LIST
,
2098 if (torture_setting_bool(tctx
, "samba3", false) ||
2099 torture_setting_bool(tctx
, "samba4", false)) {
2100 torture_skip(tctx
, "skipping extended SetValue test against Samba");
2103 torture_comment(tctx
, "Testing SetValue (extended formats)\n");
2105 for (t
=0; t
< ARRAY_SIZE(types
); t
++) {
2106 for (l
=0; l
< 32; l
++) {
2108 enum winreg_Type w_type
;
2109 uint32_t w_size
, w_length
;
2116 data
= talloc_array(tctx
, uint8_t, size
);
2118 generate_random_buffer(data
, size
);
2120 torture_assert(tctx
,
2121 test_SetValue(b
, tctx
, handle
, value_name
, types
[t
], data
, size
),
2122 "test_SetValue failed");
2124 torture_assert(tctx
,
2125 test_winreg_QueryValue(tctx
, b
, handle
, value_name
, &w_type
, &w_size
, &w_length
, &w_data
),
2126 "test_winreg_QueryValue failed");
2128 torture_assert(tctx
,
2129 test_DeleteValue(b
, tctx
, handle
, value_name
),
2130 "test_DeleteValue failed");
2132 torture_assert_int_equal(tctx
, w_type
, types
[t
], "winreg type mismatch");
2133 torture_assert_int_equal(tctx
, w_size
, size
, "winreg size mismatch");
2134 torture_assert_int_equal(tctx
, w_length
, size
, "winreg length mismatch");
2135 torture_assert_mem_equal(tctx
, w_data
, data
, size
, "winreg buffer mismatch");
2139 torture_comment(tctx
, "Testing SetValue (extended formats) succeeded\n");
2144 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2145 #define VALUE_CURRENT_VERSION "CurrentVersion"
2147 static bool test_HKLM_wellknown(struct torture_context
*tctx
,
2148 struct dcerpc_binding_handle
*b
,
2149 struct policy_handle
*handle
)
2151 struct policy_handle newhandle
;
2153 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2154 if (torture_setting_bool(tctx
, "samba3", false)) {
2155 torture_assert(tctx
, test_OpenKey_opts(tctx
, b
, handle
,
2156 KEY_CURRENT_VERSION
,
2157 REG_KEYTYPE_NON_VOLATILE
,
2161 "failed to open current version key");
2163 torture_assert(tctx
, test_OpenKey(b
, tctx
, handle
, KEY_CURRENT_VERSION
, &newhandle
),
2164 "failed to open current version key");
2167 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, VALUE_CURRENT_VERSION
, true),
2168 "failed to query current version");
2169 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "IDoNotExist", false),
2170 "failed to query current version");
2171 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, NULL
, false),
2172 "test_QueryValue_full for NULL value failed");
2173 torture_assert(tctx
, test_QueryValue_full(b
, tctx
, &newhandle
, "", false),
2174 "test_QueryValue_full for \"\" value failed");
2176 torture_assert(tctx
, test_CloseKey(b
, tctx
, &newhandle
),
2177 "failed to close current version key");
2182 static bool test_Open(struct torture_context
*tctx
, struct dcerpc_pipe
*p
,
2185 struct policy_handle handle
, newhandle
;
2186 bool ret
= true, created
= false, deleted
= false;
2187 bool created3
= false, created_subkey
= false;
2188 struct winreg_OpenHKLM r
;
2189 struct dcerpc_binding_handle
*b
= p
->binding_handle
;
2191 winreg_open_fn open_fn
= userdata
;
2194 r
.in
.system_name
= 0;
2195 r
.in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2196 r
.out
.handle
= &handle
;
2198 torture_assert_ntstatus_ok(tctx
, open_fn(b
, tctx
, &r
),
2201 if (open_fn
== (void *)dcerpc_winreg_OpenHKLM_r
) {
2202 torture_assert(tctx
,
2203 test_HKLM_wellknown(tctx
, b
, &handle
),
2204 "failed to test HKLM wellknown keys");
2207 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2209 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY_BASE
, NULL
)) {
2210 torture_comment(tctx
,
2211 "CreateKey (TEST_KEY_BASE) failed\n");
2214 if (!test_CreateKey(b
, tctx
, &handle
, TEST_KEY1
, NULL
)) {
2215 torture_comment(tctx
,
2216 "CreateKey failed - not considering a failure\n");
2221 if (created
&& !test_FlushKey(b
, tctx
, &handle
)) {
2222 torture_comment(tctx
, "FlushKey failed\n");
2226 if (created
&& !test_OpenKey(b
, tctx
, &handle
, TEST_KEY1
, &newhandle
))
2228 "CreateKey failed (OpenKey after Create didn't work)\n");
2231 torture_assert(tctx
, test_SetValue_simple(b
, tctx
, &newhandle
),
2232 "simple SetValue test failed");
2233 torture_assert(tctx
, test_SetValue_extended(b
, tctx
, &newhandle
),
2234 "extended SetValue test failed");
2237 if (created
&& !test_CloseKey(b
, tctx
, &newhandle
))
2239 "CreateKey failed (CloseKey after Open didn't work)\n");
2241 if (created
&& !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY1
)) {
2242 torture_comment(tctx
, "DeleteKey failed\n");
2248 if (created
&& !test_FlushKey(b
, tctx
, &handle
)) {
2249 torture_comment(tctx
, "FlushKey failed\n");
2253 if (created
&& deleted
&&
2254 !test_OpenKey_opts(tctx
, b
, &handle
, TEST_KEY1
,
2255 REG_KEYTYPE_NON_VOLATILE
,
2256 SEC_FLAG_MAXIMUM_ALLOWED
,
2259 torture_comment(tctx
,
2260 "DeleteKey failed (OpenKey after Delete "
2261 "did not return WERR_BADFILE)\n");
2265 if (!test_GetVersion(b
, tctx
, &handle
)) {
2266 torture_comment(tctx
, "GetVersion failed\n");
2270 if (created
&& test_CreateKey(b
, tctx
, &handle
, TEST_KEY3
, NULL
)) {
2275 test_CreateKey(b
, tctx
, &handle
, TEST_SUBKEY
, NULL
)) {
2276 created_subkey
= true;
2279 if (created_subkey
&&
2280 !test_DeleteKey(b
, tctx
, &handle
, TEST_KEY3
)) {
2281 torture_comment(tctx
, "DeleteKey failed\n");
2285 /* The HKCR hive has a very large fanout */
2286 if (open_fn
== (void *)dcerpc_winreg_OpenHKCR_r
) {
2287 if(!test_key(p
, tctx
, &handle
, MAX_DEPTH
- 1, false)) {
2291 if (!test_key(p
, tctx
, &handle
, 0, false)) {
2296 test_Cleanup(b
, tctx
, &handle
, TEST_KEY_BASE
);
2301 struct torture_suite
*torture_rpc_winreg(TALLOC_CTX
*mem_ctx
)
2303 struct torture_rpc_tcase
*tcase
;
2304 struct torture_suite
*suite
= torture_suite_create(mem_ctx
, "WINREG");
2305 struct torture_test
*test
;
2307 tcase
= torture_suite_add_rpc_iface_tcase(suite
, "winreg",
2310 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdown",
2311 test_InitiateSystemShutdown
);
2312 test
->dangerous
= true;
2314 test
= torture_rpc_tcase_add_test(tcase
, "InitiateSystemShutdownEx",
2315 test_InitiateSystemShutdownEx
);
2316 test
->dangerous
= true;
2318 /* Basic tests without security descriptors */
2319 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-basic",
2321 (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
);
2322 torture_rpc_tcase_add_test_ex(tcase
, "HKU-basic",
2324 (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
);
2325 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-basic",
2327 (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
);
2328 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-basic",
2330 (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
);
2332 /* Security descriptor tests */
2333 torture_rpc_tcase_add_test_ex(tcase
, "HKLM-security",
2335 (winreg_open_fn
)dcerpc_winreg_OpenHKLM_r
);
2336 torture_rpc_tcase_add_test_ex(tcase
, "HKU-security",
2338 (winreg_open_fn
)dcerpc_winreg_OpenHKU_r
);
2339 torture_rpc_tcase_add_test_ex(tcase
, "HKCR-security",
2341 (winreg_open_fn
)dcerpc_winreg_OpenHKCR_r
);
2342 torture_rpc_tcase_add_test_ex(tcase
, "HKCU-security",
2344 (winreg_open_fn
)dcerpc_winreg_OpenHKCU_r
);