s4-torture: Disable the security descriptor tests.
[Samba/ekacnet.git] / source4 / torture / rpc / winreg.c
blobbbe72be7cad3570d4e3a327bb9570fe934d9dd74
1 /*
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/>.
23 #include "includes.h"
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"
44 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
46 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
48 name->string = s;
51 static void init_winreg_String(struct winreg_String *name, const char *s)
53 name->name = s;
54 if (s) {
55 name->name_len = 2 * (strlen_m(s) + 1);
56 name->name_size = name->name_len;
57 } else {
58 name->name_len = 0;
59 name->name_size = 0;
63 static bool test_GetVersion(struct dcerpc_binding_handle *b,
64 struct torture_context *tctx,
65 struct policy_handle *handle)
67 struct winreg_GetVersion r;
68 uint32_t v;
70 torture_comment(tctx, "Testing GetVersion\n");
72 ZERO_STRUCT(r);
73 r.in.handle = handle;
74 r.out.version = &v;
76 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
77 "GetVersion failed");
79 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
81 return true;
84 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
85 struct torture_context *tctx,
86 struct policy_handle *handle)
88 struct winreg_NotifyChangeKeyValue r;
90 ZERO_STRUCT(r);
91 r.in.handle = handle;
92 r.in.watch_subtree = true;
93 r.in.notify_filter = 0;
94 r.in.unknown = r.in.unknown2 = 0;
95 init_winreg_String(&r.in.string1, NULL);
96 init_winreg_String(&r.in.string2, NULL);
98 torture_assert_ntstatus_ok(tctx,
99 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
100 "NotifyChangeKeyValue failed");
102 if (!W_ERROR_IS_OK(r.out.result)) {
103 torture_comment(tctx,
104 "NotifyChangeKeyValue failed - %s - not considering\n",
105 win_errstr(r.out.result));
106 return true;
109 return true;
112 static bool test_CreateKey_opts(struct torture_context *tctx,
113 struct dcerpc_binding_handle *b,
114 struct policy_handle *handle,
115 const char *name,
116 const char *kclass,
117 uint32_t options,
118 uint32_t access_mask,
119 struct winreg_SecBuf *secdesc,
120 WERROR expected_result,
121 enum winreg_CreateAction *action_taken_p,
122 struct policy_handle *new_handle_p)
124 struct winreg_CreateKey r;
125 struct policy_handle newhandle;
126 enum winreg_CreateAction action_taken = 0;
128 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
130 ZERO_STRUCT(r);
131 r.in.handle = handle;
132 init_winreg_String(&r.in.name, name);
133 init_winreg_String(&r.in.keyclass, kclass);
134 r.in.options = options;
135 r.in.access_mask = access_mask;
136 r.in.action_taken = &action_taken;
137 r.in.secdesc = secdesc;
138 r.out.new_handle = &newhandle;
139 r.out.action_taken = &action_taken;
141 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
142 "CreateKey failed");
144 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
146 if (new_handle_p) {
147 *new_handle_p = newhandle;
149 if (action_taken_p) {
150 *action_taken_p = *r.out.action_taken;
153 return true;
156 static bool test_CreateKey(struct dcerpc_binding_handle *b,
157 struct torture_context *tctx,
158 struct policy_handle *handle, const char *name,
159 const char *kclass)
161 return test_CreateKey_opts(tctx, b, handle, name, kclass,
162 REG_OPTION_NON_VOLATILE,
163 SEC_FLAG_MAXIMUM_ALLOWED,
164 NULL, /* secdesc */
165 WERR_OK,
166 NULL, /* action_taken */
167 NULL /* new_handle */);
171 createkey testing with a SD
173 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
174 struct torture_context *tctx,
175 struct policy_handle *handle, const char *name,
176 const char *kclass,
177 struct policy_handle *newhandle)
179 struct winreg_CreateKey r;
180 enum winreg_CreateAction action_taken = 0;
181 struct security_descriptor *sd;
182 DATA_BLOB sdblob;
183 struct winreg_SecBuf secbuf;
185 sd = security_descriptor_dacl_create(tctx,
187 NULL, NULL,
188 SID_NT_AUTHENTICATED_USERS,
189 SEC_ACE_TYPE_ACCESS_ALLOWED,
190 SEC_GENERIC_ALL,
191 SEC_ACE_FLAG_OBJECT_INHERIT |
192 SEC_ACE_FLAG_CONTAINER_INHERIT,
193 NULL);
195 torture_assert_ndr_success(tctx,
196 ndr_push_struct_blob(&sdblob, tctx, sd,
197 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
198 "Failed to push security_descriptor ?!\n");
200 secbuf.sd.data = sdblob.data;
201 secbuf.sd.len = sdblob.length;
202 secbuf.sd.size = sdblob.length;
203 secbuf.length = sdblob.length-10;
204 secbuf.inherit = 0;
206 ZERO_STRUCT(r);
207 r.in.handle = handle;
208 r.out.new_handle = newhandle;
209 init_winreg_String(&r.in.name, name);
210 init_winreg_String(&r.in.keyclass, kclass);
211 r.in.options = 0x0;
212 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
213 r.in.action_taken = r.out.action_taken = &action_taken;
214 r.in.secdesc = &secbuf;
216 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
217 "CreateKey with sd failed");
219 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
221 return true;
224 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
225 struct torture_context *tctx,
226 struct policy_handle *handle,
227 uint32_t *sec_info_ptr,
228 WERROR get_werr,
229 struct security_descriptor **sd_out)
231 struct winreg_GetKeySecurity r;
232 struct security_descriptor *sd = NULL;
233 uint32_t sec_info;
234 DATA_BLOB sdblob;
235 struct dcerpc_binding_handle *b = p->binding_handle;
237 if (sec_info_ptr) {
238 sec_info = *sec_info_ptr;
239 } else {
240 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
243 ZERO_STRUCT(r);
245 r.in.handle = handle;
246 r.in.sec_info = sec_info;
247 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
248 r.in.sd->size = 0x1000;
250 torture_assert_ntstatus_ok(tctx,
251 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
252 "GetKeySecurity failed");
254 torture_assert_werr_equal(tctx, r.out.result, get_werr,
255 "GetKeySecurity failed");
257 sdblob.data = r.out.sd->data;
258 sdblob.length = r.out.sd->len;
260 sd = talloc_zero(tctx, struct security_descriptor);
262 torture_assert_ndr_success(tctx,
263 ndr_pull_struct_blob(&sdblob, tctx, sd,
264 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
265 "pull_security_descriptor failed");
267 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
268 NDR_PRINT_DEBUG(security_descriptor, sd);
271 if (sd_out) {
272 *sd_out = sd;
273 } else {
274 talloc_free(sd);
277 return true;
280 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
281 struct torture_context *tctx,
282 struct policy_handle *handle,
283 struct security_descriptor **sd_out)
285 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
288 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
289 struct torture_context *tctx,
290 struct policy_handle *handle,
291 uint32_t *sec_info_ptr,
292 struct security_descriptor *sd,
293 WERROR werr)
295 struct winreg_SetKeySecurity r;
296 struct KeySecurityData *sdata = NULL;
297 DATA_BLOB sdblob;
298 uint32_t sec_info;
299 struct dcerpc_binding_handle *b = p->binding_handle;
301 ZERO_STRUCT(r);
303 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
304 NDR_PRINT_DEBUG(security_descriptor, sd);
307 torture_assert_ndr_success(tctx,
308 ndr_push_struct_blob(&sdblob, tctx, sd,
309 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
310 "push_security_descriptor failed");
312 sdata = talloc_zero(tctx, struct KeySecurityData);
313 sdata->data = sdblob.data;
314 sdata->size = sdblob.length;
315 sdata->len = sdblob.length;
317 if (sec_info_ptr) {
318 sec_info = *sec_info_ptr;
319 } else {
320 sec_info = SECINFO_UNPROTECTED_SACL |
321 SECINFO_UNPROTECTED_DACL;
322 if (sd->owner_sid) {
323 sec_info |= SECINFO_OWNER;
325 if (sd->group_sid) {
326 sec_info |= SECINFO_GROUP;
328 if (sd->sacl) {
329 sec_info |= SECINFO_SACL;
331 if (sd->dacl) {
332 sec_info |= SECINFO_DACL;
336 r.in.handle = handle;
337 r.in.sec_info = sec_info;
338 r.in.sd = sdata;
340 torture_assert_ntstatus_ok(tctx,
341 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
342 "SetKeySecurity failed");
344 torture_assert_werr_equal(tctx, r.out.result, werr,
345 "SetKeySecurity failed");
347 return true;
350 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
351 struct torture_context *tctx,
352 struct policy_handle *handle,
353 struct security_descriptor *sd)
355 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
358 static bool test_CloseKey(struct dcerpc_binding_handle *b,
359 struct torture_context *tctx,
360 struct policy_handle *handle)
362 struct winreg_CloseKey r;
364 ZERO_STRUCT(r);
365 r.in.handle = r.out.handle = handle;
367 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
368 "CloseKey failed");
370 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
372 return true;
375 static bool test_FlushKey(struct dcerpc_binding_handle *b,
376 struct torture_context *tctx,
377 struct policy_handle *handle)
379 struct winreg_FlushKey r;
381 ZERO_STRUCT(r);
382 r.in.handle = handle;
384 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
385 "FlushKey failed");
387 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
389 return true;
392 static bool test_OpenKey_opts(struct torture_context *tctx,
393 struct dcerpc_binding_handle *b,
394 struct policy_handle *hive_handle,
395 const char *keyname,
396 uint32_t options,
397 uint32_t access_mask,
398 struct policy_handle *key_handle,
399 WERROR expected_result)
401 struct winreg_OpenKey r;
403 ZERO_STRUCT(r);
404 r.in.parent_handle = hive_handle;
405 init_winreg_String(&r.in.keyname, keyname);
406 r.in.options = options;
407 r.in.access_mask = access_mask;
408 r.out.handle = key_handle;
410 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
411 "OpenKey failed");
413 torture_assert_werr_equal(tctx, r.out.result, expected_result,
414 "OpenKey failed");
416 return true;
419 static bool test_OpenKey(struct dcerpc_binding_handle *b,
420 struct torture_context *tctx,
421 struct policy_handle *hive_handle,
422 const char *keyname, struct policy_handle *key_handle)
424 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
425 REG_OPTION_NON_VOLATILE,
426 SEC_FLAG_MAXIMUM_ALLOWED,
427 key_handle,
428 WERR_OK);
431 static bool test_Cleanup(struct dcerpc_binding_handle *b,
432 struct torture_context *tctx,
433 struct policy_handle *handle, const char *key)
435 struct winreg_DeleteKey r;
437 ZERO_STRUCT(r);
438 r.in.handle = handle;
440 init_winreg_String(&r.in.key, key);
441 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
443 return true;
446 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
447 struct torture_context *tctx,
448 struct policy_handle *handle,
449 WERROR get_werr,
450 WERROR set_werr)
452 struct security_descriptor *sd = NULL;
454 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
455 return false;
458 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
459 return false;
462 return true;
465 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
466 struct torture_context *tctx,
467 struct policy_handle *handle,
468 const char *key)
470 struct policy_handle new_handle;
471 bool ret = true;
472 struct dcerpc_binding_handle *b = p->binding_handle;
474 torture_comment(tctx, "SecurityDescriptor get & set\n");
476 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
477 return false;
480 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
481 WERR_OK, WERR_OK)) {
482 ret = false;
485 if (!test_CloseKey(b, tctx, &new_handle)) {
486 return false;
489 return ret;
492 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
493 struct torture_context *tctx,
494 struct policy_handle *handle,
495 uint32_t access_mask,
496 const char *key,
497 WERROR open_werr,
498 WERROR get_werr,
499 WERROR set_werr)
501 struct policy_handle new_handle;
502 bool ret = true;
503 struct dcerpc_binding_handle *b = p->binding_handle;
505 torture_assert(tctx,
506 test_OpenKey_opts(tctx, b, handle, key,
507 REG_OPTION_NON_VOLATILE,
508 access_mask,
509 &new_handle,
510 open_werr),
511 "failed to open key");
513 if (!W_ERROR_IS_OK(open_werr)) {
514 return true;
517 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
518 get_werr, set_werr)) {
519 ret = false;
522 if (!test_CloseKey(b, tctx, &new_handle)) {
523 return false;
526 return ret;
529 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
530 struct torture_context *tctx,
531 struct policy_handle *handle,
532 const struct dom_sid *sid)
534 struct security_descriptor *sd = NULL;
535 int i;
537 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
538 return false;
541 if (!sd || !sd->dacl) {
542 return false;
545 for (i = 0; i < sd->dacl->num_aces; i++) {
546 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
547 return true;
551 return false;
554 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
555 struct torture_context *tctx,
556 struct policy_handle *handle,
557 const char *key,
558 const struct dom_sid *sid)
560 struct policy_handle new_handle;
561 bool ret = true;
562 struct dcerpc_binding_handle *b = p->binding_handle;
564 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
565 return false;
568 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
570 test_CloseKey(b, tctx, &new_handle);
572 return ret;
575 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
576 struct torture_context *tctx,
577 struct policy_handle *handle,
578 const struct dom_sid *sid)
580 struct security_descriptor *sd = NULL;
581 int i;
582 uint32_t sec_info = SECINFO_SACL;
584 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
585 return false;
588 if (!sd || !sd->sacl) {
589 return false;
592 for (i = 0; i < sd->sacl->num_aces; i++) {
593 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
594 return true;
598 return false;
601 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
602 struct torture_context *tctx,
603 struct policy_handle *handle,
604 const char *key,
605 const struct dom_sid *sid)
607 struct policy_handle new_handle;
608 bool ret = true;
609 struct dcerpc_binding_handle *b = p->binding_handle;
611 torture_assert(tctx,
612 test_OpenKey_opts(tctx, b, handle, key,
613 REG_OPTION_NON_VOLATILE,
614 SEC_FLAG_SYSTEM_SECURITY,
615 &new_handle,
616 WERR_OK),
617 "failed to open key");
619 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
621 test_CloseKey(b, tctx, &new_handle);
623 return ret;
626 static bool test_owner_present(struct dcerpc_pipe *p,
627 struct torture_context *tctx,
628 struct policy_handle *handle,
629 const struct dom_sid *sid)
631 struct security_descriptor *sd = NULL;
632 uint32_t sec_info = SECINFO_OWNER;
634 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
635 return false;
638 if (!sd || !sd->owner_sid) {
639 return false;
642 return dom_sid_equal(sd->owner_sid, sid);
645 static bool _test_owner_present(struct dcerpc_pipe *p,
646 struct torture_context *tctx,
647 struct policy_handle *handle,
648 const char *key,
649 const struct dom_sid *sid)
651 struct policy_handle new_handle;
652 bool ret = true;
653 struct dcerpc_binding_handle *b = p->binding_handle;
655 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
656 return false;
659 ret = test_owner_present(p, tctx, &new_handle, sid);
661 test_CloseKey(b, tctx, &new_handle);
663 return ret;
666 static bool test_group_present(struct dcerpc_pipe *p,
667 struct torture_context *tctx,
668 struct policy_handle *handle,
669 const struct dom_sid *sid)
671 struct security_descriptor *sd = NULL;
672 uint32_t sec_info = SECINFO_GROUP;
674 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
675 return false;
678 if (!sd || !sd->group_sid) {
679 return false;
682 return dom_sid_equal(sd->group_sid, sid);
685 static bool _test_group_present(struct dcerpc_pipe *p,
686 struct torture_context *tctx,
687 struct policy_handle *handle,
688 const char *key,
689 const struct dom_sid *sid)
691 struct policy_handle new_handle;
692 bool ret = true;
693 struct dcerpc_binding_handle *b = p->binding_handle;
695 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
696 return false;
699 ret = test_group_present(p, tctx, &new_handle, sid);
701 test_CloseKey(b, tctx, &new_handle);
703 return ret;
706 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
707 struct torture_context *tctx,
708 struct policy_handle *handle,
709 const struct dom_sid *sid,
710 uint8_t flags)
712 struct security_descriptor *sd = NULL;
713 int i;
715 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
716 return false;
719 if (!sd || !sd->dacl) {
720 return false;
723 for (i = 0; i < sd->dacl->num_aces; i++) {
724 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
725 (sd->dacl->aces[i].flags == flags)) {
726 return true;
730 return false;
733 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
734 struct torture_context *tctx,
735 struct policy_handle *handle,
736 const struct security_ace *ace)
738 struct security_descriptor *sd = NULL;
739 int i;
741 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
742 return false;
745 if (!sd || !sd->dacl) {
746 return false;
749 for (i = 0; i < sd->dacl->num_aces; i++) {
750 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
751 return true;
755 return false;
758 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
759 struct torture_context *tctx,
760 struct policy_handle *handle,
761 const char *key,
762 struct security_descriptor *sd)
764 struct policy_handle new_handle;
765 bool ret = true;
766 struct dcerpc_binding_handle *b = p->binding_handle;
768 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
769 return false;
772 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
773 ret = false;
776 if (!test_CloseKey(b, tctx, &new_handle)) {
777 ret = false;
780 return ret;
783 static bool test_BackupSecurity(struct dcerpc_pipe *p,
784 struct torture_context *tctx,
785 struct policy_handle *handle,
786 const char *key,
787 struct security_descriptor **sd)
789 struct policy_handle new_handle;
790 bool ret = true;
791 struct dcerpc_binding_handle *b = p->binding_handle;
793 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
794 return false;
797 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
798 ret = false;
801 if (!test_CloseKey(b, tctx, &new_handle)) {
802 ret = false;
805 return ret;
808 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
809 struct torture_context *tctx,
810 struct policy_handle *handle,
811 const char *key)
813 /* get sd
814 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
815 set sd
816 get sd
817 check ace
818 add subkey
819 get sd
820 check ace
821 add subsubkey
822 get sd
823 check ace
824 del subsubkey
825 del subkey
826 reset sd
829 struct security_descriptor *sd = NULL;
830 struct security_descriptor *sd_orig = NULL;
831 struct security_ace *ace = NULL;
832 struct policy_handle new_handle;
833 bool ret = true;
834 struct dcerpc_binding_handle *b = p->binding_handle;
835 const char *test_subkey_sd;
836 const char *test_subsubkey_sd;
838 torture_comment(tctx, "SecurityDescriptor inheritance\n");
840 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
841 return false;
844 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
845 return false;
848 sd_orig = security_descriptor_copy(tctx, sd);
849 if (sd_orig == NULL) {
850 return false;
853 ace = security_ace_create(tctx,
854 TEST_SID,
855 SEC_ACE_TYPE_ACCESS_ALLOWED,
856 SEC_STD_REQUIRED,
857 SEC_ACE_FLAG_CONTAINER_INHERIT);
859 torture_assert_ntstatus_ok(tctx,
860 security_descriptor_dacl_add(sd, ace),
861 "failed to add ace");
863 /* FIXME: add further tests for these flags */
864 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
865 SEC_DESC_SACL_AUTO_INHERITED;
867 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
868 return false;
871 torture_assert(tctx,
872 test_dacl_ace_present(p, tctx, &new_handle, ace),
873 "new ACE not present!");
875 if (!test_CloseKey(b, tctx, &new_handle)) {
876 return false;
879 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
881 if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
882 ret = false;
883 goto out;
886 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
887 ret = false;
888 goto out;
891 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
892 torture_comment(tctx, "inherited ACE not present!\n");
893 ret = false;
894 goto out;
897 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
899 test_CloseKey(b, tctx, &new_handle);
900 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
901 ret = false;
902 goto out;
905 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
906 ret = false;
907 goto out;
910 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
911 torture_comment(tctx, "inherited ACE not present!\n");
912 ret = false;
913 goto out;
916 out:
917 test_CloseKey(b, tctx, &new_handle);
918 test_Cleanup(b, tctx, handle, test_subkey_sd);
919 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
921 return ret;
924 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
925 struct torture_context *tctx,
926 struct policy_handle *handle,
927 const char *key)
929 /* get sd
930 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
931 set sd
932 add subkey/subkey
933 get sd
934 check ace
935 get sd from subkey
936 check ace
937 del subkey/subkey
938 del subkey
939 reset sd
942 struct security_descriptor *sd = NULL;
943 struct security_descriptor *sd_orig = NULL;
944 struct security_ace *ace = NULL;
945 struct policy_handle new_handle;
946 struct dom_sid *sid = NULL;
947 bool ret = true;
948 uint8_t ace_flags = 0x0;
949 struct dcerpc_binding_handle *b = p->binding_handle;
950 const char *test_subkey_sd;
951 const char *test_subsubkey_sd;
953 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
955 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
956 return false;
959 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
960 return false;
963 sd_orig = security_descriptor_copy(tctx, sd);
964 if (sd_orig == NULL) {
965 return false;
968 ace = security_ace_create(tctx,
969 TEST_SID,
970 SEC_ACE_TYPE_ACCESS_ALLOWED,
971 SEC_STD_REQUIRED,
972 SEC_ACE_FLAG_CONTAINER_INHERIT |
973 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
975 torture_assert_ntstatus_ok(tctx,
976 security_descriptor_dacl_add(sd, ace),
977 "failed to add ace");
979 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
980 return false;
983 torture_assert(tctx,
984 test_dacl_ace_present(p, tctx, &new_handle, ace),
985 "new ACE not present!");
987 if (!test_CloseKey(b, tctx, &new_handle)) {
988 return false;
991 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
992 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
994 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
995 return false;
998 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
999 ret = false;
1000 goto out;
1003 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1004 torture_comment(tctx, "inherited ACE present but should not!\n");
1005 ret = false;
1006 goto out;
1009 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1010 if (sid == NULL) {
1011 return false;
1014 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1015 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1016 ret = false;
1017 goto out;
1020 test_CloseKey(b, tctx, &new_handle);
1022 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1023 ret = false;
1024 goto out;
1027 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1028 torture_comment(tctx, "inherited ACE present but should not!\n");
1029 ret = false;
1030 goto out;
1033 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1034 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1035 ace_flags);
1036 ret = false;
1037 goto out;
1040 out:
1041 test_CloseKey(b, tctx, &new_handle);
1042 test_Cleanup(b, tctx, handle, test_subkey_sd);
1043 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1045 return ret;
1048 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1049 struct torture_context *tctx,
1050 struct policy_handle *handle,
1051 const char *key)
1053 bool ret = true;
1054 int i;
1056 struct winreg_mask_result_table {
1057 uint32_t access_mask;
1058 WERROR open_werr;
1059 WERROR get_werr;
1060 WERROR set_werr;
1061 } sd_mask_tests[] = {
1062 { 0,
1063 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1064 { SEC_FLAG_MAXIMUM_ALLOWED,
1065 WERR_OK, WERR_OK, WERR_OK },
1066 { SEC_STD_WRITE_DAC,
1067 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1068 { SEC_FLAG_SYSTEM_SECURITY,
1069 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1072 /* FIXME: before this test can ever run successfully we need a way to
1073 * correctly read a NULL security_descritpor in ndr, get the required
1074 * length, requery, etc.
1077 return true;
1079 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1081 torture_comment(tctx,
1082 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1083 sd_mask_tests[i].access_mask);
1084 torture_comment(tctx,
1085 "expecting: open %s, get: %s, set: %s\n",
1086 win_errstr(sd_mask_tests[i].open_werr),
1087 win_errstr(sd_mask_tests[i].get_werr),
1088 win_errstr(sd_mask_tests[i].set_werr));
1090 if (_test_SecurityDescriptor(p, tctx, handle,
1091 sd_mask_tests[i].access_mask, key,
1092 sd_mask_tests[i].open_werr,
1093 sd_mask_tests[i].get_werr,
1094 sd_mask_tests[i].set_werr)) {
1095 ret = false;
1099 return ret;
1102 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1103 struct torture_context *,
1104 struct policy_handle *,
1105 const char *,
1106 const struct dom_sid *);
1108 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1109 struct torture_context *tctx,
1110 struct policy_handle *handle,
1111 const char *key,
1112 const char *test,
1113 uint32_t access_mask,
1114 uint32_t sec_info,
1115 struct security_descriptor *sd,
1116 WERROR set_werr,
1117 bool expect_present,
1118 bool (*fn) (struct dcerpc_pipe *,
1119 struct torture_context *,
1120 struct policy_handle *,
1121 const char *,
1122 const struct dom_sid *),
1123 const struct dom_sid *sid)
1125 struct policy_handle new_handle;
1126 struct dcerpc_binding_handle *b = p->binding_handle;
1128 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1129 "0x%08x, access_mask: 0x%08x\n",
1130 test, sec_info, access_mask);
1132 torture_assert(tctx,
1133 test_OpenKey_opts(tctx, b, handle, key,
1134 REG_OPTION_NON_VOLATILE,
1135 access_mask,
1136 &new_handle,
1137 WERR_OK),
1138 "failed to open key");
1140 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1142 set_werr)) {
1143 torture_warning(tctx,
1144 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1145 sec_info);
1146 smb_panic("");
1147 test_CloseKey(b, tctx, &new_handle);
1148 return false;
1151 test_CloseKey(b, tctx, &new_handle);
1153 if (W_ERROR_IS_OK(set_werr)) {
1154 bool present;
1155 present = fn(p, tctx, handle, key, sid);
1156 if ((expect_present) && (!present)) {
1157 torture_warning(tctx,
1158 "%s sid is not present!\n",
1159 test);
1160 return false;
1162 if ((!expect_present) && (present)) {
1163 torture_warning(tctx,
1164 "%s sid is present but not expected!\n",
1165 test);
1166 return false;
1170 return true;
1173 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1174 struct torture_context *tctx,
1175 struct policy_handle *handle,
1176 const char *key)
1178 struct security_descriptor *sd_orig = NULL;
1179 struct dom_sid *sid = NULL;
1180 bool ret = true;
1181 int i, a;
1183 struct security_descriptor *sd_owner =
1184 security_descriptor_dacl_create(tctx,
1186 TEST_SID, NULL, NULL);
1188 struct security_descriptor *sd_group =
1189 security_descriptor_dacl_create(tctx,
1191 NULL, TEST_SID, NULL);
1193 struct security_descriptor *sd_dacl =
1194 security_descriptor_dacl_create(tctx,
1196 NULL, NULL,
1197 TEST_SID,
1198 SEC_ACE_TYPE_ACCESS_ALLOWED,
1199 SEC_GENERIC_ALL,
1201 SID_NT_AUTHENTICATED_USERS,
1202 SEC_ACE_TYPE_ACCESS_ALLOWED,
1203 SEC_GENERIC_ALL,
1205 NULL);
1207 struct security_descriptor *sd_sacl =
1208 security_descriptor_sacl_create(tctx,
1210 NULL, NULL,
1211 TEST_SID,
1212 SEC_ACE_TYPE_SYSTEM_AUDIT,
1213 SEC_GENERIC_ALL,
1214 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1215 NULL);
1217 struct winreg_secinfo_table {
1218 struct security_descriptor *sd;
1219 uint32_t sec_info;
1220 WERROR set_werr;
1221 bool sid_present;
1222 secinfo_verify_fn fn;
1225 struct winreg_secinfo_table sec_info_owner_tests[] = {
1226 { sd_owner, 0, WERR_OK,
1227 false, (secinfo_verify_fn)_test_owner_present },
1228 { sd_owner, SECINFO_OWNER, WERR_OK,
1229 true, (secinfo_verify_fn)_test_owner_present },
1230 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1231 { sd_owner, SECINFO_DACL, WERR_OK,
1232 true, (secinfo_verify_fn)_test_owner_present },
1233 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1236 uint32_t sd_owner_good_access_masks[] = {
1237 SEC_FLAG_MAXIMUM_ALLOWED,
1238 /* SEC_STD_WRITE_OWNER, */
1241 struct winreg_secinfo_table sec_info_group_tests[] = {
1242 { sd_group, 0, WERR_OK,
1243 false, (secinfo_verify_fn)_test_group_present },
1244 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1245 { sd_group, SECINFO_GROUP, WERR_OK,
1246 true, (secinfo_verify_fn)_test_group_present },
1247 { sd_group, SECINFO_DACL, WERR_OK,
1248 true, (secinfo_verify_fn)_test_group_present },
1249 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1252 uint32_t sd_group_good_access_masks[] = {
1253 SEC_FLAG_MAXIMUM_ALLOWED,
1256 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1257 { sd_dacl, 0, WERR_OK,
1258 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1259 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1260 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1261 { sd_dacl, SECINFO_DACL, WERR_OK,
1262 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1263 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1266 uint32_t sd_dacl_good_access_masks[] = {
1267 SEC_FLAG_MAXIMUM_ALLOWED,
1268 SEC_STD_WRITE_DAC,
1271 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1272 { sd_sacl, 0, WERR_OK,
1273 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1274 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1275 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1276 { sd_sacl, SECINFO_DACL, WERR_OK,
1277 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1278 { sd_sacl, SECINFO_SACL, WERR_OK,
1279 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1282 uint32_t sd_sacl_good_access_masks[] = {
1283 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1284 /* SEC_FLAG_SYSTEM_SECURITY, */
1287 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1288 if (sid == NULL) {
1289 return false;
1292 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1293 return false;
1296 /* OWNER */
1298 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1300 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1302 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1303 key,
1304 "OWNER",
1305 sd_owner_good_access_masks[a],
1306 sec_info_owner_tests[i].sec_info,
1307 sec_info_owner_tests[i].sd,
1308 sec_info_owner_tests[i].set_werr,
1309 sec_info_owner_tests[i].sid_present,
1310 sec_info_owner_tests[i].fn,
1311 sid))
1313 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1314 ret = false;
1315 goto out;
1320 /* GROUP */
1322 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1324 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1326 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1327 key,
1328 "GROUP",
1329 sd_group_good_access_masks[a],
1330 sec_info_group_tests[i].sec_info,
1331 sec_info_group_tests[i].sd,
1332 sec_info_group_tests[i].set_werr,
1333 sec_info_group_tests[i].sid_present,
1334 sec_info_group_tests[i].fn,
1335 sid))
1337 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1338 ret = false;
1339 goto out;
1344 /* DACL */
1346 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1348 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1350 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1351 key,
1352 "DACL",
1353 sd_dacl_good_access_masks[a],
1354 sec_info_dacl_tests[i].sec_info,
1355 sec_info_dacl_tests[i].sd,
1356 sec_info_dacl_tests[i].set_werr,
1357 sec_info_dacl_tests[i].sid_present,
1358 sec_info_dacl_tests[i].fn,
1359 sid))
1361 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1362 ret = false;
1363 goto out;
1368 /* SACL */
1370 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1372 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1374 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1375 key,
1376 "SACL",
1377 sd_sacl_good_access_masks[a],
1378 sec_info_sacl_tests[i].sec_info,
1379 sec_info_sacl_tests[i].sd,
1380 sec_info_sacl_tests[i].set_werr,
1381 sec_info_sacl_tests[i].sid_present,
1382 sec_info_sacl_tests[i].fn,
1383 sid))
1385 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1386 ret = false;
1387 goto out;
1392 out:
1393 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1395 return ret;
1398 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1399 struct torture_context *tctx,
1400 struct policy_handle *handle,
1401 const char *key)
1403 bool ret = true;
1405 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1406 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1407 ret = false;
1410 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1411 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1412 ret = false;
1415 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1416 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1417 ret = false;
1420 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1421 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1422 ret = false;
1425 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1426 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1427 ret = false;
1430 return ret;
1433 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1434 struct torture_context *tctx,
1435 struct policy_handle *handle,
1436 const char *key,
1437 WERROR expected_result)
1439 struct winreg_DeleteKey r;
1441 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1443 r.in.handle = handle;
1444 init_winreg_String(&r.in.key, key);
1446 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1447 "Delete Key failed");
1448 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1449 "DeleteKey failed");
1451 return true;
1454 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1455 struct torture_context *tctx,
1456 struct policy_handle *handle, const char *key)
1458 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1461 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1462 struct torture_context *tctx,
1463 struct policy_handle *handle, char *kclass)
1465 struct winreg_QueryInfoKey r;
1466 uint32_t num_subkeys, max_subkeylen, max_classlen,
1467 num_values, max_valnamelen, max_valbufsize,
1468 secdescsize;
1469 NTTIME last_changed_time;
1471 ZERO_STRUCT(r);
1472 r.in.handle = handle;
1473 r.out.num_subkeys = &num_subkeys;
1474 r.out.max_subkeylen = &max_subkeylen;
1475 r.out.max_classlen = &max_classlen;
1476 r.out.num_values = &num_values;
1477 r.out.max_valnamelen = &max_valnamelen;
1478 r.out.max_valbufsize = &max_valbufsize;
1479 r.out.secdescsize = &secdescsize;
1480 r.out.last_changed_time = &last_changed_time;
1482 r.out.classname = talloc(tctx, struct winreg_String);
1484 r.in.classname = talloc(tctx, struct winreg_String);
1485 init_winreg_String(r.in.classname, kclass);
1487 torture_assert_ntstatus_ok(tctx,
1488 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1489 "QueryInfoKey failed");
1491 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1493 return true;
1496 static bool test_SetValue(struct dcerpc_binding_handle *b,
1497 struct torture_context *tctx,
1498 struct policy_handle *handle,
1499 const char *value_name,
1500 enum winreg_Type type,
1501 uint8_t *data,
1502 uint32_t size)
1504 struct winreg_SetValue r;
1505 struct winreg_String name;
1507 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1508 value_name, str_regtype(type), size);
1510 init_winreg_String(&name, value_name);
1512 r.in.handle = handle;
1513 r.in.name = name;
1514 r.in.type = type;
1515 r.in.data = data;
1516 r.in.size = size;
1518 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1519 "winreg_SetValue failed");
1520 torture_assert_werr_ok(tctx, r.out.result,
1521 "winreg_SetValue failed");
1523 return true;
1526 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1527 struct torture_context *tctx,
1528 struct policy_handle *handle,
1529 const char *value_name)
1531 struct winreg_DeleteValue r;
1532 struct winreg_String value;
1534 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1536 init_winreg_String(&value, value_name);
1538 r.in.handle = handle;
1539 r.in.value = value;
1541 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1542 "winreg_DeleteValue failed");
1543 torture_assert_werr_ok(tctx, r.out.result,
1544 "winreg_DeleteValue failed");
1546 return true;
1549 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1550 struct policy_handle *handle, int depth,
1551 bool test_security);
1553 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1554 struct policy_handle *handle, int depth,
1555 bool test_security)
1557 struct winreg_EnumKey r;
1558 struct winreg_StringBuf kclass, name;
1559 NTSTATUS status;
1560 NTTIME t = 0;
1561 struct dcerpc_binding_handle *b = p->binding_handle;
1563 kclass.name = "";
1564 kclass.size = 1024;
1566 ZERO_STRUCT(r);
1567 r.in.handle = handle;
1568 r.in.enum_index = 0;
1569 r.in.name = &name;
1570 r.in.keyclass = &kclass;
1571 r.out.name = &name;
1572 r.in.last_changed_time = &t;
1574 do {
1575 name.name = NULL;
1576 name.size = 1024;
1578 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1580 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1581 struct policy_handle key_handle;
1583 torture_comment(tctx, "EnumKey: %d: %s\n",
1584 r.in.enum_index,
1585 r.out.name->name);
1587 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1588 &key_handle)) {
1589 } else {
1590 test_key(p, tctx, &key_handle,
1591 depth + 1, test_security);
1595 r.in.enum_index++;
1597 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1599 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1601 if (!W_ERROR_IS_OK(r.out.result) &&
1602 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1603 torture_fail(tctx, "EnumKey failed");
1606 return true;
1609 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1610 struct torture_context *tctx,
1611 struct policy_handle *handle,
1612 const char *valuename)
1614 struct winreg_QueryMultipleValues r;
1615 uint32_t bufsize=0;
1617 ZERO_STRUCT(r);
1618 r.in.key_handle = handle;
1619 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1620 r.in.values[0].name = talloc(tctx, struct winreg_String);
1621 r.in.values[0].name->name = valuename;
1622 r.in.values[0].offset = 0;
1623 r.in.values[0].length = 0;
1624 r.in.values[0].type = 0;
1626 r.in.num_values = 1;
1627 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1628 *r.in.buffer_size = bufsize;
1629 do {
1630 *r.in.buffer_size = bufsize;
1631 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1632 *r.in.buffer_size);
1634 torture_assert_ntstatus_ok(tctx,
1635 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1636 "QueryMultipleValues failed");
1638 talloc_free(r.in.buffer);
1639 bufsize += 0x20;
1640 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1642 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1644 return true;
1647 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1648 struct torture_context *tctx,
1649 struct policy_handle *handle,
1650 const char *valuename)
1652 struct winreg_QueryValue r;
1653 NTSTATUS status;
1654 enum winreg_Type zero_type = 0;
1655 uint32_t offered = 0xfff;
1656 uint32_t zero = 0;
1658 ZERO_STRUCT(r);
1659 r.in.handle = handle;
1660 r.in.data = NULL;
1661 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1662 r.in.value_name->name = valuename;
1663 r.in.type = &zero_type;
1664 r.in.data_size = &offered;
1665 r.in.data_length = &zero;
1667 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1668 if (NT_STATUS_IS_ERR(status)) {
1669 torture_fail(tctx, "QueryValue failed");
1672 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1674 return true;
1677 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1678 struct torture_context *tctx,
1679 struct policy_handle *handle,
1680 const char *valuename,
1681 bool existing_value)
1683 struct winreg_QueryValue r;
1684 struct winreg_String value_name;
1685 enum winreg_Type type = REG_NONE;
1686 uint32_t data_size = 0;
1687 uint32_t real_data_size = 0;
1688 uint32_t data_length = 0;
1689 uint8_t *data = NULL;
1690 WERROR expected_error = WERR_BADFILE;
1691 const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1693 if (valuename == NULL) {
1694 expected_error = WERR_INVALID_PARAM;
1695 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1698 ZERO_STRUCT(r);
1700 init_winreg_String(&value_name, NULL);
1702 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1704 r.in.handle = handle;
1705 r.in.value_name = &value_name;
1707 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1708 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1709 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1711 init_winreg_String(&value_name, valuename);
1712 r.in.value_name = &value_name;
1714 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1715 "QueryValue failed");
1716 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1717 "expected WERR_INVALID_PARAM for missing type length and size");
1719 r.in.type = &type;
1720 r.out.type = &type;
1721 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1722 "QueryValue failed");
1723 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1724 "expected WERR_INVALID_PARAM for missing length and size");
1726 r.in.data_length = &data_length;
1727 r.out.data_length = &data_length;
1728 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1729 "QueryValue failed");
1730 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1731 "expected WERR_INVALID_PARAM for missing size");
1733 r.in.data_size = &data_size;
1734 r.out.data_size = &data_size;
1735 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1736 "QueryValue failed");
1737 if (existing_value) {
1738 torture_assert_werr_ok(tctx, r.out.result,
1739 "QueryValue failed");
1740 } else {
1741 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1742 errmsg_nonexisting);
1745 real_data_size = *r.out.data_size;
1747 data = talloc_zero_array(tctx, uint8_t, 0);
1748 r.in.data = data;
1749 r.out.data = data;
1750 *r.in.data_size = 0;
1751 *r.out.data_size = 0;
1752 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1753 "QueryValue failed");
1754 if (existing_value) {
1755 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1756 "expected WERR_MORE_DATA for query with too small buffer");
1757 } else {
1758 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1759 errmsg_nonexisting);
1762 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1763 r.in.data = data;
1764 r.out.data = data;
1765 r.in.data_size = &real_data_size;
1766 r.out.data_size = &real_data_size;
1767 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1768 "QueryValue failed");
1769 if (existing_value) {
1770 torture_assert_werr_ok(tctx, r.out.result,
1771 "QueryValue failed");
1772 } else {
1773 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1774 errmsg_nonexisting);
1777 return true;
1780 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1781 struct torture_context *tctx,
1782 struct policy_handle *handle, int max_valnamelen,
1783 int max_valbufsize)
1785 struct winreg_EnumValue r;
1786 enum winreg_Type type = 0;
1787 uint32_t size = max_valbufsize, zero = 0;
1788 bool ret = true;
1789 uint8_t buf8;
1790 struct winreg_ValNameBuf name;
1792 name.name = "";
1793 name.size = 1024;
1795 ZERO_STRUCT(r);
1796 r.in.handle = handle;
1797 r.in.enum_index = 0;
1798 r.in.name = &name;
1799 r.out.name = &name;
1800 r.in.type = &type;
1801 r.in.value = &buf8;
1802 r.in.length = &zero;
1803 r.in.size = &size;
1805 do {
1806 torture_assert_ntstatus_ok(tctx,
1807 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1808 "EnumValue failed");
1810 if (W_ERROR_IS_OK(r.out.result)) {
1811 ret &= test_QueryValue(b, tctx, handle,
1812 r.out.name->name);
1813 ret &= test_QueryMultipleValues(b, tctx, handle,
1814 r.out.name->name);
1817 r.in.enum_index++;
1818 } while (W_ERROR_IS_OK(r.out.result));
1820 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1821 "EnumValue failed");
1823 return ret;
1826 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1827 struct torture_context *tctx)
1829 struct winreg_AbortSystemShutdown r;
1830 uint16_t server = 0x0;
1832 ZERO_STRUCT(r);
1833 r.in.server = &server;
1835 torture_assert_ntstatus_ok(tctx,
1836 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1837 "AbortSystemShutdown failed");
1839 torture_assert_werr_ok(tctx, r.out.result,
1840 "AbortSystemShutdown failed");
1842 return true;
1845 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1846 struct dcerpc_pipe *p)
1848 struct winreg_InitiateSystemShutdown r;
1849 uint16_t hostname = 0x0;
1850 struct dcerpc_binding_handle *b = p->binding_handle;
1852 ZERO_STRUCT(r);
1853 r.in.hostname = &hostname;
1854 r.in.message = talloc(tctx, struct lsa_StringLarge);
1855 init_lsa_StringLarge(r.in.message, "spottyfood");
1856 r.in.force_apps = 1;
1857 r.in.timeout = 30;
1858 r.in.do_reboot = 1;
1860 torture_assert_ntstatus_ok(tctx,
1861 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1862 "InitiateSystemShutdown failed");
1864 torture_assert_werr_ok(tctx, r.out.result,
1865 "InitiateSystemShutdown failed");
1867 return test_AbortSystemShutdown(b, tctx);
1871 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1872 struct dcerpc_pipe *p)
1874 struct winreg_InitiateSystemShutdownEx r;
1875 uint16_t hostname = 0x0;
1876 struct dcerpc_binding_handle *b = p->binding_handle;
1878 ZERO_STRUCT(r);
1879 r.in.hostname = &hostname;
1880 r.in.message = talloc(tctx, struct lsa_StringLarge);
1881 init_lsa_StringLarge(r.in.message, "spottyfood");
1882 r.in.force_apps = 1;
1883 r.in.timeout = 30;
1884 r.in.do_reboot = 1;
1885 r.in.reason = 0;
1887 torture_assert_ntstatus_ok(tctx,
1888 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1889 "InitiateSystemShutdownEx failed");
1891 torture_assert_werr_ok(tctx, r.out.result,
1892 "InitiateSystemShutdownEx failed");
1894 return test_AbortSystemShutdown(b, tctx);
1896 #define MAX_DEPTH 2 /* Only go this far down the tree */
1898 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1899 struct policy_handle *handle, int depth,
1900 bool test_security)
1902 struct dcerpc_binding_handle *b = p->binding_handle;
1904 if (depth == MAX_DEPTH)
1905 return true;
1907 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1910 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1913 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1916 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1919 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1922 test_CloseKey(b, tctx, handle);
1924 return true;
1927 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1928 struct torture_context *tctx,
1929 struct policy_handle *handle)
1931 const char *value_name = TEST_VALUE;
1932 uint32_t value = 0x12345678;
1933 uint64_t value2 = 0x12345678;
1934 const char *string = "torture";
1935 const char *array[2];
1936 DATA_BLOB blob;
1937 enum winreg_Type types[] = {
1938 REG_DWORD,
1939 REG_DWORD_BIG_ENDIAN,
1940 REG_QWORD,
1941 REG_BINARY,
1942 REG_SZ,
1943 REG_MULTI_SZ
1945 int t;
1947 array[0] = "array0";
1948 array[1] = NULL;
1950 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1952 for (t=0; t < ARRAY_SIZE(types); t++) {
1954 enum winreg_Type w_type;
1955 uint32_t w_size, w_length;
1956 uint8_t *w_data;
1958 switch (types[t]) {
1959 case REG_DWORD:
1960 case REG_DWORD_BIG_ENDIAN:
1961 blob = data_blob_talloc_zero(tctx, 4);
1962 SIVAL(blob.data, 0, value);
1963 break;
1964 case REG_QWORD:
1965 blob = data_blob_talloc_zero(tctx, 8);
1966 SBVAL(blob.data, 0, value2);
1967 break;
1968 case REG_BINARY:
1969 blob = data_blob_string_const("binary_blob");
1970 break;
1971 case REG_SZ:
1972 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
1973 break;
1974 case REG_MULTI_SZ:
1975 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
1976 break;
1977 default:
1978 break;
1981 torture_assert(tctx,
1982 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1983 "test_SetValue failed");
1984 torture_assert(tctx,
1985 test_QueryValue_full(b, tctx, handle, value_name, true),
1986 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1987 torture_assert(tctx,
1988 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1989 "test_winreg_QueryValue failed");
1990 torture_assert(tctx,
1991 test_DeleteValue(b, tctx, handle, value_name),
1992 "test_DeleteValue failed");
1994 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1995 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1996 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1997 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2000 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2002 return true;
2005 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2007 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2008 struct torture_context *tctx,
2009 struct policy_handle *handle)
2011 const char *value_name = TEST_VALUE;
2012 enum winreg_Type types[] = {
2013 REG_NONE,
2014 REG_SZ,
2015 REG_EXPAND_SZ,
2016 REG_BINARY,
2017 REG_DWORD,
2018 REG_DWORD_BIG_ENDIAN,
2019 REG_LINK,
2020 REG_MULTI_SZ,
2021 REG_RESOURCE_LIST,
2022 REG_FULL_RESOURCE_DESCRIPTOR,
2023 REG_RESOURCE_REQUIREMENTS_LIST,
2024 REG_QWORD,
2029 123456,
2030 653210,
2031 __LINE__
2033 int t, l;
2035 if (torture_setting_bool(tctx, "samba3", false) ||
2036 torture_setting_bool(tctx, "samba4", false)) {
2037 torture_skip(tctx, "skipping extended SetValue test against Samba");
2040 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2042 for (t=0; t < ARRAY_SIZE(types); t++) {
2043 for (l=0; l < 32; l++) {
2045 enum winreg_Type w_type;
2046 uint32_t w_size, w_length;
2047 uint8_t *w_data;
2049 uint32_t size;
2050 uint8_t *data;
2052 size = l;
2053 data = talloc_array(tctx, uint8_t, size);
2055 generate_random_buffer(data, size);
2057 torture_assert(tctx,
2058 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2059 "test_SetValue failed");
2061 torture_assert(tctx,
2062 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2063 "test_winreg_QueryValue failed");
2065 torture_assert(tctx,
2066 test_DeleteValue(b, tctx, handle, value_name),
2067 "test_DeleteValue failed");
2069 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2070 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2071 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2072 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2076 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2078 return true;
2081 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2082 #define VALUE_CURRENT_VERSION "CurrentVersion"
2084 static bool test_HKLM_wellknown(struct torture_context *tctx,
2085 struct dcerpc_binding_handle *b,
2086 struct policy_handle *handle)
2088 struct policy_handle newhandle;
2090 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2091 if (torture_setting_bool(tctx, "samba3", false)) {
2092 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2093 KEY_CURRENT_VERSION,
2094 REG_OPTION_NON_VOLATILE,
2095 KEY_QUERY_VALUE,
2096 &newhandle,
2097 WERR_OK),
2098 "failed to open current version key");
2099 } else {
2100 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2101 "failed to open current version key");
2104 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2105 "failed to query current version");
2106 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2107 "succeeded to query nonexistent value");
2108 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2109 "succeeded to query value with NULL name");
2110 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2111 "succeeded to query nonexistent default value (\"\")");
2113 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2114 "failed to close current version key");
2116 return true;
2119 static bool test_OpenHive(struct torture_context *tctx,
2120 struct dcerpc_binding_handle *b,
2121 struct policy_handle *handle,
2122 int hkey)
2124 struct winreg_OpenHKLM r;
2126 r.in.system_name = 0;
2127 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2128 r.out.handle = handle;
2130 switch (hkey) {
2131 case HKEY_LOCAL_MACHINE:
2132 torture_assert_ntstatus_ok(tctx,
2133 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2134 "failed to open HKLM");
2135 torture_assert_werr_ok(tctx, r.out.result,
2136 "failed to open HKLM");
2137 break;
2138 case HKEY_CURRENT_USER:
2139 torture_assert_ntstatus_ok(tctx,
2140 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)&r),
2141 "failed to open HKCU");
2142 torture_assert_werr_ok(tctx, r.out.result,
2143 "failed to open HKCU");
2144 break;
2145 case HKEY_USERS:
2146 torture_assert_ntstatus_ok(tctx,
2147 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)&r),
2148 "failed to open HKU");
2149 torture_assert_werr_ok(tctx, r.out.result,
2150 "failed to open HKU");
2151 break;
2152 case HKEY_CLASSES_ROOT:
2153 torture_assert_ntstatus_ok(tctx,
2154 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)&r),
2155 "failed to open HKCR");
2156 torture_assert_werr_ok(tctx, r.out.result,
2157 "failed to open HKCR");
2158 break;
2159 default:
2160 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2161 return false;
2164 return true;
2167 static bool test_volatile_keys(struct torture_context *tctx,
2168 struct dcerpc_binding_handle *b,
2169 struct policy_handle *handle,
2170 int hkey)
2172 struct policy_handle new_handle;
2173 enum winreg_CreateAction action_taken;
2175 torture_comment(tctx, "Testing VOLATILE key\n");
2177 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2179 torture_assert(tctx,
2180 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2181 REG_OPTION_VOLATILE,
2182 SEC_FLAG_MAXIMUM_ALLOWED,
2183 NULL,
2184 WERR_OK,
2185 &action_taken,
2186 &new_handle),
2187 "failed to create REG_OPTION_VOLATILE type key");
2189 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2191 torture_assert(tctx,
2192 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2193 REG_OPTION_NON_VOLATILE,
2194 SEC_FLAG_MAXIMUM_ALLOWED,
2195 NULL,
2196 WERR_CHILD_MUST_BE_VOLATILE,
2197 NULL,
2198 NULL),
2199 "failed to fail create REG_OPTION_VOLATILE type key");
2201 torture_assert(tctx,
2202 test_CloseKey(b, tctx, &new_handle),
2203 "failed to close");
2205 torture_assert(tctx,
2206 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2207 REG_OPTION_NON_VOLATILE,
2208 SEC_FLAG_MAXIMUM_ALLOWED,
2209 &new_handle,
2210 WERR_OK),
2211 "failed to open volatile key");
2213 torture_assert(tctx,
2214 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2215 "failed to delete key");
2217 torture_assert(tctx,
2218 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2219 REG_OPTION_VOLATILE,
2220 SEC_FLAG_MAXIMUM_ALLOWED,
2221 NULL,
2222 WERR_OK,
2223 &action_taken,
2224 &new_handle),
2225 "failed to create REG_OPTION_VOLATILE type key");
2227 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2229 torture_assert(tctx,
2230 test_CloseKey(b, tctx, &new_handle),
2231 "failed to close");
2233 torture_assert(tctx,
2234 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2235 REG_OPTION_VOLATILE,
2236 SEC_FLAG_MAXIMUM_ALLOWED,
2237 &new_handle,
2238 WERR_OK),
2239 "failed to open volatile key");
2241 torture_assert(tctx,
2242 test_CloseKey(b, tctx, &new_handle),
2243 "failed to close");
2245 torture_assert(tctx,
2246 test_CloseKey(b, tctx, handle),
2247 "failed to close");
2249 torture_assert(tctx,
2250 test_OpenHive(tctx, b, handle, hkey),
2251 "failed top open hive");
2253 torture_assert(tctx,
2254 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2255 REG_OPTION_VOLATILE,
2256 SEC_FLAG_MAXIMUM_ALLOWED,
2257 &new_handle,
2258 WERR_BADFILE),
2259 "failed to open volatile key");
2261 torture_assert(tctx,
2262 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2263 REG_OPTION_NON_VOLATILE,
2264 SEC_FLAG_MAXIMUM_ALLOWED,
2265 &new_handle,
2266 WERR_BADFILE),
2267 "failed to open volatile key");
2269 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2271 return true;
2274 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2275 int hkey,
2276 const char *sid_string,
2277 const char *path)
2279 switch (hkey) {
2280 case HKEY_LOCAL_MACHINE:
2281 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2282 case HKEY_CURRENT_USER:
2283 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2284 case HKEY_USERS:
2285 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2286 case HKEY_CLASSES_ROOT:
2287 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2288 default:
2289 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2290 return NULL;
2293 return NULL;
2296 static bool test_symlink_keys(struct torture_context *tctx,
2297 struct dcerpc_binding_handle *b,
2298 struct policy_handle *handle,
2299 int hkey)
2301 struct policy_handle new_handle;
2302 enum winreg_CreateAction action_taken;
2303 DATA_BLOB blob;
2304 /* symlink destination needs to be a kernel mode registry path */
2305 const char *dest = "\\Registry\\MACHINE\\SOFTWARE\\foo";
2307 /* disable until we know how to *not* screw up a windows registry */
2308 torture_skip(tctx, "symlink test disabled");
2310 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2312 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2314 torture_assert(tctx,
2315 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2316 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2317 SEC_FLAG_MAXIMUM_ALLOWED,
2318 NULL,
2319 WERR_OK,
2320 &action_taken,
2321 &new_handle),
2322 "failed to create REG_OPTION_CREATE_LINK type key");
2324 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2326 torture_assert(tctx,
2327 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2328 dest, strlen(dest), /* not NULL terminated */
2329 &blob.data, &blob.length,
2330 false),
2331 "failed to convert");
2333 torture_assert(tctx,
2334 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2335 "failed to create SymbolicLinkValue value");
2337 torture_assert(tctx,
2338 test_CloseKey(b, tctx, &new_handle),
2339 "failed to close");
2341 torture_assert(tctx,
2342 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2343 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2344 SEC_FLAG_MAXIMUM_ALLOWED,
2345 &new_handle,
2346 WERR_OK),
2347 "failed to open symlink key");
2349 torture_assert(tctx,
2350 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK),
2351 "failed to delete key");
2353 return true;
2356 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2357 struct dcerpc_binding_handle *b,
2358 struct policy_handle *handle,
2359 int hkey)
2362 if (torture_setting_bool(tctx, "samba3", false) ||
2363 torture_setting_bool(tctx, "samba4", false)) {
2364 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2367 torture_assert(tctx,
2368 test_volatile_keys(tctx, b, handle, hkey),
2369 "failed to test volatile keys");
2371 torture_assert(tctx,
2372 test_symlink_keys(tctx, b, handle, hkey),
2373 "failed to test symlink keys");
2375 return true;
2378 static bool test_key_base(struct torture_context *tctx,
2379 struct dcerpc_binding_handle *b,
2380 struct policy_handle *handle,
2381 const char *base_key,
2382 int hkey)
2384 struct policy_handle newhandle;
2385 bool ret = true, created = false, deleted = false;
2386 bool created3 = false;
2387 const char *test_key1;
2388 const char *test_key3;
2389 const char *test_subkey;
2391 test_Cleanup(b, tctx, handle, base_key);
2393 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2394 torture_comment(tctx,
2395 "CreateKey(%s) failed\n", base_key);
2398 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2400 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2401 torture_comment(tctx,
2402 "CreateKey failed - not considering a failure\n");
2403 } else {
2404 created = true;
2407 if (created) {
2408 if (!test_FlushKey(b, tctx, handle)) {
2409 torture_comment(tctx, "FlushKey failed\n");
2410 ret = false;
2413 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2414 torture_fail(tctx,
2415 "CreateKey failed (OpenKey after Create didn't work)\n");
2418 if (hkey == HKEY_CURRENT_USER) {
2419 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2420 "simple SetValue test failed");
2421 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2422 "extended SetValue test failed");
2423 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, hkey),
2424 "keytype test failed");
2427 if (!test_CloseKey(b, tctx, &newhandle)) {
2428 torture_fail(tctx,
2429 "CreateKey failed (CloseKey after Open didn't work)\n");
2432 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2433 torture_comment(tctx, "DeleteKey failed\n");
2434 ret = false;
2435 } else {
2436 deleted = true;
2439 if (!test_FlushKey(b, tctx, handle)) {
2440 torture_comment(tctx, "FlushKey failed\n");
2441 ret = false;
2444 if (deleted) {
2445 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2446 REG_OPTION_NON_VOLATILE,
2447 SEC_FLAG_MAXIMUM_ALLOWED,
2448 &newhandle,
2449 WERR_BADFILE)) {
2450 torture_comment(tctx,
2451 "DeleteKey failed (OpenKey after Delete "
2452 "did not return WERR_BADFILE)\n");
2453 ret = false;
2457 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2459 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2460 created3 = true;
2463 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2465 if (created3) {
2466 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2467 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2468 torture_comment(tctx, "DeleteKey failed\n");
2469 ret = false;
2473 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2474 torture_comment(tctx, "DeleteKey failed\n");
2475 ret = false;
2480 test_Cleanup(b, tctx, handle, base_key);
2482 return ret;
2485 static bool test_key_base_sd(struct torture_context *tctx,
2486 struct dcerpc_pipe *p,
2487 struct policy_handle *handle,
2488 const char *base_key)
2490 struct policy_handle newhandle;
2491 bool ret = true, created2 = false, created4 = false;
2492 struct dcerpc_binding_handle *b = p->binding_handle;
2493 const char *test_key2;
2494 const char *test_key4;
2496 torture_skip(tctx, "security descriptor test disabled\n");
2498 if (torture_setting_bool(tctx, "samba3", false) ||
2499 torture_setting_bool(tctx, "samba4", false)) {
2500 torture_skip(tctx, "skipping security descriptor tests against Samba");
2503 test_Cleanup(b, tctx, handle, base_key);
2505 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2506 torture_comment(tctx,
2507 "CreateKey(%s) failed\n", base_key);
2510 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2512 if (test_CreateKey_sd(b, tctx, handle, test_key2,
2513 NULL, &newhandle)) {
2514 created2 = true;
2517 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2518 torture_comment(tctx, "CloseKey failed\n");
2519 ret = false;
2522 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
2524 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
2525 created4 = true;
2528 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2529 torture_comment(tctx, "CloseKey failed\n");
2530 ret = false;
2533 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
2534 ret = false;
2537 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
2538 torture_comment(tctx, "DeleteKey failed\n");
2539 ret = false;
2542 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
2543 torture_comment(tctx, "DeleteKey failed\n");
2544 ret = false;
2547 test_Cleanup(b, tctx, handle, base_key);
2549 return ret;
2552 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2553 void *userdata)
2555 struct policy_handle handle;
2556 bool ret = true;
2557 struct winreg_OpenHKLM r;
2558 struct dcerpc_binding_handle *b = p->binding_handle;
2559 const char *torture_base_key;
2560 int hkey = 0;
2562 winreg_open_fn open_fn = (winreg_open_fn)userdata;
2564 r.in.system_name = 0;
2565 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2566 r.out.handle = &handle;
2568 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2569 "open");
2571 if (!test_GetVersion(b, tctx, &handle)) {
2572 torture_comment(tctx, "GetVersion failed\n");
2573 ret = false;
2576 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
2577 hkey = HKEY_LOCAL_MACHINE;
2578 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
2579 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
2580 hkey = HKEY_USERS;
2581 torture_base_key = TEST_KEY_BASE;
2582 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
2583 hkey = HKEY_CLASSES_ROOT;
2584 torture_base_key = TEST_KEY_BASE;
2585 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
2586 hkey = HKEY_CURRENT_USER;
2587 torture_base_key = TEST_KEY_BASE;
2588 } else {
2589 torture_fail(tctx, "unsupported hkey");
2592 if (hkey == HKEY_LOCAL_MACHINE) {
2593 torture_assert(tctx,
2594 test_HKLM_wellknown(tctx, b, &handle),
2595 "failed to test HKLM wellknown keys");
2598 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
2599 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
2600 torture_base_key);
2601 ret = false;
2604 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
2605 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
2606 torture_base_key);
2607 ret = false;
2610 /* The HKCR hive has a very large fanout */
2611 if (hkey == HKEY_CLASSES_ROOT) {
2612 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2613 ret = false;
2615 } else if (hkey == HKEY_LOCAL_MACHINE) {
2616 /* FIXME we are not allowed to enum values in the HKLM root */
2617 } else {
2618 if (!test_key(p, tctx, &handle, 0, false)) {
2619 ret = false;
2623 return ret;
2626 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2628 struct torture_rpc_tcase *tcase;
2629 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2630 struct torture_test *test;
2632 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2633 &ndr_table_winreg);
2635 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2636 test_InitiateSystemShutdown);
2637 test->dangerous = true;
2639 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2640 test_InitiateSystemShutdownEx);
2641 test->dangerous = true;
2643 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2644 test_Open,
2645 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2646 torture_rpc_tcase_add_test_ex(tcase, "HKU",
2647 test_Open,
2648 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2649 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2650 test_Open,
2651 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2652 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2653 test_Open,
2654 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2656 return suite;