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, "samba3", false) ||
2275 torture_setting_bool(tctx, "samba4", false)) {
2276 torture_skip(tctx, "skipping extended SetValue test against Samba");
2279 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2281 for (t=0; t < ARRAY_SIZE(types); t++) {
2282 for (l=0; l < 32; l++) {
2284 enum winreg_Type w_type;
2285 uint32_t w_size, w_length;
2292 data = talloc_array(tctx, uint8_t, size);
2294 generate_random_buffer(data, size);
2296 torture_assert(tctx,
2297 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2298 "test_SetValue failed");
2300 torture_assert(tctx,
2301 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2302 "test_winreg_QueryValue failed");
2304 torture_assert(tctx,
2305 test_DeleteValue(b, tctx, handle, value_name),
2306 "test_DeleteValue failed");
2308 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2309 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2310 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2311 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2315 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2320 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2321 struct torture_context *tctx,
2322 struct policy_handle *handle)
2324 const char *keys[] = {
2333 for (i=0; i < ARRAY_SIZE(keys); i++) {
2335 enum winreg_CreateAction action_taken;
2336 struct policy_handle new_handle;
2339 torture_assert(tctx,
2340 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2341 REG_OPTION_NON_VOLATILE,
2342 SEC_FLAG_MAXIMUM_ALLOWED,
2347 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2349 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2351 torture_assert(tctx,
2352 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2353 "failed to delete key");
2355 torture_assert(tctx,
2356 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2357 "failed 2nd delete key");
2359 tmp = talloc_strdup(tctx, keys[i]);
2361 q = strchr(tmp, '\\');
2366 torture_assert(tctx,
2367 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2368 "failed to delete key");
2370 torture_assert(tctx,
2371 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2372 "failed 2nd delete key");
2379 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2380 #define VALUE_CURRENT_VERSION "CurrentVersion"
2381 #define VALUE_SYSTEM_ROOT "SystemRoot"
2383 static bool test_HKLM_wellknown(struct torture_context *tctx,
2384 struct dcerpc_binding_handle *b,
2385 struct policy_handle *handle)
2387 struct policy_handle newhandle;
2390 const char *values[3];
2391 uint32_t num_values;
2392 bool existing_value;
2393 const char *error_message;
2394 } multiple_values_tests[] = {
2396 .values[0] = VALUE_CURRENT_VERSION,
2400 .existing_value = true
2402 .values[0] = VALUE_SYSTEM_ROOT,
2406 .existing_value = true
2408 .values[0] = VALUE_CURRENT_VERSION,
2409 .values[1] = VALUE_SYSTEM_ROOT,
2412 .existing_value = true
2414 .values[0] = VALUE_CURRENT_VERSION,
2415 .values[1] = VALUE_SYSTEM_ROOT,
2416 .values[2] = VALUE_CURRENT_VERSION,
2418 .existing_value = true
2420 .values[0] = VALUE_CURRENT_VERSION,
2422 .values[2] = VALUE_SYSTEM_ROOT,
2424 .existing_value = false
2426 .values[0] = VALUE_CURRENT_VERSION,
2428 .values[2] = VALUE_SYSTEM_ROOT,
2430 .existing_value = false
2432 .values[0] = "IDoNotExist",
2436 .existing_value = false
2438 .values[0] = "IDoNotExist",
2439 .values[1] = VALUE_CURRENT_VERSION,
2442 .existing_value = false
2444 .values[0] = VALUE_CURRENT_VERSION,
2445 .values[1] = "IDoNotExist",
2448 .existing_value = false
2452 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2453 if (torture_setting_bool(tctx, "samba3", false)) {
2454 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2455 KEY_CURRENT_VERSION,
2456 REG_OPTION_NON_VOLATILE,
2460 "failed to open current version key");
2462 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2463 "failed to open current version key");
2466 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2467 "failed to query current version");
2468 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2469 "succeeded to query nonexistent value");
2470 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2471 "succeeded to query value with NULL name");
2472 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2473 "succeeded to query nonexistent default value (\"\")");
2475 if (torture_setting_bool(tctx, "samba4", false)) {
2476 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2480 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2482 msg = talloc_asprintf(tctx,
2483 "failed to query %d %sexisting values\n",
2484 multiple_values_tests[i].num_values,
2485 multiple_values_tests[i].existing_value ? "":"non");
2487 torture_assert(tctx,
2488 test_QueryMultipleValues_full(b, tctx, &newhandle,
2489 multiple_values_tests[i].num_values,
2490 multiple_values_tests[i].values,
2491 multiple_values_tests[i].existing_value),
2493 torture_assert(tctx,
2494 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2495 multiple_values_tests[i].num_values,
2496 multiple_values_tests[i].values,
2497 multiple_values_tests[i].existing_value),
2502 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2503 "failed to close current version key");
2508 static bool test_OpenHive(struct torture_context *tctx,
2509 struct dcerpc_binding_handle *b,
2510 struct policy_handle *handle,
2513 struct winreg_OpenHKLM r;
2515 r.in.system_name = 0;
2516 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2517 r.out.handle = handle;
2520 case HKEY_LOCAL_MACHINE:
2521 torture_assert_ntstatus_ok(tctx,
2522 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2523 "failed to open HKLM");
2524 torture_assert_werr_ok(tctx, r.out.result,
2525 "failed to open HKLM");
2527 case HKEY_CURRENT_USER:
2528 torture_assert_ntstatus_ok(tctx,
2529 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)&r),
2530 "failed to open HKCU");
2531 torture_assert_werr_ok(tctx, r.out.result,
2532 "failed to open HKCU");
2535 torture_assert_ntstatus_ok(tctx,
2536 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)&r),
2537 "failed to open HKU");
2538 torture_assert_werr_ok(tctx, r.out.result,
2539 "failed to open HKU");
2541 case HKEY_CLASSES_ROOT:
2542 torture_assert_ntstatus_ok(tctx,
2543 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)&r),
2544 "failed to open HKCR");
2545 torture_assert_werr_ok(tctx, r.out.result,
2546 "failed to open HKCR");
2549 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2556 static bool test_volatile_keys(struct torture_context *tctx,
2557 struct dcerpc_binding_handle *b,
2558 struct policy_handle *handle,
2561 struct policy_handle new_handle;
2562 enum winreg_CreateAction action_taken;
2564 torture_comment(tctx, "Testing VOLATILE key\n");
2566 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2568 torture_assert(tctx,
2569 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2570 REG_OPTION_VOLATILE,
2571 SEC_FLAG_MAXIMUM_ALLOWED,
2576 "failed to create REG_OPTION_VOLATILE type key");
2578 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2580 torture_assert(tctx,
2581 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2582 REG_OPTION_NON_VOLATILE,
2583 SEC_FLAG_MAXIMUM_ALLOWED,
2585 WERR_CHILD_MUST_BE_VOLATILE,
2588 "failed to fail create REG_OPTION_VOLATILE type key");
2590 torture_assert(tctx,
2591 test_CloseKey(b, tctx, &new_handle),
2594 torture_assert(tctx,
2595 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2596 REG_OPTION_NON_VOLATILE,
2597 SEC_FLAG_MAXIMUM_ALLOWED,
2600 "failed to open volatile key");
2602 torture_assert(tctx,
2603 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2604 "failed to delete key");
2606 torture_assert(tctx,
2607 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2608 REG_OPTION_VOLATILE,
2609 SEC_FLAG_MAXIMUM_ALLOWED,
2614 "failed to create REG_OPTION_VOLATILE type key");
2616 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2618 torture_assert(tctx,
2619 test_CloseKey(b, tctx, &new_handle),
2622 torture_assert(tctx,
2623 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2624 REG_OPTION_VOLATILE,
2625 SEC_FLAG_MAXIMUM_ALLOWED,
2628 "failed to open volatile key");
2630 torture_assert(tctx,
2631 test_CloseKey(b, tctx, &new_handle),
2634 torture_assert(tctx,
2635 test_CloseKey(b, tctx, handle),
2638 torture_assert(tctx,
2639 test_OpenHive(tctx, b, handle, hkey),
2640 "failed top open hive");
2642 torture_assert(tctx,
2643 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2644 REG_OPTION_VOLATILE,
2645 SEC_FLAG_MAXIMUM_ALLOWED,
2648 "failed to open volatile key");
2650 torture_assert(tctx,
2651 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2652 REG_OPTION_NON_VOLATILE,
2653 SEC_FLAG_MAXIMUM_ALLOWED,
2656 "failed to open volatile key");
2658 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2663 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2665 const char *sid_string,
2669 case HKEY_LOCAL_MACHINE:
2670 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2671 case HKEY_CURRENT_USER:
2672 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2674 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2675 case HKEY_CLASSES_ROOT:
2676 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2678 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2685 static bool test_symlink_keys(struct torture_context *tctx,
2686 struct dcerpc_binding_handle *b,
2687 struct policy_handle *handle,
2691 struct policy_handle new_handle;
2692 enum winreg_CreateAction action_taken;
2694 uint32_t value = 42;
2695 const char *test_key_symlink_dest;
2696 const char *test_key_symlink;
2697 const char *kernel_mode_path;
2699 /* disable until we know how to delete a symbolic link */
2700 torture_skip(tctx, "symlink test disabled");
2702 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2704 /* create destination key with testvalue */
2705 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2706 key, TEST_KEY_SYMLINK);
2707 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2708 key, TEST_KEY_SYMLINK_DEST);
2710 test_DeleteKey(b, tctx, handle, test_key_symlink);
2712 torture_assert(tctx,
2713 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2715 SEC_FLAG_MAXIMUM_ALLOWED,
2720 "failed to create symlink destination");
2722 blob = data_blob_talloc_zero(tctx, 4);
2723 SIVAL(blob.data, 0, value);
2725 torture_assert(tctx,
2726 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2727 "failed to create TestValue");
2729 torture_assert(tctx,
2730 test_CloseKey(b, tctx, &new_handle),
2733 /* create symlink */
2735 torture_assert(tctx,
2736 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2737 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2738 SEC_FLAG_MAXIMUM_ALLOWED,
2743 "failed to create REG_OPTION_CREATE_LINK type key");
2745 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2747 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2749 torture_assert(tctx,
2750 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2752 strlen(kernel_mode_path), /* not NULL terminated */
2753 &blob.data, &blob.length,
2755 "failed to convert");
2757 torture_assert(tctx,
2758 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2759 "failed to create SymbolicLinkValue value");
2761 torture_assert(tctx,
2762 test_CloseKey(b, tctx, &new_handle),
2765 /* test follow symlink */
2767 torture_assert(tctx,
2768 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2770 SEC_FLAG_MAXIMUM_ALLOWED,
2773 "failed to follow symlink key");
2775 torture_assert(tctx,
2776 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2777 "failed to query value");
2779 torture_assert(tctx,
2780 test_CloseKey(b, tctx, &new_handle),
2785 torture_assert(tctx,
2786 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2787 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2788 SEC_FLAG_MAXIMUM_ALLOWED,
2791 "failed to open symlink key");
2793 torture_assert(tctx,
2794 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2795 "failed to delete value SymbolicLinkValue");
2797 torture_assert(tctx,
2798 test_CloseKey(b, tctx, &new_handle),
2801 torture_assert(tctx,
2802 test_DeleteKey(b, tctx, handle, test_key_symlink),
2803 "failed to delete key");
2805 /* delete destination */
2807 torture_assert(tctx,
2808 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2809 "failed to delete key");
2814 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2815 struct dcerpc_binding_handle *b,
2816 struct policy_handle *handle,
2821 if (torture_setting_bool(tctx, "samba3", false) ||
2822 torture_setting_bool(tctx, "samba4", false)) {
2823 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2826 torture_assert(tctx,
2827 test_volatile_keys(tctx, b, handle, hkey),
2828 "failed to test volatile keys");
2830 torture_assert(tctx,
2831 test_symlink_keys(tctx, b, handle, key, hkey),
2832 "failed to test symlink keys");
2837 static bool test_key_base(struct torture_context *tctx,
2838 struct dcerpc_binding_handle *b,
2839 struct policy_handle *handle,
2840 const char *base_key,
2843 struct policy_handle newhandle;
2844 bool ret = true, created = false, deleted = false;
2845 bool created3 = false;
2846 const char *test_key1;
2847 const char *test_key3;
2848 const char *test_subkey;
2850 test_Cleanup(b, tctx, handle, base_key);
2852 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2853 torture_comment(tctx,
2854 "CreateKey(%s) failed\n", base_key);
2857 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2859 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2860 torture_comment(tctx,
2861 "CreateKey failed - not considering a failure\n");
2867 if (!test_FlushKey(b, tctx, handle)) {
2868 torture_comment(tctx, "FlushKey failed\n");
2872 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2874 "CreateKey failed (OpenKey after Create didn't work)\n");
2877 if (hkey == HKEY_CURRENT_USER) {
2878 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2879 "simple SetValue test failed");
2880 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2881 "values SetValue test failed");
2882 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2883 "extended SetValue test failed");
2884 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2885 "keyname CreateKey test failed");
2887 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2888 "keytype test failed");
2891 if (!test_CloseKey(b, tctx, &newhandle)) {
2893 "CreateKey failed (CloseKey after Open didn't work)\n");
2896 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2897 torture_comment(tctx, "DeleteKey failed\n");
2903 if (!test_FlushKey(b, tctx, handle)) {
2904 torture_comment(tctx, "FlushKey failed\n");
2909 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2910 REG_OPTION_NON_VOLATILE,
2911 SEC_FLAG_MAXIMUM_ALLOWED,
2914 torture_comment(tctx,
2915 "DeleteKey failed (OpenKey after Delete "
2916 "did not return WERR_BADFILE)\n");
2921 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2923 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2927 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2930 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2931 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2932 torture_comment(tctx, "DeleteKey failed\n");
2937 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2938 torture_comment(tctx, "DeleteKey failed\n");
2944 test_Cleanup(b, tctx, handle, base_key);
2949 static bool test_key_base_sd(struct torture_context *tctx,
2950 struct dcerpc_pipe *p,
2951 struct policy_handle *handle,
2952 const char *base_key)
2954 struct policy_handle newhandle;
2955 bool ret = true, created2 = false, created4 = false;
2956 struct dcerpc_binding_handle *b = p->binding_handle;
2957 const char *test_key2;
2958 const char *test_key4;
2960 torture_skip(tctx, "security descriptor test disabled\n");
2962 if (torture_setting_bool(tctx, "samba3", false) ||
2963 torture_setting_bool(tctx, "samba4", false)) {
2964 torture_skip(tctx, "skipping security descriptor tests against Samba");
2967 test_Cleanup(b, tctx, handle, base_key);
2969 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2970 torture_comment(tctx,
2971 "CreateKey(%s) failed\n", base_key);
2974 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2976 if (test_CreateKey_sd(b, tctx, handle, test_key2,
2977 NULL, &newhandle)) {
2981 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2982 torture_comment(tctx, "CloseKey failed\n");
2986 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
2988 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
2992 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2993 torture_comment(tctx, "CloseKey failed\n");
2997 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3001 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3002 torture_comment(tctx, "DeleteKey failed\n");
3006 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3007 torture_comment(tctx, "DeleteKey failed\n");
3011 test_Cleanup(b, tctx, handle, base_key);
3016 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3019 struct policy_handle handle;
3021 struct winreg_OpenHKLM r;
3022 struct dcerpc_binding_handle *b = p->binding_handle;
3023 const char *torture_base_key;
3026 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3028 r.in.system_name = 0;
3029 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3030 r.out.handle = &handle;
3032 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3035 if (!test_GetVersion(b, tctx, &handle)) {
3036 torture_comment(tctx, "GetVersion failed\n");
3040 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3041 hkey = HKEY_LOCAL_MACHINE;
3042 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3043 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3045 torture_base_key = TEST_KEY_BASE;
3046 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3047 hkey = HKEY_CLASSES_ROOT;
3048 torture_base_key = TEST_KEY_BASE;
3049 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3050 hkey = HKEY_CURRENT_USER;
3051 torture_base_key = TEST_KEY_BASE;
3053 torture_fail(tctx, "unsupported hkey");
3056 if (hkey == HKEY_LOCAL_MACHINE) {
3057 torture_assert(tctx,
3058 test_HKLM_wellknown(tctx, b, &handle),
3059 "failed to test HKLM wellknown keys");
3062 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3063 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3068 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3069 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3074 /* The HKCR hive has a very large fanout */
3075 if (hkey == HKEY_CLASSES_ROOT) {
3076 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3079 } else if (hkey == HKEY_LOCAL_MACHINE) {
3080 /* FIXME we are not allowed to enum values in the HKLM root */
3082 if (!test_key(p, tctx, &handle, 0, false)) {
3090 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3092 struct torture_rpc_tcase *tcase;
3093 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3094 struct torture_test *test;
3096 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3099 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3100 test_InitiateSystemShutdown);
3101 test->dangerous = true;
3103 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3104 test_InitiateSystemShutdownEx);
3105 test->dangerous = true;
3107 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3109 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
3110 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3112 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
3113 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3115 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
3116 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3118 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);