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_FILE_NOT_FOUND, 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[] = {
1230 .set_werr = WERR_OK,
1231 .sid_present = false,
1232 .fn = (secinfo_verify_fn)_test_owner_present,
1236 .sec_info = SECINFO_OWNER,
1237 .set_werr = WERR_OK,
1238 .sid_present = true,
1239 .fn = (secinfo_verify_fn)_test_owner_present,
1243 .sec_info = SECINFO_GROUP,
1244 .set_werr = WERR_INVALID_PARAMETER,
1245 .sid_present = false,
1249 .sec_info = SECINFO_DACL,
1250 .set_werr = WERR_OK,
1251 .sid_present = true,
1252 .fn = (secinfo_verify_fn)_test_owner_present,
1256 .sec_info = SECINFO_SACL,
1257 .set_werr = WERR_ACCESS_DENIED,
1258 .sid_present = false,
1262 uint32_t sd_owner_good_access_masks[] = {
1263 SEC_FLAG_MAXIMUM_ALLOWED,
1264 /* SEC_STD_WRITE_OWNER, */
1267 struct winreg_secinfo_table sec_info_group_tests[] = {
1271 .set_werr = WERR_OK,
1272 .sid_present = false,
1273 .fn = (secinfo_verify_fn)_test_group_present,
1277 .sec_info = SECINFO_OWNER,
1278 .set_werr = WERR_INVALID_PARAMETER,
1279 .sid_present = false,
1283 .sec_info = SECINFO_GROUP,
1284 .set_werr = WERR_OK,
1285 .sid_present = true,
1286 .fn = (secinfo_verify_fn)_test_group_present,
1290 .sec_info = SECINFO_DACL,
1291 .set_werr = WERR_OK,
1292 .sid_present = true,
1293 .fn = (secinfo_verify_fn)_test_group_present,
1297 .sec_info = SECINFO_SACL,
1298 .set_werr = WERR_ACCESS_DENIED,
1299 .sid_present = false,
1303 uint32_t sd_group_good_access_masks[] = {
1304 SEC_FLAG_MAXIMUM_ALLOWED,
1307 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1311 .set_werr = WERR_OK,
1312 .sid_present = false,
1313 .fn = (secinfo_verify_fn)_test_dacl_trustee_present,
1317 .sec_info = SECINFO_OWNER,
1318 .set_werr = WERR_INVALID_PARAMETER,
1319 .sid_present = false,
1323 .sec_info = SECINFO_GROUP,
1324 .set_werr = WERR_INVALID_PARAMETER,
1325 .sid_present = false,
1329 .sec_info = SECINFO_DACL,
1330 .set_werr = WERR_OK,
1331 .sid_present = true,
1332 .fn = (secinfo_verify_fn)_test_dacl_trustee_present
1336 .sec_info = SECINFO_SACL,
1337 .set_werr = WERR_ACCESS_DENIED,
1338 .sid_present = false,
1342 uint32_t sd_dacl_good_access_masks[] = {
1343 SEC_FLAG_MAXIMUM_ALLOWED,
1347 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1351 .set_werr = WERR_OK,
1352 .sid_present = false,
1353 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1357 .sec_info = SECINFO_OWNER,
1358 .set_werr = WERR_INVALID_PARAMETER,
1359 .sid_present = false,
1363 .sec_info = SECINFO_GROUP,
1364 .set_werr = WERR_INVALID_PARAMETER,
1365 .sid_present = false,
1369 .sec_info = SECINFO_DACL,
1370 .set_werr = WERR_OK,
1371 .sid_present = false,
1372 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1376 .sec_info = SECINFO_SACL,
1377 .set_werr = WERR_OK,
1378 .sid_present = true,
1379 .fn = (secinfo_verify_fn)_test_sacl_trustee_present,
1383 uint32_t sd_sacl_good_access_masks[] = {
1384 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1385 /* SEC_FLAG_SYSTEM_SECURITY, */
1388 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1393 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1399 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1401 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1403 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1406 sd_owner_good_access_masks[a],
1407 sec_info_owner_tests[i].sec_info,
1408 sec_info_owner_tests[i].sd,
1409 sec_info_owner_tests[i].set_werr,
1410 sec_info_owner_tests[i].sid_present,
1411 sec_info_owner_tests[i].fn,
1414 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1423 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1425 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1427 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1430 sd_group_good_access_masks[a],
1431 sec_info_group_tests[i].sec_info,
1432 sec_info_group_tests[i].sd,
1433 sec_info_group_tests[i].set_werr,
1434 sec_info_group_tests[i].sid_present,
1435 sec_info_group_tests[i].fn,
1438 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1447 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1449 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1451 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1454 sd_dacl_good_access_masks[a],
1455 sec_info_dacl_tests[i].sec_info,
1456 sec_info_dacl_tests[i].sd,
1457 sec_info_dacl_tests[i].set_werr,
1458 sec_info_dacl_tests[i].sid_present,
1459 sec_info_dacl_tests[i].fn,
1462 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1471 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1473 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1475 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1478 sd_sacl_good_access_masks[a],
1479 sec_info_sacl_tests[i].sec_info,
1480 sec_info_sacl_tests[i].sd,
1481 sec_info_sacl_tests[i].set_werr,
1482 sec_info_sacl_tests[i].sid_present,
1483 sec_info_sacl_tests[i].fn,
1486 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1494 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1499 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1500 struct torture_context *tctx,
1501 struct policy_handle *handle,
1506 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1507 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1511 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1512 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1516 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1517 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1521 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1522 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1526 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1527 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1534 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1535 struct torture_context *tctx,
1536 struct policy_handle *handle,
1538 WERROR expected_result)
1540 struct winreg_DeleteKey r;
1542 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1544 r.in.handle = handle;
1545 init_winreg_String(&r.in.key, key);
1547 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1548 "Delete Key failed");
1549 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1550 "DeleteKey failed");
1555 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1556 struct torture_context *tctx,
1557 struct policy_handle *handle, const char *key)
1559 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1562 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1563 struct torture_context *tctx,
1564 struct policy_handle *handle,
1566 uint32_t *pmax_valnamelen,
1567 uint32_t *pmax_valbufsize)
1569 struct winreg_QueryInfoKey r;
1570 uint32_t num_subkeys, max_subkeylen, max_classlen,
1571 num_values, max_valnamelen, max_valbufsize,
1573 NTTIME last_changed_time;
1576 r.in.handle = handle;
1577 r.out.num_subkeys = &num_subkeys;
1578 r.out.max_subkeylen = &max_subkeylen;
1579 r.out.max_classlen = &max_classlen;
1580 r.out.num_values = &num_values;
1581 r.out.max_valnamelen = &max_valnamelen;
1582 r.out.max_valbufsize = &max_valbufsize;
1583 r.out.secdescsize = &secdescsize;
1584 r.out.last_changed_time = &last_changed_time;
1586 r.out.classname = talloc(tctx, struct winreg_String);
1588 r.in.classname = talloc(tctx, struct winreg_String);
1589 init_winreg_String(r.in.classname, kclass);
1591 torture_assert_ntstatus_ok(tctx,
1592 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1593 "QueryInfoKey failed");
1595 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1597 if (pmax_valnamelen) {
1598 *pmax_valnamelen = max_valnamelen;
1601 if (pmax_valbufsize) {
1602 *pmax_valbufsize = max_valbufsize;
1608 static bool test_SetValue(struct dcerpc_binding_handle *b,
1609 struct torture_context *tctx,
1610 struct policy_handle *handle,
1611 const char *value_name,
1612 enum winreg_Type type,
1616 struct winreg_SetValue r;
1617 struct winreg_String name;
1619 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1620 value_name, str_regtype(type), size);
1622 init_winreg_String(&name, value_name);
1624 r.in.handle = handle;
1630 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1631 "winreg_SetValue failed");
1632 torture_assert_werr_ok(tctx, r.out.result,
1633 "winreg_SetValue failed");
1638 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1639 struct torture_context *tctx,
1640 struct policy_handle *handle,
1641 const char *value_name)
1643 struct winreg_DeleteValue r;
1644 struct winreg_String value;
1646 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1648 init_winreg_String(&value, value_name);
1650 r.in.handle = handle;
1653 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1654 "winreg_DeleteValue failed");
1655 torture_assert_werr_ok(tctx, r.out.result,
1656 "winreg_DeleteValue failed");
1661 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1662 struct policy_handle *handle, int depth,
1663 bool test_security);
1665 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1666 struct policy_handle *handle, int depth,
1669 struct winreg_EnumKey r;
1670 struct winreg_StringBuf kclass, name;
1673 struct dcerpc_binding_handle *b = p->binding_handle;
1679 r.in.handle = handle;
1680 r.in.enum_index = 0;
1682 r.in.keyclass = &kclass;
1684 r.in.last_changed_time = &t;
1690 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1692 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1693 struct policy_handle key_handle;
1695 torture_comment(tctx, "EnumKey: %d: %s\n",
1699 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1702 test_key(p, tctx, &key_handle,
1703 depth + 1, test_security);
1709 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1711 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1713 if (!W_ERROR_IS_OK(r.out.result) &&
1714 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1715 torture_fail(tctx, "EnumKey failed");
1721 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1722 struct torture_context *tctx,
1723 struct policy_handle *handle,
1724 const char *valuename)
1726 struct winreg_QueryMultipleValues r;
1731 r.in.key_handle = handle;
1732 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1733 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1734 r.in.values_in[0].ve_valuename->name = valuename;
1735 /* size needs to be set manually for winreg_ValNameBuf */
1736 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1738 r.in.num_values = 1;
1739 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1740 *r.in.buffer_size = bufsize;
1742 *r.in.buffer_size = bufsize;
1743 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1746 torture_assert_ntstatus_ok(tctx,
1747 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1748 "QueryMultipleValues failed");
1750 talloc_free(r.in.buffer);
1752 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1754 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1759 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1760 struct torture_context *tctx,
1761 struct policy_handle *handle,
1762 uint32_t num_values,
1763 const char * const *valuenames,
1764 bool existing_value)
1766 struct winreg_QueryMultipleValues r;
1767 uint32_t bufsize = 0;
1770 torture_comment(tctx, "Testing QueryMultipleValues\n");
1774 r.in.key_handle = handle;
1775 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1776 r.in.buffer_size = r.out.buffer_size = &bufsize;
1778 torture_assert_ntstatus_ok(tctx,
1779 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1780 "QueryMultipleValues failed");
1781 torture_assert_werr_ok(tctx, r.out.result,
1782 "QueryMultipleValues failed");
1784 /* this test crashes w2k8 remote registry */
1786 r.in.num_values = num_values;
1787 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1789 torture_assert_ntstatus_ok(tctx,
1790 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1791 "QueryMultipleValues failed");
1792 torture_assert_werr_ok(tctx, r.out.result,
1793 "QueryMultipleValues failed");
1795 r.in.num_values = num_values;
1796 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1797 for (i=0; i < r.in.num_values; i++) {
1798 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1799 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1800 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1803 torture_assert_ntstatus_ok(tctx,
1804 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1805 "QueryMultipleValues failed");
1806 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1807 "QueryMultipleValues failed");
1809 if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1813 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1814 *r.in.buffer_size = 0xff;
1815 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1817 torture_assert_ntstatus_ok(tctx,
1818 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1819 "QueryMultipleValues failed");
1822 torture_assert_werr_ok(tctx, r.out.result,
1823 "QueryMultipleValues failed");
1829 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1830 struct torture_context *tctx,
1831 struct policy_handle *handle,
1832 uint32_t num_values,
1833 const char * const *valuenames,
1834 bool existing_value)
1836 struct winreg_QueryMultipleValues2 r;
1837 uint32_t offered = 0, needed;
1840 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1844 r.in.key_handle = handle;
1845 r.in.offered = &offered;
1846 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1847 r.out.needed = &needed;
1849 torture_assert_ntstatus_ok(tctx,
1850 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1851 "QueryMultipleValues2 failed");
1852 torture_assert_werr_ok(tctx, r.out.result,
1853 "QueryMultipleValues2 failed");
1855 /* this test crashes w2k8 remote registry */
1857 r.in.num_values = num_values;
1858 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1860 torture_assert_ntstatus_ok(tctx,
1861 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1862 "QueryMultipleValues2 failed");
1863 torture_assert_werr_ok(tctx, r.out.result,
1864 "QueryMultipleValues2 failed");
1866 r.in.num_values = num_values;
1867 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1868 for (i=0; i < r.in.num_values; i++) {
1869 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1870 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1871 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1874 torture_assert_ntstatus_ok(tctx,
1875 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1876 "QueryMultipleValues2 failed");
1877 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_FILE_NOT_FOUND,
1878 "QueryMultipleValues2 failed");
1880 if (W_ERROR_EQUAL(r.out.result, WERR_FILE_NOT_FOUND)) {
1884 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1885 *r.in.offered = *r.out.needed;
1886 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1888 torture_assert_ntstatus_ok(tctx,
1889 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1890 "QueryMultipleValues2 failed");
1893 torture_assert_werr_ok(tctx, r.out.result,
1894 "QueryMultipleValues2 failed");
1899 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1900 struct torture_context *tctx,
1901 struct policy_handle *handle,
1902 const char *valuename)
1904 struct winreg_QueryMultipleValues2 r;
1905 uint32_t offered = 0, needed;
1909 r.in.key_handle = handle;
1910 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1911 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1912 r.in.values_in[0].ve_valuename->name = valuename;
1913 /* size needs to be set manually for winreg_ValNameBuf */
1914 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1916 r.in.num_values = 1;
1917 r.in.offered = &offered;
1918 r.out.needed = &needed;
1920 torture_assert_ntstatus_ok(tctx,
1921 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1922 "QueryMultipleValues2 failed");
1923 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1924 *r.in.offered = *r.out.needed;
1925 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1927 torture_assert_ntstatus_ok(tctx,
1928 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1929 "QueryMultipleValues2 failed");
1932 torture_assert_werr_ok(tctx, r.out.result,
1933 "QueryMultipleValues2 failed");
1938 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1939 struct torture_context *tctx,
1940 struct policy_handle *handle,
1941 const char *valuename)
1943 struct winreg_QueryValue r;
1945 enum winreg_Type zero_type = 0;
1946 uint32_t offered = 0xfff;
1950 r.in.handle = handle;
1952 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1953 r.in.value_name->name = valuename;
1954 r.in.type = &zero_type;
1955 r.in.data_size = &offered;
1956 r.in.data_length = &zero;
1958 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1959 if (NT_STATUS_IS_ERR(status)) {
1960 torture_fail(tctx, "QueryValue failed");
1963 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1968 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1969 struct torture_context *tctx,
1970 struct policy_handle *handle,
1971 const char *valuename,
1972 bool existing_value)
1974 struct winreg_QueryValue r;
1975 struct winreg_String value_name;
1976 enum winreg_Type type = REG_NONE;
1977 uint32_t data_size = 0;
1978 uint32_t real_data_size = 0;
1979 uint32_t data_length = 0;
1980 uint8_t *data = NULL;
1981 WERROR expected_error = WERR_FILE_NOT_FOUND;
1982 const char *errmsg_nonexisting = "expected WERR_FILE_NOT_FOUND for nonexisting value";
1984 if (valuename == NULL) {
1985 expected_error = WERR_INVALID_PARAMETER;
1986 errmsg_nonexisting = "expected WERR_INVALID_PARAMETER for NULL valuename";
1991 init_winreg_String(&value_name, NULL);
1993 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1995 r.in.handle = handle;
1996 r.in.value_name = &value_name;
1998 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1999 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2000 "expected WERR_INVALID_PARAMETER for NULL winreg_String.name");
2002 init_winreg_String(&value_name, valuename);
2003 r.in.value_name = &value_name;
2005 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2006 "QueryValue failed");
2007 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2008 "expected WERR_INVALID_PARAMETER for missing type length and size");
2012 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2013 "QueryValue failed");
2014 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2015 "expected WERR_INVALID_PARAMETER for missing length and size");
2017 r.in.data_length = &data_length;
2018 r.out.data_length = &data_length;
2019 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2020 "QueryValue failed");
2021 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAMETER,
2022 "expected WERR_INVALID_PARAMETER for missing size");
2024 r.in.data_size = &data_size;
2025 r.out.data_size = &data_size;
2026 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2027 "QueryValue failed");
2028 if (existing_value) {
2029 torture_assert_werr_ok(tctx, r.out.result,
2030 "QueryValue failed");
2032 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2033 errmsg_nonexisting);
2036 real_data_size = *r.out.data_size;
2038 data = talloc_zero_array(tctx, uint8_t, 0);
2041 *r.in.data_size = 0;
2042 *r.out.data_size = 0;
2043 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2044 "QueryValue failed");
2045 if (existing_value) {
2046 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
2047 "expected WERR_MORE_DATA for query with too small buffer");
2049 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2050 errmsg_nonexisting);
2053 data = talloc_zero_array(tctx, uint8_t, real_data_size);
2056 r.in.data_size = &real_data_size;
2057 r.out.data_size = &real_data_size;
2058 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
2059 "QueryValue failed");
2060 if (existing_value) {
2061 torture_assert_werr_ok(tctx, r.out.result,
2062 "QueryValue failed");
2064 torture_assert_werr_equal(tctx, r.out.result, expected_error,
2065 errmsg_nonexisting);
2071 static bool test_EnumValue(struct dcerpc_binding_handle *b,
2072 struct torture_context *tctx,
2073 struct policy_handle *handle, int max_valnamelen,
2076 struct winreg_EnumValue r;
2077 enum winreg_Type type = 0;
2078 uint32_t size = max_valbufsize, zero = 0;
2080 uint8_t *data = NULL;
2081 struct winreg_ValNameBuf name;
2085 r.in.handle = handle;
2086 r.in.enum_index = 0;
2090 r.in.length = &zero;
2095 name.size = max_valnamelen + 2;
2100 data = talloc_array(tctx, uint8_t, size);
2104 torture_assert_ntstatus_ok(tctx,
2105 dcerpc_winreg_EnumValue_r(b, tctx, &r),
2106 "EnumValue failed");
2108 if (W_ERROR_IS_OK(r.out.result)) {
2109 ret &= test_QueryValue(b, tctx, handle,
2111 ret &= test_QueryMultipleValues(b, tctx, handle,
2113 ret &= test_QueryMultipleValues2(b, tctx, handle,
2120 } while (W_ERROR_IS_OK(r.out.result));
2122 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2123 "EnumValue failed");
2128 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2129 struct torture_context *tctx)
2131 struct winreg_AbortSystemShutdown r;
2132 uint16_t server = 0x0;
2135 r.in.server = &server;
2137 torture_assert_ntstatus_ok(tctx,
2138 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2139 "AbortSystemShutdown failed");
2141 torture_assert_werr_ok(tctx, r.out.result,
2142 "AbortSystemShutdown failed");
2147 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2148 struct dcerpc_pipe *p)
2150 struct winreg_InitiateSystemShutdown r;
2151 uint16_t hostname = 0x0;
2152 struct dcerpc_binding_handle *b = p->binding_handle;
2155 r.in.hostname = &hostname;
2156 r.in.message = talloc(tctx, struct lsa_StringLarge);
2157 init_lsa_StringLarge(r.in.message, "spottyfood");
2158 r.in.force_apps = 1;
2162 torture_assert_ntstatus_ok(tctx,
2163 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2164 "InitiateSystemShutdown failed");
2166 torture_assert_werr_ok(tctx, r.out.result,
2167 "InitiateSystemShutdown failed");
2169 return test_AbortSystemShutdown(b, tctx);
2173 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2174 struct dcerpc_pipe *p)
2176 struct winreg_InitiateSystemShutdownEx r;
2177 uint16_t hostname = 0x0;
2178 struct dcerpc_binding_handle *b = p->binding_handle;
2181 r.in.hostname = &hostname;
2182 r.in.message = talloc(tctx, struct lsa_StringLarge);
2183 init_lsa_StringLarge(r.in.message, "spottyfood");
2184 r.in.force_apps = 1;
2189 torture_assert_ntstatus_ok(tctx,
2190 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2191 "InitiateSystemShutdownEx failed");
2193 torture_assert_werr_ok(tctx, r.out.result,
2194 "InitiateSystemShutdownEx failed");
2196 return test_AbortSystemShutdown(b, tctx);
2198 #define MAX_DEPTH 2 /* Only go this far down the tree */
2200 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2201 struct policy_handle *handle, int depth,
2204 struct dcerpc_binding_handle *b = p->binding_handle;
2205 uint32_t max_valnamelen = 0;
2206 uint32_t max_valbufsize = 0;
2208 if (depth == MAX_DEPTH)
2211 if (!test_QueryInfoKey(b, tctx, handle, NULL,
2212 &max_valnamelen, &max_valbufsize)) {
2215 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2218 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2221 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2224 if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2227 if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2230 test_CloseKey(b, tctx, handle);
2235 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2236 struct torture_context *tctx,
2237 struct policy_handle *handle)
2239 const char *value_name = TEST_VALUE;
2240 uint32_t value = 0x12345678;
2241 uint64_t value2 = 0x12345678;
2242 const char *string = "torture";
2243 const char *array[2];
2245 enum winreg_Type types[] = {
2247 REG_DWORD_BIG_ENDIAN,
2255 array[0] = "array0";
2258 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2260 for (t=0; t < ARRAY_SIZE(types); t++) {
2262 enum winreg_Type w_type;
2263 uint32_t w_size, w_length;
2268 case REG_DWORD_BIG_ENDIAN:
2269 blob = data_blob_talloc_zero(tctx, 4);
2270 SIVAL(blob.data, 0, value);
2273 blob = data_blob_talloc_zero(tctx, 8);
2274 SBVAL(blob.data, 0, value2);
2277 blob = data_blob_string_const("binary_blob");
2280 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2283 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2289 torture_assert(tctx,
2290 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2291 "test_SetValue failed");
2292 torture_assert(tctx,
2293 test_QueryValue_full(b, tctx, handle, value_name, true),
2294 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2295 torture_assert(tctx,
2296 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2297 "test_winreg_QueryValue failed");
2298 torture_assert(tctx,
2299 test_DeleteValue(b, tctx, handle, value_name),
2300 "test_DeleteValue failed");
2302 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2303 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2304 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2305 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2308 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2313 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2314 struct torture_context *tctx,
2315 struct policy_handle *handle)
2318 const char *values[] = {
2325 "torture_value_name",
2326 "torture value name",
2327 "torture,value,name",
2328 "torture;value;name",
2329 "torture/value/name",
2330 "torture\\value\\name",
2334 torture_comment(tctx, "Testing SetValue (values)\n");
2336 for (i=0; i < ARRAY_SIZE(values); i++) {
2338 enum winreg_Type w_type;
2339 uint32_t w_size, w_length;
2342 blob = data_blob_talloc(tctx, NULL, 32);
2344 generate_random_buffer(blob.data, 32);
2346 torture_assert(tctx,
2347 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2348 "test_SetValue failed");
2349 torture_assert(tctx,
2350 test_QueryValue_full(b, tctx, handle, values[i], true),
2351 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2352 torture_assert(tctx,
2353 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2354 "test_winreg_QueryValue failed");
2355 torture_assert(tctx,
2356 test_DeleteValue(b, tctx, handle, values[i]),
2357 "test_DeleteValue failed");
2359 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2360 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2361 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2362 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2365 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2370 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2372 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2373 struct torture_context *tctx,
2374 struct policy_handle *handle)
2376 const char *value_name = TEST_VALUE;
2377 enum winreg_Type types[] = {
2383 REG_DWORD_BIG_ENDIAN,
2387 REG_FULL_RESOURCE_DESCRIPTOR,
2388 REG_RESOURCE_REQUIREMENTS_LIST,
2400 if (torture_setting_bool(tctx, "samba4", false)) {
2401 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2404 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2406 for (t=0; t < ARRAY_SIZE(types); t++) {
2407 for (l=0; l < 16; l++) {
2409 enum winreg_Type w_type;
2410 uint32_t w_size, w_length;
2417 data = talloc_array(tctx, uint8_t, size);
2419 generate_random_buffer(data, size);
2421 torture_assert(tctx,
2422 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2423 "test_SetValue failed");
2425 torture_assert(tctx,
2426 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2427 "test_winreg_QueryValue failed");
2429 torture_assert(tctx,
2430 test_DeleteValue(b, tctx, handle, value_name),
2431 "test_DeleteValue failed");
2433 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2434 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2435 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2436 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2440 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2445 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2446 struct torture_context *tctx,
2447 struct policy_handle *handle)
2449 const char *keys[] = {
2458 for (i=0; i < ARRAY_SIZE(keys); i++) {
2460 enum winreg_CreateAction action_taken;
2461 struct policy_handle new_handle;
2464 torture_assert(tctx,
2465 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2466 REG_OPTION_NON_VOLATILE,
2467 SEC_FLAG_MAXIMUM_ALLOWED,
2472 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2474 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2476 torture_assert(tctx,
2477 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2478 "failed to delete key");
2480 torture_assert(tctx,
2481 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_FILE_NOT_FOUND),
2482 "failed 2nd delete key");
2484 tmp = talloc_strdup(tctx, keys[i]);
2486 q = strchr(tmp, '\\');
2491 torture_assert(tctx,
2492 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2493 "failed to delete key");
2495 torture_assert(tctx,
2496 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_FILE_NOT_FOUND),
2497 "failed 2nd delete key");
2504 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2505 #define VALUE_CURRENT_VERSION "CurrentVersion"
2506 #define VALUE_SYSTEM_ROOT "SystemRoot"
2508 static const struct {
2509 const char *values[3];
2510 uint32_t num_values;
2511 bool existing_value;
2512 const char *error_message;
2513 } multiple_values_tests[] = {
2515 .values = { VALUE_CURRENT_VERSION, NULL, NULL },
2517 .existing_value = true,
2518 .error_message = NULL
2520 .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2522 .existing_value = true,
2523 .error_message = NULL
2525 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2527 .existing_value = true,
2528 .error_message = NULL
2530 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2531 VALUE_CURRENT_VERSION },
2533 .existing_value = true,
2534 .error_message = NULL
2536 .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2538 .existing_value = false,
2539 .error_message = NULL
2541 .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2543 .existing_value = false,
2544 .error_message = NULL
2546 .values = { "IDoNotExist", NULL, NULL },
2548 .existing_value = false,
2549 .error_message = NULL
2551 .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2553 .existing_value = false,
2554 .error_message = NULL
2556 .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2558 .existing_value = false,
2559 .error_message = NULL
2563 static bool test_HKLM_wellknown(struct torture_context *tctx,
2564 struct dcerpc_binding_handle *b,
2565 struct policy_handle *handle)
2567 struct policy_handle newhandle;
2570 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2571 if (torture_setting_bool(tctx, "samba3", false)) {
2572 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2573 KEY_CURRENT_VERSION,
2574 REG_OPTION_NON_VOLATILE,
2578 "failed to open current version key");
2580 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2581 "failed to open current version key");
2584 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2585 "failed to query current version");
2586 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2587 "succeeded to query nonexistent value");
2588 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2589 "succeeded to query value with NULL name");
2590 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2591 "succeeded to query nonexistent default value (\"\")");
2593 if (torture_setting_bool(tctx, "samba4", false)) {
2594 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2598 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2600 msg = talloc_asprintf(tctx,
2601 "failed to query %d %sexisting values\n",
2602 multiple_values_tests[i].num_values,
2603 multiple_values_tests[i].existing_value ? "":"non");
2605 torture_assert(tctx,
2606 test_QueryMultipleValues_full(b, tctx, &newhandle,
2607 multiple_values_tests[i].num_values,
2608 multiple_values_tests[i].values,
2609 multiple_values_tests[i].existing_value),
2611 torture_assert(tctx,
2612 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2613 multiple_values_tests[i].num_values,
2614 multiple_values_tests[i].values,
2615 multiple_values_tests[i].existing_value),
2620 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2621 "failed to close current version key");
2626 static bool test_OpenHive(struct torture_context *tctx,
2627 struct dcerpc_binding_handle *b,
2628 struct policy_handle *handle,
2631 struct winreg_OpenHKLM r;
2633 r.in.system_name = 0;
2634 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2635 r.out.handle = handle;
2638 case HKEY_LOCAL_MACHINE:
2639 torture_assert_ntstatus_ok(tctx,
2640 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2641 "failed to open HKLM");
2642 torture_assert_werr_ok(tctx, r.out.result,
2643 "failed to open HKLM");
2645 case HKEY_CURRENT_USER:
2646 torture_assert_ntstatus_ok(tctx,
2647 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2648 "failed to open HKCU");
2649 torture_assert_werr_ok(tctx, r.out.result,
2650 "failed to open HKCU");
2653 torture_assert_ntstatus_ok(tctx,
2654 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2655 "failed to open HKU");
2656 torture_assert_werr_ok(tctx, r.out.result,
2657 "failed to open HKU");
2659 case HKEY_CLASSES_ROOT:
2660 torture_assert_ntstatus_ok(tctx,
2661 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2662 "failed to open HKCR");
2663 torture_assert_werr_ok(tctx, r.out.result,
2664 "failed to open HKCR");
2667 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2674 static bool test_volatile_keys(struct torture_context *tctx,
2675 struct dcerpc_binding_handle *b,
2676 struct policy_handle *handle,
2679 struct policy_handle new_handle, hive_handle;
2680 enum winreg_CreateAction action_taken = REG_ACTION_NONE;
2682 ZERO_STRUCT(new_handle);
2683 ZERO_STRUCT(hive_handle);
2685 torture_comment(tctx, "Testing VOLATILE key\n");
2687 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2689 torture_assert(tctx,
2690 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2691 REG_OPTION_VOLATILE,
2692 SEC_FLAG_MAXIMUM_ALLOWED,
2697 "failed to create REG_OPTION_VOLATILE type key");
2699 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2701 torture_assert(tctx,
2702 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2703 REG_OPTION_NON_VOLATILE,
2704 SEC_FLAG_MAXIMUM_ALLOWED,
2706 WERR_CHILD_MUST_BE_VOLATILE,
2709 "failed to fail create REG_OPTION_VOLATILE type key");
2711 torture_assert(tctx,
2712 test_CloseKey(b, tctx, &new_handle),
2715 torture_assert(tctx,
2716 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2717 REG_OPTION_NON_VOLATILE,
2718 SEC_FLAG_MAXIMUM_ALLOWED,
2721 "failed to open volatile key");
2723 torture_assert(tctx,
2724 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2725 "failed to delete key");
2727 torture_assert(tctx,
2728 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2729 REG_OPTION_VOLATILE,
2730 SEC_FLAG_MAXIMUM_ALLOWED,
2735 "failed to create REG_OPTION_VOLATILE type key");
2737 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2739 torture_assert(tctx,
2740 test_CloseKey(b, tctx, &new_handle),
2743 torture_assert(tctx,
2744 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2745 REG_OPTION_VOLATILE,
2746 SEC_FLAG_MAXIMUM_ALLOWED,
2749 "failed to open volatile key");
2751 torture_assert(tctx,
2752 test_CloseKey(b, tctx, &new_handle),
2755 torture_assert(tctx,
2756 test_OpenHive(tctx, b, &hive_handle, hkey),
2757 "failed top open hive");
2759 torture_assert(tctx,
2760 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2761 REG_OPTION_VOLATILE,
2762 SEC_FLAG_MAXIMUM_ALLOWED,
2764 WERR_FILE_NOT_FOUND),
2765 "failed to open volatile key");
2767 torture_assert(tctx,
2768 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2769 REG_OPTION_NON_VOLATILE,
2770 SEC_FLAG_MAXIMUM_ALLOWED,
2772 WERR_FILE_NOT_FOUND),
2773 "failed to open volatile key");
2775 torture_assert(tctx,
2776 test_CloseKey(b, tctx, &hive_handle),
2779 torture_assert(tctx,
2780 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2781 "failed to delete key");
2784 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2789 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2791 const char *sid_string,
2795 case HKEY_LOCAL_MACHINE:
2796 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2797 case HKEY_CURRENT_USER:
2798 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2800 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2801 case HKEY_CLASSES_ROOT:
2802 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2804 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2809 static bool test_symlink_keys(struct torture_context *tctx,
2810 struct dcerpc_binding_handle *b,
2811 struct policy_handle *handle,
2815 struct policy_handle new_handle;
2816 enum winreg_CreateAction action_taken;
2818 uint32_t value = 42;
2819 const char *test_key_symlink_dest;
2820 const char *test_key_symlink;
2821 const char *kernel_mode_path;
2823 /* disable until we know how to delete a symbolic link */
2824 torture_skip(tctx, "symlink test disabled");
2826 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2828 /* create destination key with testvalue */
2829 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2830 key, TEST_KEY_SYMLINK);
2831 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2832 key, TEST_KEY_SYMLINK_DEST);
2834 test_DeleteKey(b, tctx, handle, test_key_symlink);
2836 torture_assert(tctx,
2837 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2839 SEC_FLAG_MAXIMUM_ALLOWED,
2844 "failed to create symlink destination");
2846 blob = data_blob_talloc_zero(tctx, 4);
2847 SIVAL(blob.data, 0, value);
2849 torture_assert(tctx,
2850 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2851 "failed to create TestValue");
2853 torture_assert(tctx,
2854 test_CloseKey(b, tctx, &new_handle),
2857 /* create symlink */
2859 torture_assert(tctx,
2860 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2861 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2862 SEC_FLAG_MAXIMUM_ALLOWED,
2867 "failed to create REG_OPTION_CREATE_LINK type key");
2869 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2871 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2873 torture_assert(tctx,
2874 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2876 strlen(kernel_mode_path), /* not NULL terminated */
2877 &blob.data, &blob.length),
2878 "failed to convert");
2880 torture_assert(tctx,
2881 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2882 "failed to create SymbolicLinkValue value");
2884 torture_assert(tctx,
2885 test_CloseKey(b, tctx, &new_handle),
2888 /* test follow symlink */
2890 torture_assert(tctx,
2891 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2893 SEC_FLAG_MAXIMUM_ALLOWED,
2896 "failed to follow symlink key");
2898 torture_assert(tctx,
2899 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2900 "failed to query value");
2902 torture_assert(tctx,
2903 test_CloseKey(b, tctx, &new_handle),
2908 torture_assert(tctx,
2909 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2910 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2911 SEC_FLAG_MAXIMUM_ALLOWED,
2914 "failed to open symlink key");
2916 torture_assert(tctx,
2917 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2918 "failed to delete value SymbolicLinkValue");
2920 torture_assert(tctx,
2921 test_CloseKey(b, tctx, &new_handle),
2924 torture_assert(tctx,
2925 test_DeleteKey(b, tctx, handle, test_key_symlink),
2926 "failed to delete key");
2928 /* delete destination */
2930 torture_assert(tctx,
2931 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2932 "failed to delete key");
2937 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2938 struct dcerpc_binding_handle *b,
2939 struct policy_handle *handle,
2944 if (torture_setting_bool(tctx, "samba3", false) ||
2945 torture_setting_bool(tctx, "samba4", false)) {
2946 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2949 torture_assert(tctx,
2950 test_volatile_keys(tctx, b, handle, hkey),
2951 "failed to test volatile keys");
2953 torture_assert(tctx,
2954 test_symlink_keys(tctx, b, handle, key, hkey),
2955 "failed to test symlink keys");
2960 static bool test_key_base(struct torture_context *tctx,
2961 struct dcerpc_binding_handle *b,
2962 struct policy_handle *handle,
2963 const char *base_key,
2966 struct policy_handle newhandle;
2967 bool ret = true, created = false, deleted = false;
2968 bool created3 = false;
2969 const char *test_key1;
2970 const char *test_key3;
2971 const char *test_subkey;
2973 test_Cleanup(b, tctx, handle, base_key);
2975 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2976 torture_comment(tctx,
2977 "CreateKey(%s) failed\n", base_key);
2980 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2982 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2983 torture_comment(tctx,
2984 "CreateKey failed - not considering a failure\n");
2990 if (!test_FlushKey(b, tctx, handle)) {
2991 torture_comment(tctx, "FlushKey failed\n");
2995 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2997 "CreateKey failed (OpenKey after Create didn't work)\n");
3000 if (hkey == HKEY_CURRENT_USER) {
3001 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
3002 "simple SetValue test failed");
3003 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
3004 "values SetValue test failed");
3005 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
3006 "extended SetValue test failed");
3007 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
3008 "keyname CreateKey test failed");
3010 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
3011 "keytype test failed");
3014 if (!test_CloseKey(b, tctx, &newhandle)) {
3016 "CreateKey failed (CloseKey after Open didn't work)\n");
3019 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
3020 torture_comment(tctx, "DeleteKey(%s) failed\n",
3027 if (!test_FlushKey(b, tctx, handle)) {
3028 torture_comment(tctx, "FlushKey failed\n");
3033 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
3034 REG_OPTION_NON_VOLATILE,
3035 SEC_FLAG_MAXIMUM_ALLOWED,
3037 WERR_FILE_NOT_FOUND)) {
3038 torture_comment(tctx,
3039 "DeleteKey failed (OpenKey after Delete "
3040 "did not return WERR_FILE_NOT_FOUND)\n");
3045 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
3047 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
3051 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
3054 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
3055 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
3056 torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
3061 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
3062 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
3068 test_Cleanup(b, tctx, handle, base_key);
3073 static bool test_key_base_sd(struct torture_context *tctx,
3074 struct dcerpc_pipe *p,
3075 struct policy_handle *handle,
3076 const char *base_key)
3078 struct policy_handle newhandle;
3079 bool ret = true, created2 = false, created4 = false;
3080 struct dcerpc_binding_handle *b = p->binding_handle;
3081 const char *test_key2;
3082 const char *test_key4;
3084 torture_skip(tctx, "security descriptor test disabled\n");
3086 if (torture_setting_bool(tctx, "samba3", false) ||
3087 torture_setting_bool(tctx, "samba4", false)) {
3088 torture_skip(tctx, "skipping security descriptor tests against Samba");
3091 test_Cleanup(b, tctx, handle, base_key);
3093 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
3094 torture_comment(tctx,
3095 "CreateKey(%s) failed\n", base_key);
3098 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3100 if (test_CreateKey_sd(b, tctx, handle, test_key2,
3101 NULL, &newhandle)) {
3105 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3106 torture_comment(tctx, "CloseKey failed\n");
3110 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3112 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3116 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3117 torture_comment(tctx, "CloseKey failed\n");
3121 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3125 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3126 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3130 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3131 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3135 test_Cleanup(b, tctx, handle, base_key);
3140 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3143 struct policy_handle handle;
3145 struct winreg_OpenHKLM r;
3146 struct dcerpc_binding_handle *b = p->binding_handle;
3147 const char *torture_base_key;
3150 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3152 r.in.system_name = 0;
3153 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3154 r.out.handle = &handle;
3156 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3159 if (!test_GetVersion(b, tctx, &handle)) {
3160 torture_comment(tctx, "GetVersion failed\n");
3164 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3165 hkey = HKEY_LOCAL_MACHINE;
3166 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3167 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3169 torture_base_key = TEST_KEY_BASE;
3170 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3171 hkey = HKEY_CLASSES_ROOT;
3172 torture_base_key = TEST_KEY_BASE;
3173 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3174 hkey = HKEY_CURRENT_USER;
3175 torture_base_key = TEST_KEY_BASE;
3177 torture_fail(tctx, "unsupported hkey");
3180 if (hkey == HKEY_LOCAL_MACHINE) {
3181 torture_assert(tctx,
3182 test_HKLM_wellknown(tctx, b, &handle),
3183 "failed to test HKLM wellknown keys");
3186 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3187 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3192 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3193 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3198 /* The HKCR hive has a very large fanout */
3199 if (hkey == HKEY_CLASSES_ROOT) {
3200 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3203 } else if (hkey == HKEY_LOCAL_MACHINE) {
3204 /* FIXME we are not allowed to enum values in the HKLM root */
3206 if (!test_key(p, tctx, &handle, 0, false)) {
3214 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3216 struct torture_rpc_tcase *tcase;
3217 struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3218 struct torture_test *test;
3220 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3223 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3224 test_InitiateSystemShutdown);
3225 test->dangerous = true;
3227 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3228 test_InitiateSystemShutdownEx);
3229 test->dangerous = true;
3231 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3233 (void *)dcerpc_winreg_OpenHKLM_r);
3234 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3236 (void *)dcerpc_winreg_OpenHKU_r);
3237 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3239 (void *)dcerpc_winreg_OpenHKCR_r);
3240 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3242 (void *)dcerpc_winreg_OpenHKCU_r);