2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007,2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
43 #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
45 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
47 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
52 static void init_winreg_String(struct winreg_String *name, const char *s)
56 name->name_len = 2 * (strlen_m(s) + 1);
57 name->name_size = name->name_len;
64 static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 struct torture_context *tctx,
66 struct policy_handle *handle)
68 struct winreg_GetVersion r;
71 torture_comment(tctx, "Testing GetVersion\n");
77 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
80 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
85 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 struct torture_context *tctx,
87 struct policy_handle *handle)
89 struct winreg_NotifyChangeKeyValue r;
93 r.in.watch_subtree = true;
94 r.in.notify_filter = 0;
95 r.in.unknown = r.in.unknown2 = 0;
96 init_winreg_String(&r.in.string1, NULL);
97 init_winreg_String(&r.in.string2, NULL);
99 torture_assert_ntstatus_ok(tctx,
100 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 "NotifyChangeKeyValue failed");
103 if (!W_ERROR_IS_OK(r.out.result)) {
104 torture_comment(tctx,
105 "NotifyChangeKeyValue failed - %s - not considering\n",
106 win_errstr(r.out.result));
113 static bool test_CreateKey_opts(struct torture_context *tctx,
114 struct dcerpc_binding_handle *b,
115 struct policy_handle *handle,
119 uint32_t access_mask,
120 struct winreg_SecBuf *secdesc,
121 WERROR expected_result,
122 enum winreg_CreateAction *action_taken_p,
123 struct policy_handle *new_handle_p)
125 struct winreg_CreateKey r;
126 struct policy_handle newhandle;
127 enum winreg_CreateAction action_taken = 0;
129 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
132 r.in.handle = handle;
133 init_winreg_String(&r.in.name, name);
134 init_winreg_String(&r.in.keyclass, kclass);
135 r.in.options = options;
136 r.in.access_mask = access_mask;
137 r.in.action_taken = &action_taken;
138 r.in.secdesc = secdesc;
139 r.out.new_handle = &newhandle;
140 r.out.action_taken = &action_taken;
142 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
145 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
148 *new_handle_p = newhandle;
150 if (action_taken_p) {
151 *action_taken_p = *r.out.action_taken;
157 static bool test_CreateKey(struct dcerpc_binding_handle *b,
158 struct torture_context *tctx,
159 struct policy_handle *handle, const char *name,
162 return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 REG_OPTION_NON_VOLATILE,
164 SEC_FLAG_MAXIMUM_ALLOWED,
167 NULL, /* action_taken */
168 NULL /* new_handle */);
172 createkey testing with a SD
174 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175 struct torture_context *tctx,
176 struct policy_handle *handle, const char *name,
178 struct policy_handle *newhandle)
180 struct winreg_CreateKey r;
181 enum winreg_CreateAction action_taken = 0;
182 struct security_descriptor *sd;
184 struct winreg_SecBuf secbuf;
186 sd = security_descriptor_dacl_create(tctx,
189 SID_NT_AUTHENTICATED_USERS,
190 SEC_ACE_TYPE_ACCESS_ALLOWED,
192 SEC_ACE_FLAG_OBJECT_INHERIT |
193 SEC_ACE_FLAG_CONTAINER_INHERIT,
196 torture_assert_ndr_success(tctx,
197 ndr_push_struct_blob(&sdblob, tctx, sd,
198 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199 "Failed to push security_descriptor ?!\n");
201 secbuf.sd.data = sdblob.data;
202 secbuf.sd.len = sdblob.length;
203 secbuf.sd.size = sdblob.length;
204 secbuf.length = sdblob.length-10;
208 r.in.handle = handle;
209 r.out.new_handle = newhandle;
210 init_winreg_String(&r.in.name, name);
211 init_winreg_String(&r.in.keyclass, kclass);
213 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 r.in.action_taken = r.out.action_taken = &action_taken;
215 r.in.secdesc = &secbuf;
217 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 "CreateKey with sd failed");
220 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
225 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226 struct torture_context *tctx,
227 struct policy_handle *handle,
228 uint32_t *sec_info_ptr,
230 struct security_descriptor **sd_out)
232 struct winreg_GetKeySecurity r;
233 struct security_descriptor *sd = NULL;
236 struct dcerpc_binding_handle *b = p->binding_handle;
239 sec_info = *sec_info_ptr;
241 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
246 r.in.handle = handle;
247 r.in.sec_info = sec_info;
248 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 r.in.sd->size = 0x1000;
251 torture_assert_ntstatus_ok(tctx,
252 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 "GetKeySecurity failed");
255 torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 "GetKeySecurity failed");
258 sdblob.data = r.out.sd->data;
259 sdblob.length = r.out.sd->len;
261 sd = talloc_zero(tctx, struct security_descriptor);
263 torture_assert_ndr_success(tctx,
264 ndr_pull_struct_blob(&sdblob, tctx, sd,
265 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266 "pull_security_descriptor failed");
268 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 NDR_PRINT_DEBUG(security_descriptor, sd);
281 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282 struct torture_context *tctx,
283 struct policy_handle *handle,
284 struct security_descriptor **sd_out)
286 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
289 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290 struct torture_context *tctx,
291 struct policy_handle *handle,
292 uint32_t *sec_info_ptr,
293 struct security_descriptor *sd,
296 struct winreg_SetKeySecurity r;
297 struct KeySecurityData *sdata = NULL;
300 struct dcerpc_binding_handle *b = p->binding_handle;
304 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 NDR_PRINT_DEBUG(security_descriptor, sd);
308 torture_assert_ndr_success(tctx,
309 ndr_push_struct_blob(&sdblob, tctx, sd,
310 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311 "push_security_descriptor failed");
313 sdata = talloc_zero(tctx, struct KeySecurityData);
314 sdata->data = sdblob.data;
315 sdata->size = sdblob.length;
316 sdata->len = sdblob.length;
319 sec_info = *sec_info_ptr;
321 sec_info = SECINFO_UNPROTECTED_SACL |
322 SECINFO_UNPROTECTED_DACL;
324 sec_info |= SECINFO_OWNER;
327 sec_info |= SECINFO_GROUP;
330 sec_info |= SECINFO_SACL;
333 sec_info |= SECINFO_DACL;
337 r.in.handle = handle;
338 r.in.sec_info = sec_info;
341 torture_assert_ntstatus_ok(tctx,
342 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 "SetKeySecurity failed");
345 torture_assert_werr_equal(tctx, r.out.result, werr,
346 "SetKeySecurity failed");
351 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352 struct torture_context *tctx,
353 struct policy_handle *handle,
354 struct security_descriptor *sd)
356 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
359 static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 struct torture_context *tctx,
361 struct policy_handle *handle)
363 struct winreg_CloseKey r;
366 r.in.handle = r.out.handle = handle;
368 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
371 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
376 static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 struct torture_context *tctx,
378 struct policy_handle *handle)
380 struct winreg_FlushKey r;
383 r.in.handle = handle;
385 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
388 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
393 static bool test_OpenKey_opts(struct torture_context *tctx,
394 struct dcerpc_binding_handle *b,
395 struct policy_handle *hive_handle,
398 uint32_t access_mask,
399 struct policy_handle *key_handle,
400 WERROR expected_result)
402 struct winreg_OpenKey r;
405 r.in.parent_handle = hive_handle;
406 init_winreg_String(&r.in.keyname, keyname);
407 r.in.options = options;
408 r.in.access_mask = access_mask;
409 r.out.handle = key_handle;
411 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
414 torture_assert_werr_equal(tctx, r.out.result, expected_result,
420 static bool test_OpenKey(struct dcerpc_binding_handle *b,
421 struct torture_context *tctx,
422 struct policy_handle *hive_handle,
423 const char *keyname, struct policy_handle *key_handle)
425 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 REG_OPTION_NON_VOLATILE,
427 SEC_FLAG_MAXIMUM_ALLOWED,
432 static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 struct torture_context *tctx,
434 struct policy_handle *handle, const char *key)
436 struct winreg_DeleteKey r;
439 r.in.handle = handle;
441 init_winreg_String(&r.in.key, key);
442 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
447 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448 struct torture_context *tctx,
449 struct policy_handle *handle,
453 struct security_descriptor *sd = NULL;
455 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
459 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
466 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467 struct torture_context *tctx,
468 struct policy_handle *handle,
471 struct policy_handle new_handle;
473 struct dcerpc_binding_handle *b = p->binding_handle;
475 torture_comment(tctx, "SecurityDescriptor get & set\n");
477 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
481 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
486 if (!test_CloseKey(b, tctx, &new_handle)) {
493 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494 struct torture_context *tctx,
495 struct policy_handle *handle,
496 uint32_t access_mask,
502 struct policy_handle new_handle;
504 struct dcerpc_binding_handle *b = p->binding_handle;
507 test_OpenKey_opts(tctx, b, handle, key,
508 REG_OPTION_NON_VOLATILE,
512 "failed to open key");
514 if (!W_ERROR_IS_OK(open_werr)) {
518 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 get_werr, set_werr)) {
523 if (!test_CloseKey(b, tctx, &new_handle)) {
530 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531 struct torture_context *tctx,
532 struct policy_handle *handle,
533 const struct dom_sid *sid)
535 struct security_descriptor *sd = NULL;
538 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
542 if (!sd || !sd->dacl) {
546 for (i = 0; i < sd->dacl->num_aces; i++) {
547 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
555 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
556 struct torture_context *tctx,
557 struct policy_handle *handle,
559 const struct dom_sid *sid)
561 struct policy_handle new_handle;
563 struct dcerpc_binding_handle *b = p->binding_handle;
565 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
569 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
571 test_CloseKey(b, tctx, &new_handle);
576 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
577 struct torture_context *tctx,
578 struct policy_handle *handle,
579 const struct dom_sid *sid)
581 struct security_descriptor *sd = NULL;
583 uint32_t sec_info = SECINFO_SACL;
585 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
589 if (!sd || !sd->sacl) {
593 for (i = 0; i < sd->sacl->num_aces; i++) {
594 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
602 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603 struct torture_context *tctx,
604 struct policy_handle *handle,
606 const struct dom_sid *sid)
608 struct policy_handle new_handle;
610 struct dcerpc_binding_handle *b = p->binding_handle;
613 test_OpenKey_opts(tctx, b, handle, key,
614 REG_OPTION_NON_VOLATILE,
615 SEC_FLAG_SYSTEM_SECURITY,
618 "failed to open key");
620 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
622 test_CloseKey(b, tctx, &new_handle);
627 static bool test_owner_present(struct dcerpc_pipe *p,
628 struct torture_context *tctx,
629 struct policy_handle *handle,
630 const struct dom_sid *sid)
632 struct security_descriptor *sd = NULL;
633 uint32_t sec_info = SECINFO_OWNER;
635 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
639 if (!sd || !sd->owner_sid) {
643 return dom_sid_equal(sd->owner_sid, sid);
646 static bool _test_owner_present(struct dcerpc_pipe *p,
647 struct torture_context *tctx,
648 struct policy_handle *handle,
650 const struct dom_sid *sid)
652 struct policy_handle new_handle;
654 struct dcerpc_binding_handle *b = p->binding_handle;
656 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
660 ret = test_owner_present(p, tctx, &new_handle, sid);
662 test_CloseKey(b, tctx, &new_handle);
667 static bool test_group_present(struct dcerpc_pipe *p,
668 struct torture_context *tctx,
669 struct policy_handle *handle,
670 const struct dom_sid *sid)
672 struct security_descriptor *sd = NULL;
673 uint32_t sec_info = SECINFO_GROUP;
675 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
679 if (!sd || !sd->group_sid) {
683 return dom_sid_equal(sd->group_sid, sid);
686 static bool _test_group_present(struct dcerpc_pipe *p,
687 struct torture_context *tctx,
688 struct policy_handle *handle,
690 const struct dom_sid *sid)
692 struct policy_handle new_handle;
694 struct dcerpc_binding_handle *b = p->binding_handle;
696 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
700 ret = test_group_present(p, tctx, &new_handle, sid);
702 test_CloseKey(b, tctx, &new_handle);
707 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708 struct torture_context *tctx,
709 struct policy_handle *handle,
710 const struct dom_sid *sid,
713 struct security_descriptor *sd = NULL;
716 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
720 if (!sd || !sd->dacl) {
724 for (i = 0; i < sd->dacl->num_aces; i++) {
725 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 (sd->dacl->aces[i].flags == flags)) {
734 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735 struct torture_context *tctx,
736 struct policy_handle *handle,
737 const struct security_ace *ace)
739 struct security_descriptor *sd = NULL;
742 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
746 if (!sd || !sd->dacl) {
750 for (i = 0; i < sd->dacl->num_aces; i++) {
751 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
759 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760 struct torture_context *tctx,
761 struct policy_handle *handle,
763 struct security_descriptor *sd)
765 struct policy_handle new_handle;
767 struct dcerpc_binding_handle *b = p->binding_handle;
769 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
773 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
777 if (!test_CloseKey(b, tctx, &new_handle)) {
784 static bool test_BackupSecurity(struct dcerpc_pipe *p,
785 struct torture_context *tctx,
786 struct policy_handle *handle,
788 struct security_descriptor **sd)
790 struct policy_handle new_handle;
792 struct dcerpc_binding_handle *b = p->binding_handle;
794 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
798 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
802 if (!test_CloseKey(b, tctx, &new_handle)) {
809 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810 struct torture_context *tctx,
811 struct policy_handle *handle,
815 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
830 struct security_descriptor *sd = NULL;
831 struct security_descriptor *sd_orig = NULL;
832 struct security_ace *ace = NULL;
833 struct policy_handle new_handle;
835 struct dcerpc_binding_handle *b = p->binding_handle;
836 const char *test_subkey_sd;
837 const char *test_subsubkey_sd;
839 torture_comment(tctx, "SecurityDescriptor inheritance\n");
841 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
845 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
849 sd_orig = security_descriptor_copy(tctx, sd);
850 if (sd_orig == NULL) {
854 ace = security_ace_create(tctx,
856 SEC_ACE_TYPE_ACCESS_ALLOWED,
858 SEC_ACE_FLAG_CONTAINER_INHERIT);
860 torture_assert_ntstatus_ok(tctx,
861 security_descriptor_dacl_add(sd, ace),
862 "failed to add ace");
864 /* FIXME: add further tests for these flags */
865 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 SEC_DESC_SACL_AUTO_INHERITED;
868 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
873 test_dacl_ace_present(p, tctx, &new_handle, ace),
874 "new ACE not present!");
876 if (!test_CloseKey(b, tctx, &new_handle)) {
880 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
882 if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
887 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
892 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 torture_comment(tctx, "inherited ACE not present!\n");
898 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
900 test_CloseKey(b, tctx, &new_handle);
901 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
906 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
911 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 torture_comment(tctx, "inherited ACE not present!\n");
918 test_CloseKey(b, tctx, &new_handle);
919 test_Cleanup(b, tctx, handle, test_subkey_sd);
920 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
925 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926 struct torture_context *tctx,
927 struct policy_handle *handle,
931 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
943 struct security_descriptor *sd = NULL;
944 struct security_descriptor *sd_orig = NULL;
945 struct security_ace *ace = NULL;
946 struct policy_handle new_handle;
947 struct dom_sid *sid = NULL;
949 uint8_t ace_flags = 0x0;
950 struct dcerpc_binding_handle *b = p->binding_handle;
951 const char *test_subkey_sd;
952 const char *test_subsubkey_sd;
954 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
956 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
960 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
964 sd_orig = security_descriptor_copy(tctx, sd);
965 if (sd_orig == NULL) {
969 ace = security_ace_create(tctx,
971 SEC_ACE_TYPE_ACCESS_ALLOWED,
973 SEC_ACE_FLAG_CONTAINER_INHERIT |
974 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
976 torture_assert_ntstatus_ok(tctx,
977 security_descriptor_dacl_add(sd, ace),
978 "failed to add ace");
980 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
985 test_dacl_ace_present(p, tctx, &new_handle, ace),
986 "new ACE not present!");
988 if (!test_CloseKey(b, tctx, &new_handle)) {
992 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
995 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
999 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1004 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 torture_comment(tctx, "inherited ACE present but should not!\n");
1010 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1015 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1021 test_CloseKey(b, tctx, &new_handle);
1023 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1028 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 torture_comment(tctx, "inherited ACE present but should not!\n");
1034 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1042 test_CloseKey(b, tctx, &new_handle);
1043 test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1049 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 struct torture_context *tctx,
1051 struct policy_handle *handle,
1057 struct winreg_mask_result_table {
1058 uint32_t access_mask;
1062 } sd_mask_tests[] = {
1064 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1065 { SEC_FLAG_MAXIMUM_ALLOWED,
1066 WERR_OK, WERR_OK, WERR_OK },
1067 { SEC_STD_WRITE_DAC,
1068 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069 { SEC_FLAG_SYSTEM_SECURITY,
1070 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1073 /* FIXME: before this test can ever run successfully we need a way to
1074 * correctly read a NULL security_descritpor in ndr, get the required
1075 * length, requery, etc.
1080 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1082 torture_comment(tctx,
1083 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084 sd_mask_tests[i].access_mask);
1085 torture_comment(tctx,
1086 "expecting: open %s, get: %s, set: %s\n",
1087 win_errstr(sd_mask_tests[i].open_werr),
1088 win_errstr(sd_mask_tests[i].get_werr),
1089 win_errstr(sd_mask_tests[i].set_werr));
1091 if (_test_SecurityDescriptor(p, tctx, handle,
1092 sd_mask_tests[i].access_mask, key,
1093 sd_mask_tests[i].open_werr,
1094 sd_mask_tests[i].get_werr,
1095 sd_mask_tests[i].set_werr)) {
1103 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104 struct torture_context *,
1105 struct policy_handle *,
1107 const struct dom_sid *);
1109 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110 struct torture_context *tctx,
1111 struct policy_handle *handle,
1114 uint32_t access_mask,
1116 struct security_descriptor *sd,
1118 bool expect_present,
1119 bool (*fn) (struct dcerpc_pipe *,
1120 struct torture_context *,
1121 struct policy_handle *,
1123 const struct dom_sid *),
1124 const struct dom_sid *sid)
1126 struct policy_handle new_handle;
1127 struct dcerpc_binding_handle *b = p->binding_handle;
1129 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 "0x%08x, access_mask: 0x%08x\n",
1131 test, sec_info, access_mask);
1133 torture_assert(tctx,
1134 test_OpenKey_opts(tctx, b, handle, key,
1135 REG_OPTION_NON_VOLATILE,
1139 "failed to open key");
1141 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1144 torture_warning(tctx,
1145 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1148 test_CloseKey(b, tctx, &new_handle);
1152 test_CloseKey(b, tctx, &new_handle);
1154 if (W_ERROR_IS_OK(set_werr)) {
1156 present = fn(p, tctx, handle, key, sid);
1157 if ((expect_present) && (!present)) {
1158 torture_warning(tctx,
1159 "%s sid is not present!\n",
1163 if ((!expect_present) && (present)) {
1164 torture_warning(tctx,
1165 "%s sid is present but not expected!\n",
1174 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 struct torture_context *tctx,
1176 struct policy_handle *handle,
1179 struct security_descriptor *sd_orig = NULL;
1180 struct dom_sid *sid = NULL;
1184 struct security_descriptor *sd_owner =
1185 security_descriptor_dacl_create(tctx,
1187 TEST_SID, NULL, NULL);
1189 struct security_descriptor *sd_group =
1190 security_descriptor_dacl_create(tctx,
1192 NULL, TEST_SID, NULL);
1194 struct security_descriptor *sd_dacl =
1195 security_descriptor_dacl_create(tctx,
1199 SEC_ACE_TYPE_ACCESS_ALLOWED,
1202 SID_NT_AUTHENTICATED_USERS,
1203 SEC_ACE_TYPE_ACCESS_ALLOWED,
1208 struct security_descriptor *sd_sacl =
1209 security_descriptor_sacl_create(tctx,
1213 SEC_ACE_TYPE_SYSTEM_AUDIT,
1215 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1218 struct winreg_secinfo_table {
1219 struct security_descriptor *sd;
1223 secinfo_verify_fn fn;
1226 struct winreg_secinfo_table sec_info_owner_tests[] = {
1227 { sd_owner, 0, WERR_OK,
1228 false, (secinfo_verify_fn)_test_owner_present },
1229 { sd_owner, SECINFO_OWNER, WERR_OK,
1230 true, (secinfo_verify_fn)_test_owner_present },
1231 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1232 { sd_owner, SECINFO_DACL, WERR_OK,
1233 true, (secinfo_verify_fn)_test_owner_present },
1234 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1237 uint32_t sd_owner_good_access_masks[] = {
1238 SEC_FLAG_MAXIMUM_ALLOWED,
1239 /* SEC_STD_WRITE_OWNER, */
1242 struct winreg_secinfo_table sec_info_group_tests[] = {
1243 { sd_group, 0, WERR_OK,
1244 false, (secinfo_verify_fn)_test_group_present },
1245 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1246 { sd_group, SECINFO_GROUP, WERR_OK,
1247 true, (secinfo_verify_fn)_test_group_present },
1248 { sd_group, SECINFO_DACL, WERR_OK,
1249 true, (secinfo_verify_fn)_test_group_present },
1250 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1253 uint32_t sd_group_good_access_masks[] = {
1254 SEC_FLAG_MAXIMUM_ALLOWED,
1257 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1258 { sd_dacl, 0, WERR_OK,
1259 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1260 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1261 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1262 { sd_dacl, SECINFO_DACL, WERR_OK,
1263 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1264 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1267 uint32_t sd_dacl_good_access_masks[] = {
1268 SEC_FLAG_MAXIMUM_ALLOWED,
1272 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1273 { sd_sacl, 0, WERR_OK,
1274 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1275 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1276 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1277 { sd_sacl, SECINFO_DACL, WERR_OK,
1278 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1279 { sd_sacl, SECINFO_SACL, WERR_OK,
1280 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1283 uint32_t sd_sacl_good_access_masks[] = {
1284 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1285 /* SEC_FLAG_SYSTEM_SECURITY, */
1288 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1293 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1299 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1301 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1303 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1306 sd_owner_good_access_masks[a],
1307 sec_info_owner_tests[i].sec_info,
1308 sec_info_owner_tests[i].sd,
1309 sec_info_owner_tests[i].set_werr,
1310 sec_info_owner_tests[i].sid_present,
1311 sec_info_owner_tests[i].fn,
1314 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1323 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1325 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1327 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1330 sd_group_good_access_masks[a],
1331 sec_info_group_tests[i].sec_info,
1332 sec_info_group_tests[i].sd,
1333 sec_info_group_tests[i].set_werr,
1334 sec_info_group_tests[i].sid_present,
1335 sec_info_group_tests[i].fn,
1338 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1347 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1349 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1351 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1354 sd_dacl_good_access_masks[a],
1355 sec_info_dacl_tests[i].sec_info,
1356 sec_info_dacl_tests[i].sd,
1357 sec_info_dacl_tests[i].set_werr,
1358 sec_info_dacl_tests[i].sid_present,
1359 sec_info_dacl_tests[i].fn,
1362 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1371 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1373 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1375 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1378 sd_sacl_good_access_masks[a],
1379 sec_info_sacl_tests[i].sec_info,
1380 sec_info_sacl_tests[i].sd,
1381 sec_info_sacl_tests[i].set_werr,
1382 sec_info_sacl_tests[i].sid_present,
1383 sec_info_sacl_tests[i].fn,
1386 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1394 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1399 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1400 struct torture_context *tctx,
1401 struct policy_handle *handle,
1406 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1407 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1411 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1412 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1416 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1417 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1421 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1422 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1426 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1427 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1434 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1435 struct torture_context *tctx,
1436 struct policy_handle *handle,
1438 WERROR expected_result)
1440 struct winreg_DeleteKey r;
1442 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1444 r.in.handle = handle;
1445 init_winreg_String(&r.in.key, key);
1447 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1448 "Delete Key failed");
1449 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1450 "DeleteKey failed");
1455 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1456 struct torture_context *tctx,
1457 struct policy_handle *handle, const char *key)
1459 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1462 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1463 struct torture_context *tctx,
1464 struct policy_handle *handle, char *kclass)
1466 struct winreg_QueryInfoKey r;
1467 uint32_t num_subkeys, max_subkeylen, max_classlen,
1468 num_values, max_valnamelen, max_valbufsize,
1470 NTTIME last_changed_time;
1473 r.in.handle = handle;
1474 r.out.num_subkeys = &num_subkeys;
1475 r.out.max_subkeylen = &max_subkeylen;
1476 r.out.max_classlen = &max_classlen;
1477 r.out.num_values = &num_values;
1478 r.out.max_valnamelen = &max_valnamelen;
1479 r.out.max_valbufsize = &max_valbufsize;
1480 r.out.secdescsize = &secdescsize;
1481 r.out.last_changed_time = &last_changed_time;
1483 r.out.classname = talloc(tctx, struct winreg_String);
1485 r.in.classname = talloc(tctx, struct winreg_String);
1486 init_winreg_String(r.in.classname, kclass);
1488 torture_assert_ntstatus_ok(tctx,
1489 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1490 "QueryInfoKey failed");
1492 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1497 static bool test_SetValue(struct dcerpc_binding_handle *b,
1498 struct torture_context *tctx,
1499 struct policy_handle *handle,
1500 const char *value_name,
1501 enum winreg_Type type,
1505 struct winreg_SetValue r;
1506 struct winreg_String name;
1508 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1509 value_name, str_regtype(type), size);
1511 init_winreg_String(&name, value_name);
1513 r.in.handle = handle;
1519 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1520 "winreg_SetValue failed");
1521 torture_assert_werr_ok(tctx, r.out.result,
1522 "winreg_SetValue failed");
1527 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1528 struct torture_context *tctx,
1529 struct policy_handle *handle,
1530 const char *value_name)
1532 struct winreg_DeleteValue r;
1533 struct winreg_String value;
1535 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1537 init_winreg_String(&value, value_name);
1539 r.in.handle = handle;
1542 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1543 "winreg_DeleteValue failed");
1544 torture_assert_werr_ok(tctx, r.out.result,
1545 "winreg_DeleteValue failed");
1550 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1551 struct policy_handle *handle, int depth,
1552 bool test_security);
1554 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1555 struct policy_handle *handle, int depth,
1558 struct winreg_EnumKey r;
1559 struct winreg_StringBuf kclass, name;
1562 struct dcerpc_binding_handle *b = p->binding_handle;
1568 r.in.handle = handle;
1569 r.in.enum_index = 0;
1571 r.in.keyclass = &kclass;
1573 r.in.last_changed_time = &t;
1579 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1581 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1582 struct policy_handle key_handle;
1584 torture_comment(tctx, "EnumKey: %d: %s\n",
1588 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1591 test_key(p, tctx, &key_handle,
1592 depth + 1, test_security);
1598 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1600 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1602 if (!W_ERROR_IS_OK(r.out.result) &&
1603 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1604 torture_fail(tctx, "EnumKey failed");
1610 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1611 struct torture_context *tctx,
1612 struct policy_handle *handle,
1613 const char *valuename)
1615 struct winreg_QueryMultipleValues r;
1620 r.in.key_handle = handle;
1621 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1622 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1623 r.in.values_in[0].ve_valuename->name = valuename;
1624 /* size needs to be set manually for winreg_ValNameBuf */
1625 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1627 r.in.num_values = 1;
1628 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1629 *r.in.buffer_size = bufsize;
1631 *r.in.buffer_size = bufsize;
1632 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1635 torture_assert_ntstatus_ok(tctx,
1636 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1637 "QueryMultipleValues failed");
1639 talloc_free(r.in.buffer);
1641 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1643 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1648 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1649 struct torture_context *tctx,
1650 struct policy_handle *handle,
1651 uint32_t num_values,
1652 const char **valuenames,
1653 bool existing_value)
1655 struct winreg_QueryMultipleValues r;
1656 uint32_t bufsize = 0;
1659 torture_comment(tctx, "Testing QueryMultipleValues\n");
1663 r.in.key_handle = handle;
1664 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1665 r.in.buffer_size = r.out.buffer_size = &bufsize;
1667 torture_assert_ntstatus_ok(tctx,
1668 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1669 "QueryMultipleValues failed");
1670 torture_assert_werr_ok(tctx, r.out.result,
1671 "QueryMultipleValues failed");
1673 /* this test crashes w2k8 remote registry */
1675 r.in.num_values = num_values;
1676 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1678 torture_assert_ntstatus_ok(tctx,
1679 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1680 "QueryMultipleValues failed");
1681 torture_assert_werr_ok(tctx, r.out.result,
1682 "QueryMultipleValues failed");
1684 r.in.num_values = num_values;
1685 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1686 for (i=0; i < r.in.num_values; i++) {
1687 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1688 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1689 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1692 torture_assert_ntstatus_ok(tctx,
1693 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1694 "QueryMultipleValues failed");
1695 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1696 "QueryMultipleValues failed");
1698 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1702 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1703 *r.in.buffer_size = 0xff;
1704 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1706 torture_assert_ntstatus_ok(tctx,
1707 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1708 "QueryMultipleValues failed");
1711 torture_assert_werr_ok(tctx, r.out.result,
1712 "QueryMultipleValues failed");
1718 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1719 struct torture_context *tctx,
1720 struct policy_handle *handle,
1721 uint32_t num_values,
1722 const char **valuenames,
1723 bool existing_value)
1725 struct winreg_QueryMultipleValues2 r;
1726 uint32_t offered = 0, needed;
1729 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1733 r.in.key_handle = handle;
1734 r.in.offered = &offered;
1735 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1736 r.out.needed = &needed;
1738 torture_assert_ntstatus_ok(tctx,
1739 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1740 "QueryMultipleValues2 failed");
1741 torture_assert_werr_ok(tctx, r.out.result,
1742 "QueryMultipleValues2 failed");
1744 /* this test crashes w2k8 remote registry */
1746 r.in.num_values = num_values;
1747 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1749 torture_assert_ntstatus_ok(tctx,
1750 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1751 "QueryMultipleValues2 failed");
1752 torture_assert_werr_ok(tctx, r.out.result,
1753 "QueryMultipleValues2 failed");
1755 r.in.num_values = num_values;
1756 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1757 for (i=0; i < r.in.num_values; i++) {
1758 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1759 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1760 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1763 torture_assert_ntstatus_ok(tctx,
1764 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1765 "QueryMultipleValues2 failed");
1766 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1767 "QueryMultipleValues2 failed");
1769 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1773 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1774 *r.in.offered = *r.out.needed;
1775 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1777 torture_assert_ntstatus_ok(tctx,
1778 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1779 "QueryMultipleValues2 failed");
1782 torture_assert_werr_ok(tctx, r.out.result,
1783 "QueryMultipleValues2 failed");
1788 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1789 struct torture_context *tctx,
1790 struct policy_handle *handle,
1791 const char *valuename)
1793 struct winreg_QueryMultipleValues2 r;
1794 uint32_t offered = 0, needed;
1798 r.in.key_handle = handle;
1799 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1800 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1801 r.in.values_in[0].ve_valuename->name = valuename;
1802 /* size needs to be set manually for winreg_ValNameBuf */
1803 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1805 r.in.num_values = 1;
1806 r.in.offered = &offered;
1807 r.out.needed = &needed;
1809 torture_assert_ntstatus_ok(tctx,
1810 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1811 "QueryMultipleValues2 failed");
1812 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1813 *r.in.offered = *r.out.needed;
1814 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1816 torture_assert_ntstatus_ok(tctx,
1817 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1818 "QueryMultipleValues2 failed");
1821 torture_assert_werr_ok(tctx, r.out.result,
1822 "QueryMultipleValues2 failed");
1827 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1828 struct torture_context *tctx,
1829 struct policy_handle *handle,
1830 const char *valuename)
1832 struct winreg_QueryValue r;
1834 enum winreg_Type zero_type = 0;
1835 uint32_t offered = 0xfff;
1839 r.in.handle = handle;
1841 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1842 r.in.value_name->name = valuename;
1843 r.in.type = &zero_type;
1844 r.in.data_size = &offered;
1845 r.in.data_length = &zero;
1847 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1848 if (NT_STATUS_IS_ERR(status)) {
1849 torture_fail(tctx, "QueryValue failed");
1852 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1857 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1858 struct torture_context *tctx,
1859 struct policy_handle *handle,
1860 const char *valuename,
1861 bool existing_value)
1863 struct winreg_QueryValue r;
1864 struct winreg_String value_name;
1865 enum winreg_Type type = REG_NONE;
1866 uint32_t data_size = 0;
1867 uint32_t real_data_size = 0;
1868 uint32_t data_length = 0;
1869 uint8_t *data = NULL;
1870 WERROR expected_error = WERR_BADFILE;
1871 const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1873 if (valuename == NULL) {
1874 expected_error = WERR_INVALID_PARAM;
1875 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1880 init_winreg_String(&value_name, NULL);
1882 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1884 r.in.handle = handle;
1885 r.in.value_name = &value_name;
1887 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1888 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1889 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1891 init_winreg_String(&value_name, valuename);
1892 r.in.value_name = &value_name;
1894 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1895 "QueryValue failed");
1896 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1897 "expected WERR_INVALID_PARAM for missing type length and size");
1901 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1902 "QueryValue failed");
1903 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1904 "expected WERR_INVALID_PARAM for missing length and size");
1906 r.in.data_length = &data_length;
1907 r.out.data_length = &data_length;
1908 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1909 "QueryValue failed");
1910 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1911 "expected WERR_INVALID_PARAM for missing size");
1913 r.in.data_size = &data_size;
1914 r.out.data_size = &data_size;
1915 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1916 "QueryValue failed");
1917 if (existing_value) {
1918 torture_assert_werr_ok(tctx, r.out.result,
1919 "QueryValue failed");
1921 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1922 errmsg_nonexisting);
1925 real_data_size = *r.out.data_size;
1927 data = talloc_zero_array(tctx, uint8_t, 0);
1930 *r.in.data_size = 0;
1931 *r.out.data_size = 0;
1932 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1933 "QueryValue failed");
1934 if (existing_value) {
1935 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1936 "expected WERR_MORE_DATA for query with too small buffer");
1938 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1939 errmsg_nonexisting);
1942 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1945 r.in.data_size = &real_data_size;
1946 r.out.data_size = &real_data_size;
1947 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1948 "QueryValue failed");
1949 if (existing_value) {
1950 torture_assert_werr_ok(tctx, r.out.result,
1951 "QueryValue failed");
1953 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1954 errmsg_nonexisting);
1960 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1961 struct torture_context *tctx,
1962 struct policy_handle *handle, int max_valnamelen,
1965 struct winreg_EnumValue r;
1966 enum winreg_Type type = 0;
1967 uint32_t size = max_valbufsize, zero = 0;
1970 struct winreg_ValNameBuf name;
1976 r.in.handle = handle;
1977 r.in.enum_index = 0;
1982 r.in.length = &zero;
1986 torture_assert_ntstatus_ok(tctx,
1987 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1988 "EnumValue failed");
1990 if (W_ERROR_IS_OK(r.out.result)) {
1991 ret &= test_QueryValue(b, tctx, handle,
1993 ret &= test_QueryMultipleValues(b, tctx, handle,
1995 ret &= test_QueryMultipleValues2(b, tctx, handle,
2000 } while (W_ERROR_IS_OK(r.out.result));
2002 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2003 "EnumValue failed");
2008 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2009 struct torture_context *tctx)
2011 struct winreg_AbortSystemShutdown r;
2012 uint16_t server = 0x0;
2015 r.in.server = &server;
2017 torture_assert_ntstatus_ok(tctx,
2018 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2019 "AbortSystemShutdown failed");
2021 torture_assert_werr_ok(tctx, r.out.result,
2022 "AbortSystemShutdown failed");
2027 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2028 struct dcerpc_pipe *p)
2030 struct winreg_InitiateSystemShutdown r;
2031 uint16_t hostname = 0x0;
2032 struct dcerpc_binding_handle *b = p->binding_handle;
2035 r.in.hostname = &hostname;
2036 r.in.message = talloc(tctx, struct lsa_StringLarge);
2037 init_lsa_StringLarge(r.in.message, "spottyfood");
2038 r.in.force_apps = 1;
2042 torture_assert_ntstatus_ok(tctx,
2043 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2044 "InitiateSystemShutdown failed");
2046 torture_assert_werr_ok(tctx, r.out.result,
2047 "InitiateSystemShutdown failed");
2049 return test_AbortSystemShutdown(b, tctx);
2053 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2054 struct dcerpc_pipe *p)
2056 struct winreg_InitiateSystemShutdownEx r;
2057 uint16_t hostname = 0x0;
2058 struct dcerpc_binding_handle *b = p->binding_handle;
2061 r.in.hostname = &hostname;
2062 r.in.message = talloc(tctx, struct lsa_StringLarge);
2063 init_lsa_StringLarge(r.in.message, "spottyfood");
2064 r.in.force_apps = 1;
2069 torture_assert_ntstatus_ok(tctx,
2070 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2071 "InitiateSystemShutdownEx failed");
2073 torture_assert_werr_ok(tctx, r.out.result,
2074 "InitiateSystemShutdownEx failed");
2076 return test_AbortSystemShutdown(b, tctx);
2078 #define MAX_DEPTH 2 /* Only go this far down the tree */
2080 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2081 struct policy_handle *handle, int depth,
2084 struct dcerpc_binding_handle *b = p->binding_handle;
2086 if (depth == MAX_DEPTH)
2089 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
2092 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2095 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2098 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2101 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
2104 test_CloseKey(b, tctx, handle);
2109 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2110 struct torture_context *tctx,
2111 struct policy_handle *handle)
2113 const char *value_name = TEST_VALUE;
2114 uint32_t value = 0x12345678;
2115 uint64_t value2 = 0x12345678;
2116 const char *string = "torture";
2117 const char *array[2];
2119 enum winreg_Type types[] = {
2121 REG_DWORD_BIG_ENDIAN,
2129 array[0] = "array0";
2132 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2134 for (t=0; t < ARRAY_SIZE(types); t++) {
2136 enum winreg_Type w_type;
2137 uint32_t w_size, w_length;
2142 case REG_DWORD_BIG_ENDIAN:
2143 blob = data_blob_talloc_zero(tctx, 4);
2144 SIVAL(blob.data, 0, value);
2147 blob = data_blob_talloc_zero(tctx, 8);
2148 SBVAL(blob.data, 0, value2);
2151 blob = data_blob_string_const("binary_blob");
2154 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2157 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2163 torture_assert(tctx,
2164 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2165 "test_SetValue failed");
2166 torture_assert(tctx,
2167 test_QueryValue_full(b, tctx, handle, value_name, true),
2168 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2169 torture_assert(tctx,
2170 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2171 "test_winreg_QueryValue failed");
2172 torture_assert(tctx,
2173 test_DeleteValue(b, tctx, handle, value_name),
2174 "test_DeleteValue failed");
2176 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2177 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2178 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2179 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2182 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2187 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2188 struct torture_context *tctx,
2189 struct policy_handle *handle)
2192 const char *values[] = {
2199 "torture_value_name",
2200 "torture value name",
2201 "torture,value,name",
2202 "torture;value;name",
2203 "torture/value/name",
2204 "torture\\value\\name",
2208 torture_comment(tctx, "Testing SetValue (values)\n");
2210 for (i=0; i < ARRAY_SIZE(values); i++) {
2212 enum winreg_Type w_type;
2213 uint32_t w_size, w_length;
2216 blob = data_blob_talloc(tctx, NULL, 32);
2218 generate_random_buffer(blob.data, 32);
2220 torture_assert(tctx,
2221 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2222 "test_SetValue failed");
2223 torture_assert(tctx,
2224 test_QueryValue_full(b, tctx, handle, values[i], true),
2225 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2226 torture_assert(tctx,
2227 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2228 "test_winreg_QueryValue failed");
2229 torture_assert(tctx,
2230 test_DeleteValue(b, tctx, handle, values[i]),
2231 "test_DeleteValue failed");
2233 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2234 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2235 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2236 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2239 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2244 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2246 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2247 struct torture_context *tctx,
2248 struct policy_handle *handle)
2250 const char *value_name = TEST_VALUE;
2251 enum winreg_Type types[] = {
2257 REG_DWORD_BIG_ENDIAN,
2261 REG_FULL_RESOURCE_DESCRIPTOR,
2262 REG_RESOURCE_REQUIREMENTS_LIST,
2274 if (torture_setting_bool(tctx, "samba4", false)) {
2275 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2278 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2280 for (t=0; t < ARRAY_SIZE(types); t++) {
2281 for (l=0; l < 16; l++) {
2283 enum winreg_Type w_type;
2284 uint32_t w_size, w_length;
2291 data = talloc_array(tctx, uint8_t, size);
2293 generate_random_buffer(data, size);
2295 torture_assert(tctx,
2296 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2297 "test_SetValue failed");
2299 torture_assert(tctx,
2300 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2301 "test_winreg_QueryValue failed");
2303 torture_assert(tctx,
2304 test_DeleteValue(b, tctx, handle, value_name),
2305 "test_DeleteValue failed");
2307 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2308 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2309 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2310 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2314 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2319 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2320 struct torture_context *tctx,
2321 struct policy_handle *handle)
2323 const char *keys[] = {
2332 for (i=0; i < ARRAY_SIZE(keys); i++) {
2334 enum winreg_CreateAction action_taken;
2335 struct policy_handle new_handle;
2338 torture_assert(tctx,
2339 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2340 REG_OPTION_NON_VOLATILE,
2341 SEC_FLAG_MAXIMUM_ALLOWED,
2346 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2348 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2350 torture_assert(tctx,
2351 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2352 "failed to delete key");
2354 torture_assert(tctx,
2355 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2356 "failed 2nd delete key");
2358 tmp = talloc_strdup(tctx, keys[i]);
2360 q = strchr(tmp, '\\');
2365 torture_assert(tctx,
2366 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2367 "failed to delete key");
2369 torture_assert(tctx,
2370 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2371 "failed 2nd delete key");
2378 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2379 #define VALUE_CURRENT_VERSION "CurrentVersion"
2380 #define VALUE_SYSTEM_ROOT "SystemRoot"
2382 static bool test_HKLM_wellknown(struct torture_context *tctx,
2383 struct dcerpc_binding_handle *b,
2384 struct policy_handle *handle)
2386 struct policy_handle newhandle;
2389 const char *values[3];
2390 uint32_t num_values;
2391 bool existing_value;
2392 const char *error_message;
2393 } multiple_values_tests[] = {
2395 .values[0] = VALUE_CURRENT_VERSION,
2399 .existing_value = true
2401 .values[0] = VALUE_SYSTEM_ROOT,
2405 .existing_value = true
2407 .values[0] = VALUE_CURRENT_VERSION,
2408 .values[1] = VALUE_SYSTEM_ROOT,
2411 .existing_value = true
2413 .values[0] = VALUE_CURRENT_VERSION,
2414 .values[1] = VALUE_SYSTEM_ROOT,
2415 .values[2] = VALUE_CURRENT_VERSION,
2417 .existing_value = true
2419 .values[0] = VALUE_CURRENT_VERSION,
2421 .values[2] = VALUE_SYSTEM_ROOT,
2423 .existing_value = false
2425 .values[0] = VALUE_CURRENT_VERSION,
2427 .values[2] = VALUE_SYSTEM_ROOT,
2429 .existing_value = false
2431 .values[0] = "IDoNotExist",
2435 .existing_value = false
2437 .values[0] = "IDoNotExist",
2438 .values[1] = VALUE_CURRENT_VERSION,
2441 .existing_value = false
2443 .values[0] = VALUE_CURRENT_VERSION,
2444 .values[1] = "IDoNotExist",
2447 .existing_value = false
2451 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2452 if (torture_setting_bool(tctx, "samba3", false)) {
2453 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2454 KEY_CURRENT_VERSION,
2455 REG_OPTION_NON_VOLATILE,
2459 "failed to open current version key");
2461 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2462 "failed to open current version key");
2465 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2466 "failed to query current version");
2467 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2468 "succeeded to query nonexistent value");
2469 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2470 "succeeded to query value with NULL name");
2471 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2472 "succeeded to query nonexistent default value (\"\")");
2474 if (torture_setting_bool(tctx, "samba4", false)) {
2475 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2479 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2481 msg = talloc_asprintf(tctx,
2482 "failed to query %d %sexisting values\n",
2483 multiple_values_tests[i].num_values,
2484 multiple_values_tests[i].existing_value ? "":"non");
2486 torture_assert(tctx,
2487 test_QueryMultipleValues_full(b, tctx, &newhandle,
2488 multiple_values_tests[i].num_values,
2489 multiple_values_tests[i].values,
2490 multiple_values_tests[i].existing_value),
2492 torture_assert(tctx,
2493 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2494 multiple_values_tests[i].num_values,
2495 multiple_values_tests[i].values,
2496 multiple_values_tests[i].existing_value),
2501 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2502 "failed to close current version key");
2507 static bool test_OpenHive(struct torture_context *tctx,
2508 struct dcerpc_binding_handle *b,
2509 struct policy_handle *handle,
2512 struct winreg_OpenHKLM r;
2514 r.in.system_name = 0;
2515 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2516 r.out.handle = handle;
2519 case HKEY_LOCAL_MACHINE:
2520 torture_assert_ntstatus_ok(tctx,
2521 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2522 "failed to open HKLM");
2523 torture_assert_werr_ok(tctx, r.out.result,
2524 "failed to open HKLM");
2526 case HKEY_CURRENT_USER:
2527 torture_assert_ntstatus_ok(tctx,
2528 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)&r),
2529 "failed to open HKCU");
2530 torture_assert_werr_ok(tctx, r.out.result,
2531 "failed to open HKCU");
2534 torture_assert_ntstatus_ok(tctx,
2535 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)&r),
2536 "failed to open HKU");
2537 torture_assert_werr_ok(tctx, r.out.result,
2538 "failed to open HKU");
2540 case HKEY_CLASSES_ROOT:
2541 torture_assert_ntstatus_ok(tctx,
2542 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)&r),
2543 "failed to open HKCR");
2544 torture_assert_werr_ok(tctx, r.out.result,
2545 "failed to open HKCR");
2548 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2555 static bool test_volatile_keys(struct torture_context *tctx,
2556 struct dcerpc_binding_handle *b,
2557 struct policy_handle *handle,
2560 struct policy_handle new_handle;
2561 enum winreg_CreateAction action_taken;
2563 torture_comment(tctx, "Testing VOLATILE key\n");
2565 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2567 torture_assert(tctx,
2568 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2569 REG_OPTION_VOLATILE,
2570 SEC_FLAG_MAXIMUM_ALLOWED,
2575 "failed to create REG_OPTION_VOLATILE type key");
2577 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2579 torture_assert(tctx,
2580 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2581 REG_OPTION_NON_VOLATILE,
2582 SEC_FLAG_MAXIMUM_ALLOWED,
2584 WERR_CHILD_MUST_BE_VOLATILE,
2587 "failed to fail create REG_OPTION_VOLATILE type key");
2589 torture_assert(tctx,
2590 test_CloseKey(b, tctx, &new_handle),
2593 torture_assert(tctx,
2594 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2595 REG_OPTION_NON_VOLATILE,
2596 SEC_FLAG_MAXIMUM_ALLOWED,
2599 "failed to open volatile key");
2601 torture_assert(tctx,
2602 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2603 "failed to delete key");
2605 torture_assert(tctx,
2606 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2607 REG_OPTION_VOLATILE,
2608 SEC_FLAG_MAXIMUM_ALLOWED,
2613 "failed to create REG_OPTION_VOLATILE type key");
2615 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2617 torture_assert(tctx,
2618 test_CloseKey(b, tctx, &new_handle),
2621 torture_assert(tctx,
2622 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2623 REG_OPTION_VOLATILE,
2624 SEC_FLAG_MAXIMUM_ALLOWED,
2627 "failed to open volatile key");
2629 torture_assert(tctx,
2630 test_CloseKey(b, tctx, &new_handle),
2633 torture_assert(tctx,
2634 test_CloseKey(b, tctx, handle),
2637 torture_assert(tctx,
2638 test_OpenHive(tctx, b, handle, hkey),
2639 "failed top open hive");
2641 torture_assert(tctx,
2642 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2643 REG_OPTION_VOLATILE,
2644 SEC_FLAG_MAXIMUM_ALLOWED,
2647 "failed to open volatile key");
2649 torture_assert(tctx,
2650 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2651 REG_OPTION_NON_VOLATILE,
2652 SEC_FLAG_MAXIMUM_ALLOWED,
2655 "failed to open volatile key");
2657 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2662 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2664 const char *sid_string,
2668 case HKEY_LOCAL_MACHINE:
2669 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2670 case HKEY_CURRENT_USER:
2671 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2673 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2674 case HKEY_CLASSES_ROOT:
2675 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2677 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2684 static bool test_symlink_keys(struct torture_context *tctx,
2685 struct dcerpc_binding_handle *b,
2686 struct policy_handle *handle,
2690 struct policy_handle new_handle;
2691 enum winreg_CreateAction action_taken;
2693 uint32_t value = 42;
2694 const char *test_key_symlink_dest;
2695 const char *test_key_symlink;
2696 const char *kernel_mode_path;
2698 /* disable until we know how to delete a symbolic link */
2699 torture_skip(tctx, "symlink test disabled");
2701 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2703 /* create destination key with testvalue */
2704 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2705 key, TEST_KEY_SYMLINK);
2706 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2707 key, TEST_KEY_SYMLINK_DEST);
2709 test_DeleteKey(b, tctx, handle, test_key_symlink);
2711 torture_assert(tctx,
2712 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2714 SEC_FLAG_MAXIMUM_ALLOWED,
2719 "failed to create symlink destination");
2721 blob = data_blob_talloc_zero(tctx, 4);
2722 SIVAL(blob.data, 0, value);
2724 torture_assert(tctx,
2725 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2726 "failed to create TestValue");
2728 torture_assert(tctx,
2729 test_CloseKey(b, tctx, &new_handle),
2732 /* create symlink */
2734 torture_assert(tctx,
2735 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2736 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2737 SEC_FLAG_MAXIMUM_ALLOWED,
2742 "failed to create REG_OPTION_CREATE_LINK type key");
2744 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2746 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2748 torture_assert(tctx,
2749 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2751 strlen(kernel_mode_path), /* not NULL terminated */
2752 &blob.data, &blob.length,
2754 "failed to convert");
2756 torture_assert(tctx,
2757 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2758 "failed to create SymbolicLinkValue value");
2760 torture_assert(tctx,
2761 test_CloseKey(b, tctx, &new_handle),
2764 /* test follow symlink */
2766 torture_assert(tctx,
2767 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2769 SEC_FLAG_MAXIMUM_ALLOWED,
2772 "failed to follow symlink key");
2774 torture_assert(tctx,
2775 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2776 "failed to query value");
2778 torture_assert(tctx,
2779 test_CloseKey(b, tctx, &new_handle),
2784 torture_assert(tctx,
2785 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2786 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2787 SEC_FLAG_MAXIMUM_ALLOWED,
2790 "failed to open symlink key");
2792 torture_assert(tctx,
2793 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2794 "failed to delete value SymbolicLinkValue");
2796 torture_assert(tctx,
2797 test_CloseKey(b, tctx, &new_handle),
2800 torture_assert(tctx,
2801 test_DeleteKey(b, tctx, handle, test_key_symlink),
2802 "failed to delete key");
2804 /* delete destination */
2806 torture_assert(tctx,
2807 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2808 "failed to delete key");
2813 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2814 struct dcerpc_binding_handle *b,
2815 struct policy_handle *handle,
2820 if (torture_setting_bool(tctx, "samba3", false) ||
2821 torture_setting_bool(tctx, "samba4", false)) {
2822 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2825 torture_assert(tctx,
2826 test_volatile_keys(tctx, b, handle, hkey),
2827 "failed to test volatile keys");
2829 torture_assert(tctx,
2830 test_symlink_keys(tctx, b, handle, key, hkey),
2831 "failed to test symlink keys");
2836 static bool test_key_base(struct torture_context *tctx,
2837 struct dcerpc_binding_handle *b,
2838 struct policy_handle *handle,
2839 const char *base_key,
2842 struct policy_handle newhandle;
2843 bool ret = true, created = false, deleted = false;
2844 bool created3 = false;
2845 const char *test_key1;
2846 const char *test_key3;
2847 const char *test_subkey;
2849 test_Cleanup(b, tctx, handle, base_key);
2851 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2852 torture_comment(tctx,
2853 "CreateKey(%s) failed\n", base_key);
2856 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2858 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2859 torture_comment(tctx,
2860 "CreateKey failed - not considering a failure\n");
2866 if (!test_FlushKey(b, tctx, handle)) {
2867 torture_comment(tctx, "FlushKey failed\n");
2871 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2873 "CreateKey failed (OpenKey after Create didn't work)\n");
2876 if (hkey == HKEY_CURRENT_USER) {
2877 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2878 "simple SetValue test failed");
2879 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2880 "values SetValue test failed");
2881 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2882 "extended SetValue test failed");
2883 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2884 "keyname CreateKey test failed");
2886 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2887 "keytype test failed");
2890 if (!test_CloseKey(b, tctx, &newhandle)) {
2892 "CreateKey failed (CloseKey after Open didn't work)\n");
2895 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2896 torture_comment(tctx, "DeleteKey failed\n");
2902 if (!test_FlushKey(b, tctx, handle)) {
2903 torture_comment(tctx, "FlushKey failed\n");
2908 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2909 REG_OPTION_NON_VOLATILE,
2910 SEC_FLAG_MAXIMUM_ALLOWED,
2913 torture_comment(tctx,
2914 "DeleteKey failed (OpenKey after Delete "
2915 "did not return WERR_BADFILE)\n");
2920 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2922 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2926 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2929 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2930 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2931 torture_comment(tctx, "DeleteKey failed\n");
2936 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2937 torture_comment(tctx, "DeleteKey failed\n");
2943 test_Cleanup(b, tctx, handle, base_key);
2948 static bool test_key_base_sd(struct torture_context *tctx,
2949 struct dcerpc_pipe *p,
2950 struct policy_handle *handle,
2951 const char *base_key)
2953 struct policy_handle newhandle;
2954 bool ret = true, created2 = false, created4 = false;
2955 struct dcerpc_binding_handle *b = p->binding_handle;
2956 const char *test_key2;
2957 const char *test_key4;
2959 torture_skip(tctx, "security descriptor test disabled\n");
2961 if (torture_setting_bool(tctx, "samba3", false) ||
2962 torture_setting_bool(tctx, "samba4", false)) {
2963 torture_skip(tctx, "skipping security descriptor tests against Samba");
2966 test_Cleanup(b, tctx, handle, base_key);
2968 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2969 torture_comment(tctx,
2970 "CreateKey(%s) failed\n", base_key);
2973 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2975 if (test_CreateKey_sd(b, tctx, handle, test_key2,
2976 NULL, &newhandle)) {
2980 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2981 torture_comment(tctx, "CloseKey failed\n");
2985 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
2987 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
2991 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2992 torture_comment(tctx, "CloseKey failed\n");
2996 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3000 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3001 torture_comment(tctx, "DeleteKey failed\n");
3005 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3006 torture_comment(tctx, "DeleteKey failed\n");
3010 test_Cleanup(b, tctx, handle, base_key);
3015 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3018 struct policy_handle handle;
3020 struct winreg_OpenHKLM r;
3021 struct dcerpc_binding_handle *b = p->binding_handle;
3022 const char *torture_base_key;
3025 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3027 r.in.system_name = 0;
3028 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3029 r.out.handle = &handle;
3031 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3034 if (!test_GetVersion(b, tctx, &handle)) {
3035 torture_comment(tctx, "GetVersion failed\n");
3039 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3040 hkey = HKEY_LOCAL_MACHINE;
3041 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3042 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3044 torture_base_key = TEST_KEY_BASE;
3045 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3046 hkey = HKEY_CLASSES_ROOT;
3047 torture_base_key = TEST_KEY_BASE;
3048 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3049 hkey = HKEY_CURRENT_USER;
3050 torture_base_key = TEST_KEY_BASE;
3052 torture_fail(tctx, "unsupported hkey");
3055 if (hkey == HKEY_LOCAL_MACHINE) {
3056 torture_assert(tctx,
3057 test_HKLM_wellknown(tctx, b, &handle),
3058 "failed to test HKLM wellknown keys");
3061 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3062 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3067 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3068 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3073 /* The HKCR hive has a very large fanout */
3074 if (hkey == HKEY_CLASSES_ROOT) {
3075 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3078 } else if (hkey == HKEY_LOCAL_MACHINE) {
3079 /* FIXME we are not allowed to enum values in the HKLM root */
3081 if (!test_key(p, tctx, &handle, 0, false)) {
3089 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3091 struct torture_rpc_tcase *tcase;
3092 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3093 struct torture_test *test;
3095 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3098 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3099 test_InitiateSystemShutdown);
3100 test->dangerous = true;
3102 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3103 test_InitiateSystemShutdownEx);
3104 test->dangerous = true;
3106 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3108 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
3109 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3111 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
3112 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3114 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
3115 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3117 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);