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,
1466 uint32_t *pmax_valnamelen,
1467 uint32_t *pmax_valbufsize)
1469 struct winreg_QueryInfoKey r;
1470 uint32_t num_subkeys, max_subkeylen, max_classlen,
1471 num_values, max_valnamelen, max_valbufsize,
1473 NTTIME last_changed_time;
1476 r.in.handle = handle;
1477 r.out.num_subkeys = &num_subkeys;
1478 r.out.max_subkeylen = &max_subkeylen;
1479 r.out.max_classlen = &max_classlen;
1480 r.out.num_values = &num_values;
1481 r.out.max_valnamelen = &max_valnamelen;
1482 r.out.max_valbufsize = &max_valbufsize;
1483 r.out.secdescsize = &secdescsize;
1484 r.out.last_changed_time = &last_changed_time;
1486 r.out.classname = talloc(tctx, struct winreg_String);
1488 r.in.classname = talloc(tctx, struct winreg_String);
1489 init_winreg_String(r.in.classname, kclass);
1491 torture_assert_ntstatus_ok(tctx,
1492 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1493 "QueryInfoKey failed");
1495 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1497 if (pmax_valnamelen) {
1498 *pmax_valnamelen = max_valnamelen;
1501 if (pmax_valbufsize) {
1502 *pmax_valbufsize = max_valbufsize;
1508 static bool test_SetValue(struct dcerpc_binding_handle *b,
1509 struct torture_context *tctx,
1510 struct policy_handle *handle,
1511 const char *value_name,
1512 enum winreg_Type type,
1516 struct winreg_SetValue r;
1517 struct winreg_String name;
1519 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1520 value_name, str_regtype(type), size);
1522 init_winreg_String(&name, value_name);
1524 r.in.handle = handle;
1530 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1531 "winreg_SetValue failed");
1532 torture_assert_werr_ok(tctx, r.out.result,
1533 "winreg_SetValue failed");
1538 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1539 struct torture_context *tctx,
1540 struct policy_handle *handle,
1541 const char *value_name)
1543 struct winreg_DeleteValue r;
1544 struct winreg_String value;
1546 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1548 init_winreg_String(&value, value_name);
1550 r.in.handle = handle;
1553 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1554 "winreg_DeleteValue failed");
1555 torture_assert_werr_ok(tctx, r.out.result,
1556 "winreg_DeleteValue failed");
1561 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1562 struct policy_handle *handle, int depth,
1563 bool test_security);
1565 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1566 struct policy_handle *handle, int depth,
1569 struct winreg_EnumKey r;
1570 struct winreg_StringBuf kclass, name;
1573 struct dcerpc_binding_handle *b = p->binding_handle;
1579 r.in.handle = handle;
1580 r.in.enum_index = 0;
1582 r.in.keyclass = &kclass;
1584 r.in.last_changed_time = &t;
1590 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1592 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1593 struct policy_handle key_handle;
1595 torture_comment(tctx, "EnumKey: %d: %s\n",
1599 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1602 test_key(p, tctx, &key_handle,
1603 depth + 1, test_security);
1609 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1611 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1613 if (!W_ERROR_IS_OK(r.out.result) &&
1614 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1615 torture_fail(tctx, "EnumKey failed");
1621 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1622 struct torture_context *tctx,
1623 struct policy_handle *handle,
1624 const char *valuename)
1626 struct winreg_QueryMultipleValues r;
1631 r.in.key_handle = handle;
1632 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1633 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1634 r.in.values_in[0].ve_valuename->name = valuename;
1635 /* size needs to be set manually for winreg_ValNameBuf */
1636 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1638 r.in.num_values = 1;
1639 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1640 *r.in.buffer_size = bufsize;
1642 *r.in.buffer_size = bufsize;
1643 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1646 torture_assert_ntstatus_ok(tctx,
1647 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1648 "QueryMultipleValues failed");
1650 talloc_free(r.in.buffer);
1652 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1654 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1659 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1660 struct torture_context *tctx,
1661 struct policy_handle *handle,
1662 uint32_t num_values,
1663 const char * const *valuenames,
1664 bool existing_value)
1666 struct winreg_QueryMultipleValues r;
1667 uint32_t bufsize = 0;
1670 torture_comment(tctx, "Testing QueryMultipleValues\n");
1674 r.in.key_handle = handle;
1675 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1676 r.in.buffer_size = r.out.buffer_size = &bufsize;
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 /* this test crashes w2k8 remote registry */
1686 r.in.num_values = num_values;
1687 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1689 torture_assert_ntstatus_ok(tctx,
1690 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1691 "QueryMultipleValues failed");
1692 torture_assert_werr_ok(tctx, r.out.result,
1693 "QueryMultipleValues failed");
1695 r.in.num_values = num_values;
1696 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1697 for (i=0; i < r.in.num_values; i++) {
1698 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1699 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1700 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1703 torture_assert_ntstatus_ok(tctx,
1704 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1705 "QueryMultipleValues failed");
1706 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1707 "QueryMultipleValues failed");
1709 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1713 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1714 *r.in.buffer_size = 0xff;
1715 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1717 torture_assert_ntstatus_ok(tctx,
1718 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1719 "QueryMultipleValues failed");
1722 torture_assert_werr_ok(tctx, r.out.result,
1723 "QueryMultipleValues failed");
1729 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1730 struct torture_context *tctx,
1731 struct policy_handle *handle,
1732 uint32_t num_values,
1733 const char * const *valuenames,
1734 bool existing_value)
1736 struct winreg_QueryMultipleValues2 r;
1737 uint32_t offered = 0, needed;
1740 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1744 r.in.key_handle = handle;
1745 r.in.offered = &offered;
1746 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1747 r.out.needed = &needed;
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 /* this test crashes w2k8 remote registry */
1757 r.in.num_values = num_values;
1758 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1760 torture_assert_ntstatus_ok(tctx,
1761 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1762 "QueryMultipleValues2 failed");
1763 torture_assert_werr_ok(tctx, r.out.result,
1764 "QueryMultipleValues2 failed");
1766 r.in.num_values = num_values;
1767 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1768 for (i=0; i < r.in.num_values; i++) {
1769 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1770 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1771 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1774 torture_assert_ntstatus_ok(tctx,
1775 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1776 "QueryMultipleValues2 failed");
1777 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1778 "QueryMultipleValues2 failed");
1780 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1784 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1785 *r.in.offered = *r.out.needed;
1786 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1788 torture_assert_ntstatus_ok(tctx,
1789 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1790 "QueryMultipleValues2 failed");
1793 torture_assert_werr_ok(tctx, r.out.result,
1794 "QueryMultipleValues2 failed");
1799 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1800 struct torture_context *tctx,
1801 struct policy_handle *handle,
1802 const char *valuename)
1804 struct winreg_QueryMultipleValues2 r;
1805 uint32_t offered = 0, needed;
1809 r.in.key_handle = handle;
1810 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1811 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1812 r.in.values_in[0].ve_valuename->name = valuename;
1813 /* size needs to be set manually for winreg_ValNameBuf */
1814 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1816 r.in.num_values = 1;
1817 r.in.offered = &offered;
1818 r.out.needed = &needed;
1820 torture_assert_ntstatus_ok(tctx,
1821 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1822 "QueryMultipleValues2 failed");
1823 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1824 *r.in.offered = *r.out.needed;
1825 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1827 torture_assert_ntstatus_ok(tctx,
1828 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1829 "QueryMultipleValues2 failed");
1832 torture_assert_werr_ok(tctx, r.out.result,
1833 "QueryMultipleValues2 failed");
1838 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1839 struct torture_context *tctx,
1840 struct policy_handle *handle,
1841 const char *valuename)
1843 struct winreg_QueryValue r;
1845 enum winreg_Type zero_type = 0;
1846 uint32_t offered = 0xfff;
1850 r.in.handle = handle;
1852 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1853 r.in.value_name->name = valuename;
1854 r.in.type = &zero_type;
1855 r.in.data_size = &offered;
1856 r.in.data_length = &zero;
1858 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1859 if (NT_STATUS_IS_ERR(status)) {
1860 torture_fail(tctx, "QueryValue failed");
1863 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1868 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1869 struct torture_context *tctx,
1870 struct policy_handle *handle,
1871 const char *valuename,
1872 bool existing_value)
1874 struct winreg_QueryValue r;
1875 struct winreg_String value_name;
1876 enum winreg_Type type = REG_NONE;
1877 uint32_t data_size = 0;
1878 uint32_t real_data_size = 0;
1879 uint32_t data_length = 0;
1880 uint8_t *data = NULL;
1881 WERROR expected_error = WERR_BADFILE;
1882 const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1884 if (valuename == NULL) {
1885 expected_error = WERR_INVALID_PARAM;
1886 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1891 init_winreg_String(&value_name, NULL);
1893 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1895 r.in.handle = handle;
1896 r.in.value_name = &value_name;
1898 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1899 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1900 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1902 init_winreg_String(&value_name, valuename);
1903 r.in.value_name = &value_name;
1905 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1906 "QueryValue failed");
1907 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1908 "expected WERR_INVALID_PARAM for missing type length and size");
1912 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1913 "QueryValue failed");
1914 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1915 "expected WERR_INVALID_PARAM for missing length and size");
1917 r.in.data_length = &data_length;
1918 r.out.data_length = &data_length;
1919 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1920 "QueryValue failed");
1921 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1922 "expected WERR_INVALID_PARAM for missing size");
1924 r.in.data_size = &data_size;
1925 r.out.data_size = &data_size;
1926 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1927 "QueryValue failed");
1928 if (existing_value) {
1929 torture_assert_werr_ok(tctx, r.out.result,
1930 "QueryValue failed");
1932 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1933 errmsg_nonexisting);
1936 real_data_size = *r.out.data_size;
1938 data = talloc_zero_array(tctx, uint8_t, 0);
1941 *r.in.data_size = 0;
1942 *r.out.data_size = 0;
1943 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1944 "QueryValue failed");
1945 if (existing_value) {
1946 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1947 "expected WERR_MORE_DATA for query with too small buffer");
1949 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1950 errmsg_nonexisting);
1953 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1956 r.in.data_size = &real_data_size;
1957 r.out.data_size = &real_data_size;
1958 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1959 "QueryValue failed");
1960 if (existing_value) {
1961 torture_assert_werr_ok(tctx, r.out.result,
1962 "QueryValue failed");
1964 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1965 errmsg_nonexisting);
1971 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1972 struct torture_context *tctx,
1973 struct policy_handle *handle, int max_valnamelen,
1976 struct winreg_EnumValue r;
1977 enum winreg_Type type = 0;
1978 uint32_t size = max_valbufsize, zero = 0;
1980 uint8_t *data = NULL;
1981 struct winreg_ValNameBuf name;
1985 r.in.handle = handle;
1986 r.in.enum_index = 0;
1990 r.in.length = &zero;
1995 name.size = max_valnamelen + 2;
2000 data = (uint8_t *) talloc_array(tctx, uint8_t *, size);
2004 torture_assert_ntstatus_ok(tctx,
2005 dcerpc_winreg_EnumValue_r(b, tctx, &r),
2006 "EnumValue failed");
2008 if (W_ERROR_IS_OK(r.out.result)) {
2009 ret &= test_QueryValue(b, tctx, handle,
2011 ret &= test_QueryMultipleValues(b, tctx, handle,
2013 ret &= test_QueryMultipleValues2(b, tctx, handle,
2020 } while (W_ERROR_IS_OK(r.out.result));
2022 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2023 "EnumValue failed");
2028 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2029 struct torture_context *tctx)
2031 struct winreg_AbortSystemShutdown r;
2032 uint16_t server = 0x0;
2035 r.in.server = &server;
2037 torture_assert_ntstatus_ok(tctx,
2038 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2039 "AbortSystemShutdown failed");
2041 torture_assert_werr_ok(tctx, r.out.result,
2042 "AbortSystemShutdown failed");
2047 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2048 struct dcerpc_pipe *p)
2050 struct winreg_InitiateSystemShutdown r;
2051 uint16_t hostname = 0x0;
2052 struct dcerpc_binding_handle *b = p->binding_handle;
2055 r.in.hostname = &hostname;
2056 r.in.message = talloc(tctx, struct lsa_StringLarge);
2057 init_lsa_StringLarge(r.in.message, "spottyfood");
2058 r.in.force_apps = 1;
2062 torture_assert_ntstatus_ok(tctx,
2063 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2064 "InitiateSystemShutdown failed");
2066 torture_assert_werr_ok(tctx, r.out.result,
2067 "InitiateSystemShutdown failed");
2069 return test_AbortSystemShutdown(b, tctx);
2073 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2074 struct dcerpc_pipe *p)
2076 struct winreg_InitiateSystemShutdownEx r;
2077 uint16_t hostname = 0x0;
2078 struct dcerpc_binding_handle *b = p->binding_handle;
2081 r.in.hostname = &hostname;
2082 r.in.message = talloc(tctx, struct lsa_StringLarge);
2083 init_lsa_StringLarge(r.in.message, "spottyfood");
2084 r.in.force_apps = 1;
2089 torture_assert_ntstatus_ok(tctx,
2090 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2091 "InitiateSystemShutdownEx failed");
2093 torture_assert_werr_ok(tctx, r.out.result,
2094 "InitiateSystemShutdownEx failed");
2096 return test_AbortSystemShutdown(b, tctx);
2098 #define MAX_DEPTH 2 /* Only go this far down the tree */
2100 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2101 struct policy_handle *handle, int depth,
2104 struct dcerpc_binding_handle *b = p->binding_handle;
2105 uint32_t max_valnamelen = 0;
2106 uint32_t max_valbufsize = 0;
2108 if (depth == MAX_DEPTH)
2111 if (!test_QueryInfoKey(b, tctx, handle, NULL,
2112 &max_valnamelen, &max_valbufsize)) {
2115 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2118 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2121 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2124 if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2127 if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2130 test_CloseKey(b, tctx, handle);
2135 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2136 struct torture_context *tctx,
2137 struct policy_handle *handle)
2139 const char *value_name = TEST_VALUE;
2140 uint32_t value = 0x12345678;
2141 uint64_t value2 = 0x12345678;
2142 const char *string = "torture";
2143 const char *array[2];
2145 enum winreg_Type types[] = {
2147 REG_DWORD_BIG_ENDIAN,
2155 array[0] = "array0";
2158 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2160 for (t=0; t < ARRAY_SIZE(types); t++) {
2162 enum winreg_Type w_type;
2163 uint32_t w_size, w_length;
2168 case REG_DWORD_BIG_ENDIAN:
2169 blob = data_blob_talloc_zero(tctx, 4);
2170 SIVAL(blob.data, 0, value);
2173 blob = data_blob_talloc_zero(tctx, 8);
2174 SBVAL(blob.data, 0, value2);
2177 blob = data_blob_string_const("binary_blob");
2180 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2183 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2189 torture_assert(tctx,
2190 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2191 "test_SetValue failed");
2192 torture_assert(tctx,
2193 test_QueryValue_full(b, tctx, handle, value_name, true),
2194 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2195 torture_assert(tctx,
2196 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2197 "test_winreg_QueryValue failed");
2198 torture_assert(tctx,
2199 test_DeleteValue(b, tctx, handle, value_name),
2200 "test_DeleteValue failed");
2202 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2203 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2204 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2205 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2208 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2213 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2214 struct torture_context *tctx,
2215 struct policy_handle *handle)
2218 const char *values[] = {
2225 "torture_value_name",
2226 "torture value name",
2227 "torture,value,name",
2228 "torture;value;name",
2229 "torture/value/name",
2230 "torture\\value\\name",
2234 torture_comment(tctx, "Testing SetValue (values)\n");
2236 for (i=0; i < ARRAY_SIZE(values); i++) {
2238 enum winreg_Type w_type;
2239 uint32_t w_size, w_length;
2242 blob = data_blob_talloc(tctx, NULL, 32);
2244 generate_random_buffer(blob.data, 32);
2246 torture_assert(tctx,
2247 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2248 "test_SetValue failed");
2249 torture_assert(tctx,
2250 test_QueryValue_full(b, tctx, handle, values[i], true),
2251 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2252 torture_assert(tctx,
2253 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2254 "test_winreg_QueryValue failed");
2255 torture_assert(tctx,
2256 test_DeleteValue(b, tctx, handle, values[i]),
2257 "test_DeleteValue failed");
2259 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2260 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2261 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2262 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2265 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2270 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2272 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2273 struct torture_context *tctx,
2274 struct policy_handle *handle)
2276 const char *value_name = TEST_VALUE;
2277 enum winreg_Type types[] = {
2283 REG_DWORD_BIG_ENDIAN,
2287 REG_FULL_RESOURCE_DESCRIPTOR,
2288 REG_RESOURCE_REQUIREMENTS_LIST,
2300 if (torture_setting_bool(tctx, "samba4", false)) {
2301 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2304 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2306 for (t=0; t < ARRAY_SIZE(types); t++) {
2307 for (l=0; l < 16; l++) {
2309 enum winreg_Type w_type;
2310 uint32_t w_size, w_length;
2317 data = talloc_array(tctx, uint8_t, size);
2319 generate_random_buffer(data, size);
2321 torture_assert(tctx,
2322 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2323 "test_SetValue failed");
2325 torture_assert(tctx,
2326 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2327 "test_winreg_QueryValue failed");
2329 torture_assert(tctx,
2330 test_DeleteValue(b, tctx, handle, value_name),
2331 "test_DeleteValue failed");
2333 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2334 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2335 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2336 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2340 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2345 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2346 struct torture_context *tctx,
2347 struct policy_handle *handle)
2349 const char *keys[] = {
2358 for (i=0; i < ARRAY_SIZE(keys); i++) {
2360 enum winreg_CreateAction action_taken;
2361 struct policy_handle new_handle;
2364 torture_assert(tctx,
2365 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2366 REG_OPTION_NON_VOLATILE,
2367 SEC_FLAG_MAXIMUM_ALLOWED,
2372 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2374 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2376 torture_assert(tctx,
2377 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2378 "failed to delete key");
2380 torture_assert(tctx,
2381 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2382 "failed 2nd delete key");
2384 tmp = talloc_strdup(tctx, keys[i]);
2386 q = strchr(tmp, '\\');
2391 torture_assert(tctx,
2392 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2393 "failed to delete key");
2395 torture_assert(tctx,
2396 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2397 "failed 2nd delete key");
2404 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2405 #define VALUE_CURRENT_VERSION "CurrentVersion"
2406 #define VALUE_SYSTEM_ROOT "SystemRoot"
2408 static bool test_HKLM_wellknown(struct torture_context *tctx,
2409 struct dcerpc_binding_handle *b,
2410 struct policy_handle *handle)
2412 struct policy_handle newhandle;
2414 static const struct {
2415 const char *values[3];
2416 uint32_t num_values;
2417 bool existing_value;
2418 const char *error_message;
2419 } multiple_values_tests[] = {
2421 .values[0] = VALUE_CURRENT_VERSION,
2425 .existing_value = true
2427 .values[0] = VALUE_SYSTEM_ROOT,
2431 .existing_value = true
2433 .values[0] = VALUE_CURRENT_VERSION,
2434 .values[1] = VALUE_SYSTEM_ROOT,
2437 .existing_value = true
2439 .values[0] = VALUE_CURRENT_VERSION,
2440 .values[1] = VALUE_SYSTEM_ROOT,
2441 .values[2] = VALUE_CURRENT_VERSION,
2443 .existing_value = true
2445 .values[0] = VALUE_CURRENT_VERSION,
2447 .values[2] = VALUE_SYSTEM_ROOT,
2449 .existing_value = false
2451 .values[0] = VALUE_CURRENT_VERSION,
2453 .values[2] = VALUE_SYSTEM_ROOT,
2455 .existing_value = false
2457 .values[0] = "IDoNotExist",
2461 .existing_value = false
2463 .values[0] = "IDoNotExist",
2464 .values[1] = VALUE_CURRENT_VERSION,
2467 .existing_value = false
2469 .values[0] = VALUE_CURRENT_VERSION,
2470 .values[1] = "IDoNotExist",
2473 .existing_value = false
2477 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2478 if (torture_setting_bool(tctx, "samba3", false)) {
2479 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2480 KEY_CURRENT_VERSION,
2481 REG_OPTION_NON_VOLATILE,
2485 "failed to open current version key");
2487 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2488 "failed to open current version key");
2491 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2492 "failed to query current version");
2493 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2494 "succeeded to query nonexistent value");
2495 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2496 "succeeded to query value with NULL name");
2497 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2498 "succeeded to query nonexistent default value (\"\")");
2500 if (torture_setting_bool(tctx, "samba4", false)) {
2501 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2505 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2507 msg = talloc_asprintf(tctx,
2508 "failed to query %d %sexisting values\n",
2509 multiple_values_tests[i].num_values,
2510 multiple_values_tests[i].existing_value ? "":"non");
2512 torture_assert(tctx,
2513 test_QueryMultipleValues_full(b, tctx, &newhandle,
2514 multiple_values_tests[i].num_values,
2515 multiple_values_tests[i].values,
2516 multiple_values_tests[i].existing_value),
2518 torture_assert(tctx,
2519 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2520 multiple_values_tests[i].num_values,
2521 multiple_values_tests[i].values,
2522 multiple_values_tests[i].existing_value),
2527 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2528 "failed to close current version key");
2533 static bool test_OpenHive(struct torture_context *tctx,
2534 struct dcerpc_binding_handle *b,
2535 struct policy_handle *handle,
2538 struct winreg_OpenHKLM r;
2540 r.in.system_name = 0;
2541 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2542 r.out.handle = handle;
2545 case HKEY_LOCAL_MACHINE:
2546 torture_assert_ntstatus_ok(tctx,
2547 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2548 "failed to open HKLM");
2549 torture_assert_werr_ok(tctx, r.out.result,
2550 "failed to open HKLM");
2552 case HKEY_CURRENT_USER:
2553 torture_assert_ntstatus_ok(tctx,
2554 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2555 "failed to open HKCU");
2556 torture_assert_werr_ok(tctx, r.out.result,
2557 "failed to open HKCU");
2560 torture_assert_ntstatus_ok(tctx,
2561 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2562 "failed to open HKU");
2563 torture_assert_werr_ok(tctx, r.out.result,
2564 "failed to open HKU");
2566 case HKEY_CLASSES_ROOT:
2567 torture_assert_ntstatus_ok(tctx,
2568 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2569 "failed to open HKCR");
2570 torture_assert_werr_ok(tctx, r.out.result,
2571 "failed to open HKCR");
2574 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2581 static bool test_volatile_keys(struct torture_context *tctx,
2582 struct dcerpc_binding_handle *b,
2583 struct policy_handle *handle,
2586 struct policy_handle new_handle, hive_handle;
2587 enum winreg_CreateAction action_taken;
2589 torture_comment(tctx, "Testing VOLATILE key\n");
2591 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2593 torture_assert(tctx,
2594 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2595 REG_OPTION_VOLATILE,
2596 SEC_FLAG_MAXIMUM_ALLOWED,
2601 "failed to create REG_OPTION_VOLATILE type key");
2603 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2605 torture_assert(tctx,
2606 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2607 REG_OPTION_NON_VOLATILE,
2608 SEC_FLAG_MAXIMUM_ALLOWED,
2610 WERR_CHILD_MUST_BE_VOLATILE,
2613 "failed to fail create REG_OPTION_VOLATILE type key");
2615 torture_assert(tctx,
2616 test_CloseKey(b, tctx, &new_handle),
2619 torture_assert(tctx,
2620 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2621 REG_OPTION_NON_VOLATILE,
2622 SEC_FLAG_MAXIMUM_ALLOWED,
2625 "failed to open volatile key");
2627 torture_assert(tctx,
2628 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2629 "failed to delete key");
2631 torture_assert(tctx,
2632 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2633 REG_OPTION_VOLATILE,
2634 SEC_FLAG_MAXIMUM_ALLOWED,
2639 "failed to create REG_OPTION_VOLATILE type key");
2641 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2643 torture_assert(tctx,
2644 test_CloseKey(b, tctx, &new_handle),
2647 torture_assert(tctx,
2648 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2649 REG_OPTION_VOLATILE,
2650 SEC_FLAG_MAXIMUM_ALLOWED,
2653 "failed to open volatile key");
2655 torture_assert(tctx,
2656 test_CloseKey(b, tctx, &new_handle),
2659 torture_assert(tctx,
2660 test_OpenHive(tctx, b, &hive_handle, hkey),
2661 "failed top open hive");
2663 torture_assert(tctx,
2664 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2665 REG_OPTION_VOLATILE,
2666 SEC_FLAG_MAXIMUM_ALLOWED,
2669 "failed to open volatile key");
2671 torture_assert(tctx,
2672 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2673 REG_OPTION_NON_VOLATILE,
2674 SEC_FLAG_MAXIMUM_ALLOWED,
2677 "failed to open volatile key");
2679 torture_assert(tctx,
2680 test_CloseKey(b, tctx, &hive_handle),
2683 torture_assert(tctx,
2684 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2685 "failed to delete key");
2688 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2693 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2695 const char *sid_string,
2699 case HKEY_LOCAL_MACHINE:
2700 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2701 case HKEY_CURRENT_USER:
2702 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2704 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2705 case HKEY_CLASSES_ROOT:
2706 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2708 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2713 static bool test_symlink_keys(struct torture_context *tctx,
2714 struct dcerpc_binding_handle *b,
2715 struct policy_handle *handle,
2719 struct policy_handle new_handle;
2720 enum winreg_CreateAction action_taken;
2722 uint32_t value = 42;
2723 const char *test_key_symlink_dest;
2724 const char *test_key_symlink;
2725 const char *kernel_mode_path;
2727 /* disable until we know how to delete a symbolic link */
2728 torture_skip(tctx, "symlink test disabled");
2730 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2732 /* create destination key with testvalue */
2733 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2734 key, TEST_KEY_SYMLINK);
2735 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2736 key, TEST_KEY_SYMLINK_DEST);
2738 test_DeleteKey(b, tctx, handle, test_key_symlink);
2740 torture_assert(tctx,
2741 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2743 SEC_FLAG_MAXIMUM_ALLOWED,
2748 "failed to create symlink destination");
2750 blob = data_blob_talloc_zero(tctx, 4);
2751 SIVAL(blob.data, 0, value);
2753 torture_assert(tctx,
2754 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2755 "failed to create TestValue");
2757 torture_assert(tctx,
2758 test_CloseKey(b, tctx, &new_handle),
2761 /* create symlink */
2763 torture_assert(tctx,
2764 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2765 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2766 SEC_FLAG_MAXIMUM_ALLOWED,
2771 "failed to create REG_OPTION_CREATE_LINK type key");
2773 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2775 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2777 torture_assert(tctx,
2778 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2780 strlen(kernel_mode_path), /* not NULL terminated */
2781 &blob.data, &blob.length,
2783 "failed to convert");
2785 torture_assert(tctx,
2786 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2787 "failed to create SymbolicLinkValue value");
2789 torture_assert(tctx,
2790 test_CloseKey(b, tctx, &new_handle),
2793 /* test follow symlink */
2795 torture_assert(tctx,
2796 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2798 SEC_FLAG_MAXIMUM_ALLOWED,
2801 "failed to follow symlink key");
2803 torture_assert(tctx,
2804 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2805 "failed to query value");
2807 torture_assert(tctx,
2808 test_CloseKey(b, tctx, &new_handle),
2813 torture_assert(tctx,
2814 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2815 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2816 SEC_FLAG_MAXIMUM_ALLOWED,
2819 "failed to open symlink key");
2821 torture_assert(tctx,
2822 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2823 "failed to delete value SymbolicLinkValue");
2825 torture_assert(tctx,
2826 test_CloseKey(b, tctx, &new_handle),
2829 torture_assert(tctx,
2830 test_DeleteKey(b, tctx, handle, test_key_symlink),
2831 "failed to delete key");
2833 /* delete destination */
2835 torture_assert(tctx,
2836 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2837 "failed to delete key");
2842 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2843 struct dcerpc_binding_handle *b,
2844 struct policy_handle *handle,
2849 if (torture_setting_bool(tctx, "samba3", false) ||
2850 torture_setting_bool(tctx, "samba4", false)) {
2851 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2854 torture_assert(tctx,
2855 test_volatile_keys(tctx, b, handle, hkey),
2856 "failed to test volatile keys");
2858 torture_assert(tctx,
2859 test_symlink_keys(tctx, b, handle, key, hkey),
2860 "failed to test symlink keys");
2865 static bool test_key_base(struct torture_context *tctx,
2866 struct dcerpc_binding_handle *b,
2867 struct policy_handle *handle,
2868 const char *base_key,
2871 struct policy_handle newhandle;
2872 bool ret = true, created = false, deleted = false;
2873 bool created3 = false;
2874 const char *test_key1;
2875 const char *test_key3;
2876 const char *test_subkey;
2878 test_Cleanup(b, tctx, handle, base_key);
2880 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2881 torture_comment(tctx,
2882 "CreateKey(%s) failed\n", base_key);
2885 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2887 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2888 torture_comment(tctx,
2889 "CreateKey failed - not considering a failure\n");
2895 if (!test_FlushKey(b, tctx, handle)) {
2896 torture_comment(tctx, "FlushKey failed\n");
2900 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2902 "CreateKey failed (OpenKey after Create didn't work)\n");
2905 if (hkey == HKEY_CURRENT_USER) {
2906 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2907 "simple SetValue test failed");
2908 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2909 "values SetValue test failed");
2910 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2911 "extended SetValue test failed");
2912 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2913 "keyname CreateKey test failed");
2915 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2916 "keytype test failed");
2919 if (!test_CloseKey(b, tctx, &newhandle)) {
2921 "CreateKey failed (CloseKey after Open didn't work)\n");
2924 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2925 torture_comment(tctx, "DeleteKey(%s) failed\n",
2932 if (!test_FlushKey(b, tctx, handle)) {
2933 torture_comment(tctx, "FlushKey failed\n");
2938 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2939 REG_OPTION_NON_VOLATILE,
2940 SEC_FLAG_MAXIMUM_ALLOWED,
2943 torture_comment(tctx,
2944 "DeleteKey failed (OpenKey after Delete "
2945 "did not return WERR_BADFILE)\n");
2950 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2952 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2956 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2959 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2960 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2961 torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
2966 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2967 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
2973 test_Cleanup(b, tctx, handle, base_key);
2978 static bool test_key_base_sd(struct torture_context *tctx,
2979 struct dcerpc_pipe *p,
2980 struct policy_handle *handle,
2981 const char *base_key)
2983 struct policy_handle newhandle;
2984 bool ret = true, created2 = false, created4 = false;
2985 struct dcerpc_binding_handle *b = p->binding_handle;
2986 const char *test_key2;
2987 const char *test_key4;
2989 torture_skip(tctx, "security descriptor test disabled\n");
2991 if (torture_setting_bool(tctx, "samba3", false) ||
2992 torture_setting_bool(tctx, "samba4", false)) {
2993 torture_skip(tctx, "skipping security descriptor tests against Samba");
2996 test_Cleanup(b, tctx, handle, base_key);
2998 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2999 torture_comment(tctx,
3000 "CreateKey(%s) failed\n", base_key);
3003 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
3005 if (test_CreateKey_sd(b, tctx, handle, test_key2,
3006 NULL, &newhandle)) {
3010 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3011 torture_comment(tctx, "CloseKey failed\n");
3015 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3017 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3021 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3022 torture_comment(tctx, "CloseKey failed\n");
3026 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3030 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3031 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3035 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3036 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3040 test_Cleanup(b, tctx, handle, base_key);
3045 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3048 struct policy_handle handle;
3050 struct winreg_OpenHKLM r;
3051 struct dcerpc_binding_handle *b = p->binding_handle;
3052 const char *torture_base_key;
3055 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3057 r.in.system_name = 0;
3058 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3059 r.out.handle = &handle;
3061 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3064 if (!test_GetVersion(b, tctx, &handle)) {
3065 torture_comment(tctx, "GetVersion failed\n");
3069 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3070 hkey = HKEY_LOCAL_MACHINE;
3071 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3072 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3074 torture_base_key = TEST_KEY_BASE;
3075 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3076 hkey = HKEY_CLASSES_ROOT;
3077 torture_base_key = TEST_KEY_BASE;
3078 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3079 hkey = HKEY_CURRENT_USER;
3080 torture_base_key = TEST_KEY_BASE;
3082 torture_fail(tctx, "unsupported hkey");
3085 if (hkey == HKEY_LOCAL_MACHINE) {
3086 torture_assert(tctx,
3087 test_HKLM_wellknown(tctx, b, &handle),
3088 "failed to test HKLM wellknown keys");
3091 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3092 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3097 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3098 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3103 /* The HKCR hive has a very large fanout */
3104 if (hkey == HKEY_CLASSES_ROOT) {
3105 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3108 } else if (hkey == HKEY_LOCAL_MACHINE) {
3109 /* FIXME we are not allowed to enum values in the HKLM root */
3111 if (!test_key(p, tctx, &handle, 0, false)) {
3119 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3121 struct torture_rpc_tcase *tcase;
3122 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
3123 struct torture_test *test;
3125 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3128 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3129 test_InitiateSystemShutdown);
3130 test->dangerous = true;
3132 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3133 test_InitiateSystemShutdownEx);
3134 test->dangerous = true;
3136 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3138 (void *)dcerpc_winreg_OpenHKLM_r);
3139 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3141 (void *)dcerpc_winreg_OpenHKU_r);
3142 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3144 (void *)dcerpc_winreg_OpenHKCR_r);
3145 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3147 (void *)dcerpc_winreg_OpenHKCU_r);