s4-smbtorture: re-arrange tests in RPC-WINREG.
[Samba/nascimento.git] / source4 / torture / rpc / winreg.c
blob2a26bcac52a18c33e0b16d1f06a925a27c2e97e9
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
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/rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "smbtorture test"
32 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
33 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
34 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
35 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
36 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
37 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
38 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\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 enum winreg_KeyType 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_KEYTYPE_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, NULL, 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, NULL, 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, NULL, 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 enum winreg_KeyType 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_KEYTYPE_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_KEYTYPE_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_KEYTYPE_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;
836 torture_comment(tctx, "SecurityDescriptor inheritance\n");
838 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
839 return false;
842 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
843 return false;
846 sd_orig = security_descriptor_copy(tctx, sd);
847 if (sd_orig == NULL) {
848 return false;
851 ace = security_ace_create(tctx,
852 TEST_SID,
853 SEC_ACE_TYPE_ACCESS_ALLOWED,
854 SEC_STD_REQUIRED,
855 SEC_ACE_FLAG_CONTAINER_INHERIT);
857 torture_assert_ntstatus_ok(tctx,
858 security_descriptor_dacl_add(sd, ace),
859 "failed to add ace");
861 /* FIXME: add further tests for these flags */
862 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
863 SEC_DESC_SACL_AUTO_INHERITED;
865 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
866 return false;
869 torture_assert(tctx,
870 test_dacl_ace_present(p, tctx, &new_handle, ace),
871 "new ACE not present!");
873 if (!test_CloseKey(b, tctx, &new_handle)) {
874 return false;
877 if (!test_CreateKey(b, tctx, handle, TEST_SUBKEY_SD, NULL)) {
878 ret = false;
879 goto out;
882 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
883 ret = false;
884 goto out;
887 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
888 torture_comment(tctx, "inherited ACE not present!\n");
889 ret = false;
890 goto out;
893 test_CloseKey(b, tctx, &new_handle);
894 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
895 ret = false;
896 goto out;
899 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
900 ret = false;
901 goto out;
904 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
905 torture_comment(tctx, "inherited ACE not present!\n");
906 ret = false;
907 goto out;
910 out:
911 test_CloseKey(b, tctx, &new_handle);
912 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
913 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
915 return true;
918 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
919 struct torture_context *tctx,
920 struct policy_handle *handle,
921 const char *key)
923 /* get sd
924 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
925 set sd
926 add subkey/subkey
927 get sd
928 check ace
929 get sd from subkey
930 check ace
931 del subkey/subkey
932 del subkey
933 reset sd
936 struct security_descriptor *sd = NULL;
937 struct security_descriptor *sd_orig = NULL;
938 struct security_ace *ace = NULL;
939 struct policy_handle new_handle;
940 struct dom_sid *sid = NULL;
941 bool ret = true;
942 uint8_t ace_flags = 0x0;
943 struct dcerpc_binding_handle *b = p->binding_handle;
945 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
947 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
948 return false;
951 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
952 return false;
955 sd_orig = security_descriptor_copy(tctx, sd);
956 if (sd_orig == NULL) {
957 return false;
960 ace = security_ace_create(tctx,
961 TEST_SID,
962 SEC_ACE_TYPE_ACCESS_ALLOWED,
963 SEC_STD_REQUIRED,
964 SEC_ACE_FLAG_CONTAINER_INHERIT |
965 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
967 torture_assert_ntstatus_ok(tctx,
968 security_descriptor_dacl_add(sd, ace),
969 "failed to add ace");
971 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
972 return false;
975 torture_assert(tctx,
976 test_dacl_ace_present(p, tctx, &new_handle, ace),
977 "new ACE not present!");
979 if (!test_CloseKey(b, tctx, &new_handle)) {
980 return false;
983 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
984 return false;
987 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
988 ret = false;
989 goto out;
992 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
993 torture_comment(tctx, "inherited ACE present but should not!\n");
994 ret = false;
995 goto out;
998 sid = dom_sid_parse_talloc(tctx, TEST_SID);
999 if (sid == NULL) {
1000 return false;
1003 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1004 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1005 ret = false;
1006 goto out;
1009 test_CloseKey(b, tctx, &new_handle);
1011 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
1012 ret = false;
1013 goto out;
1016 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1017 torture_comment(tctx, "inherited ACE present but should not!\n");
1018 ret = false;
1019 goto out;
1022 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1023 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1024 ace_flags);
1025 ret = false;
1026 goto out;
1029 out:
1030 test_CloseKey(b, tctx, &new_handle);
1031 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
1032 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1034 return ret;
1037 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1038 struct torture_context *tctx,
1039 struct policy_handle *handle,
1040 const char *key)
1042 bool ret = true;
1043 int i;
1045 struct winreg_mask_result_table {
1046 uint32_t access_mask;
1047 WERROR open_werr;
1048 WERROR get_werr;
1049 WERROR set_werr;
1050 } sd_mask_tests[] = {
1051 { 0,
1052 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1053 { SEC_FLAG_MAXIMUM_ALLOWED,
1054 WERR_OK, WERR_OK, WERR_OK },
1055 { SEC_STD_WRITE_DAC,
1056 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1057 { SEC_FLAG_SYSTEM_SECURITY,
1058 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1061 /* FIXME: before this test can ever run successfully we need a way to
1062 * correctly read a NULL security_descritpor in ndr, get the required
1063 * length, requery, etc.
1066 return true;
1068 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1070 torture_comment(tctx,
1071 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1072 sd_mask_tests[i].access_mask);
1073 torture_comment(tctx,
1074 "expecting: open %s, get: %s, set: %s\n",
1075 win_errstr(sd_mask_tests[i].open_werr),
1076 win_errstr(sd_mask_tests[i].get_werr),
1077 win_errstr(sd_mask_tests[i].set_werr));
1079 if (_test_SecurityDescriptor(p, tctx, handle,
1080 sd_mask_tests[i].access_mask, key,
1081 sd_mask_tests[i].open_werr,
1082 sd_mask_tests[i].get_werr,
1083 sd_mask_tests[i].set_werr)) {
1084 ret = false;
1088 return ret;
1091 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1092 struct torture_context *,
1093 struct policy_handle *,
1094 const char *,
1095 const struct dom_sid *);
1097 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1098 struct torture_context *tctx,
1099 struct policy_handle *handle,
1100 const char *key,
1101 const char *test,
1102 uint32_t access_mask,
1103 uint32_t sec_info,
1104 struct security_descriptor *sd,
1105 WERROR set_werr,
1106 bool expect_present,
1107 bool (*fn) (struct dcerpc_pipe *,
1108 struct torture_context *,
1109 struct policy_handle *,
1110 const char *,
1111 const struct dom_sid *),
1112 const struct dom_sid *sid)
1114 struct policy_handle new_handle;
1115 struct dcerpc_binding_handle *b = p->binding_handle;
1117 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1118 "0x%08x, access_mask: 0x%08x\n",
1119 test, sec_info, access_mask);
1121 torture_assert(tctx,
1122 test_OpenKey_opts(tctx, b, handle, key,
1123 REG_KEYTYPE_NON_VOLATILE,
1124 access_mask,
1125 &new_handle,
1126 WERR_OK),
1127 "failed to open key");
1129 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1131 set_werr)) {
1132 torture_warning(tctx,
1133 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1134 sec_info);
1135 smb_panic("");
1136 test_CloseKey(b, tctx, &new_handle);
1137 return false;
1140 test_CloseKey(b, tctx, &new_handle);
1142 if (W_ERROR_IS_OK(set_werr)) {
1143 bool present;
1144 present = fn(p, tctx, handle, key, sid);
1145 if ((expect_present) && (!present)) {
1146 torture_warning(tctx,
1147 "%s sid is not present!\n",
1148 test);
1149 return false;
1151 if ((!expect_present) && (present)) {
1152 torture_warning(tctx,
1153 "%s sid is present but not expected!\n",
1154 test);
1155 return false;
1159 return true;
1162 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1163 struct torture_context *tctx,
1164 struct policy_handle *handle,
1165 const char *key)
1167 struct security_descriptor *sd_orig = NULL;
1168 struct dom_sid *sid = NULL;
1169 bool ret = true;
1170 int i, a;
1172 struct security_descriptor *sd_owner =
1173 security_descriptor_dacl_create(tctx,
1175 TEST_SID, NULL, NULL);
1177 struct security_descriptor *sd_group =
1178 security_descriptor_dacl_create(tctx,
1180 NULL, TEST_SID, NULL);
1182 struct security_descriptor *sd_dacl =
1183 security_descriptor_dacl_create(tctx,
1185 NULL, NULL,
1186 TEST_SID,
1187 SEC_ACE_TYPE_ACCESS_ALLOWED,
1188 SEC_GENERIC_ALL,
1190 SID_NT_AUTHENTICATED_USERS,
1191 SEC_ACE_TYPE_ACCESS_ALLOWED,
1192 SEC_GENERIC_ALL,
1194 NULL);
1196 struct security_descriptor *sd_sacl =
1197 security_descriptor_sacl_create(tctx,
1199 NULL, NULL,
1200 TEST_SID,
1201 SEC_ACE_TYPE_SYSTEM_AUDIT,
1202 SEC_GENERIC_ALL,
1203 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1204 NULL);
1206 struct winreg_secinfo_table {
1207 struct security_descriptor *sd;
1208 uint32_t sec_info;
1209 WERROR set_werr;
1210 bool sid_present;
1211 secinfo_verify_fn fn;
1214 struct winreg_secinfo_table sec_info_owner_tests[] = {
1215 { sd_owner, 0, WERR_OK,
1216 false, (secinfo_verify_fn)_test_owner_present },
1217 { sd_owner, SECINFO_OWNER, WERR_OK,
1218 true, (secinfo_verify_fn)_test_owner_present },
1219 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1220 { sd_owner, SECINFO_DACL, WERR_OK,
1221 true, (secinfo_verify_fn)_test_owner_present },
1222 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1225 uint32_t sd_owner_good_access_masks[] = {
1226 SEC_FLAG_MAXIMUM_ALLOWED,
1227 /* SEC_STD_WRITE_OWNER, */
1230 struct winreg_secinfo_table sec_info_group_tests[] = {
1231 { sd_group, 0, WERR_OK,
1232 false, (secinfo_verify_fn)_test_group_present },
1233 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1234 { sd_group, SECINFO_GROUP, WERR_OK,
1235 true, (secinfo_verify_fn)_test_group_present },
1236 { sd_group, SECINFO_DACL, WERR_OK,
1237 true, (secinfo_verify_fn)_test_group_present },
1238 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1241 uint32_t sd_group_good_access_masks[] = {
1242 SEC_FLAG_MAXIMUM_ALLOWED,
1245 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1246 { sd_dacl, 0, WERR_OK,
1247 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1248 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1249 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1250 { sd_dacl, SECINFO_DACL, WERR_OK,
1251 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1252 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1255 uint32_t sd_dacl_good_access_masks[] = {
1256 SEC_FLAG_MAXIMUM_ALLOWED,
1257 SEC_STD_WRITE_DAC,
1260 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1261 { sd_sacl, 0, WERR_OK,
1262 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1263 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1264 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1265 { sd_sacl, SECINFO_DACL, WERR_OK,
1266 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1267 { sd_sacl, SECINFO_SACL, WERR_OK,
1268 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1271 uint32_t sd_sacl_good_access_masks[] = {
1272 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1273 /* SEC_FLAG_SYSTEM_SECURITY, */
1276 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1277 if (sid == NULL) {
1278 return false;
1281 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1282 return false;
1285 /* OWNER */
1287 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1289 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1291 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1292 key,
1293 "OWNER",
1294 sd_owner_good_access_masks[a],
1295 sec_info_owner_tests[i].sec_info,
1296 sec_info_owner_tests[i].sd,
1297 sec_info_owner_tests[i].set_werr,
1298 sec_info_owner_tests[i].sid_present,
1299 sec_info_owner_tests[i].fn,
1300 sid))
1302 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1303 ret = false;
1304 goto out;
1309 /* GROUP */
1311 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1313 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1315 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1316 key,
1317 "GROUP",
1318 sd_group_good_access_masks[a],
1319 sec_info_group_tests[i].sec_info,
1320 sec_info_group_tests[i].sd,
1321 sec_info_group_tests[i].set_werr,
1322 sec_info_group_tests[i].sid_present,
1323 sec_info_group_tests[i].fn,
1324 sid))
1326 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1327 ret = false;
1328 goto out;
1333 /* DACL */
1335 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1337 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1339 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1340 key,
1341 "DACL",
1342 sd_dacl_good_access_masks[a],
1343 sec_info_dacl_tests[i].sec_info,
1344 sec_info_dacl_tests[i].sd,
1345 sec_info_dacl_tests[i].set_werr,
1346 sec_info_dacl_tests[i].sid_present,
1347 sec_info_dacl_tests[i].fn,
1348 sid))
1350 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1351 ret = false;
1352 goto out;
1357 /* SACL */
1359 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1361 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1363 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1364 key,
1365 "SACL",
1366 sd_sacl_good_access_masks[a],
1367 sec_info_sacl_tests[i].sec_info,
1368 sec_info_sacl_tests[i].sd,
1369 sec_info_sacl_tests[i].set_werr,
1370 sec_info_sacl_tests[i].sid_present,
1371 sec_info_sacl_tests[i].fn,
1372 sid))
1374 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1375 ret = false;
1376 goto out;
1381 out:
1382 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1384 return ret;
1387 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1388 struct torture_context *tctx,
1389 struct policy_handle *handle,
1390 const char *key)
1392 bool ret = true;
1394 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1395 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1396 ret = false;
1399 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1400 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1401 ret = false;
1404 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1405 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1406 ret = false;
1409 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1410 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1411 ret = false;
1414 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1415 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1416 ret = false;
1419 return ret;
1422 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1423 struct torture_context *tctx,
1424 struct policy_handle *handle,
1425 const char *key,
1426 WERROR expected_result)
1428 struct winreg_DeleteKey r;
1430 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1432 r.in.handle = handle;
1433 init_winreg_String(&r.in.key, key);
1435 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1436 "Delete Key failed");
1437 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1438 "DeleteKey failed");
1440 return true;
1443 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1444 struct torture_context *tctx,
1445 struct policy_handle *handle, const char *key)
1447 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1450 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1451 struct torture_context *tctx,
1452 struct policy_handle *handle, char *kclass)
1454 struct winreg_QueryInfoKey r;
1455 uint32_t num_subkeys, max_subkeylen, max_classlen,
1456 num_values, max_valnamelen, max_valbufsize,
1457 secdescsize;
1458 NTTIME last_changed_time;
1460 ZERO_STRUCT(r);
1461 r.in.handle = handle;
1462 r.out.num_subkeys = &num_subkeys;
1463 r.out.max_subkeylen = &max_subkeylen;
1464 r.out.max_classlen = &max_classlen;
1465 r.out.num_values = &num_values;
1466 r.out.max_valnamelen = &max_valnamelen;
1467 r.out.max_valbufsize = &max_valbufsize;
1468 r.out.secdescsize = &secdescsize;
1469 r.out.last_changed_time = &last_changed_time;
1471 r.out.classname = talloc(tctx, struct winreg_String);
1473 r.in.classname = talloc(tctx, struct winreg_String);
1474 init_winreg_String(r.in.classname, kclass);
1476 torture_assert_ntstatus_ok(tctx,
1477 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1478 "QueryInfoKey failed");
1480 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1482 return true;
1485 static bool test_SetValue(struct dcerpc_binding_handle *b,
1486 struct torture_context *tctx,
1487 struct policy_handle *handle,
1488 const char *value_name,
1489 enum winreg_Type type,
1490 uint8_t *data,
1491 uint32_t size)
1493 struct winreg_SetValue r;
1494 struct winreg_String name;
1496 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1497 value_name, str_regtype(type), size);
1499 init_winreg_String(&name, value_name);
1501 r.in.handle = handle;
1502 r.in.name = name;
1503 r.in.type = type;
1504 r.in.data = data;
1505 r.in.size = size;
1507 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1508 "winreg_SetValue failed");
1509 torture_assert_werr_ok(tctx, r.out.result,
1510 "winreg_SetValue failed");
1512 return true;
1515 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1516 struct torture_context *tctx,
1517 struct policy_handle *handle,
1518 const char *value_name)
1520 struct winreg_DeleteValue r;
1521 struct winreg_String value;
1523 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1525 init_winreg_String(&value, value_name);
1527 r.in.handle = handle;
1528 r.in.value = value;
1530 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1531 "winreg_DeleteValue failed");
1532 torture_assert_werr_ok(tctx, r.out.result,
1533 "winreg_DeleteValue failed");
1535 return true;
1538 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1539 struct policy_handle *handle, int depth,
1540 bool test_security);
1542 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1543 struct policy_handle *handle, int depth,
1544 bool test_security)
1546 struct winreg_EnumKey r;
1547 struct winreg_StringBuf kclass, name;
1548 NTSTATUS status;
1549 NTTIME t = 0;
1550 struct dcerpc_binding_handle *b = p->binding_handle;
1552 kclass.name = "";
1553 kclass.size = 1024;
1555 ZERO_STRUCT(r);
1556 r.in.handle = handle;
1557 r.in.enum_index = 0;
1558 r.in.name = &name;
1559 r.in.keyclass = &kclass;
1560 r.out.name = &name;
1561 r.in.last_changed_time = &t;
1563 do {
1564 name.name = NULL;
1565 name.size = 1024;
1567 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1569 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1570 struct policy_handle key_handle;
1572 torture_comment(tctx, "EnumKey: %d: %s\n",
1573 r.in.enum_index,
1574 r.out.name->name);
1576 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1577 &key_handle)) {
1578 } else {
1579 test_key(p, tctx, &key_handle,
1580 depth + 1, test_security);
1584 r.in.enum_index++;
1586 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1588 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1590 if (!W_ERROR_IS_OK(r.out.result) &&
1591 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1592 torture_fail(tctx, "EnumKey failed");
1595 return true;
1598 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1599 struct torture_context *tctx,
1600 struct policy_handle *handle,
1601 const char *valuename)
1603 struct winreg_QueryMultipleValues r;
1604 NTSTATUS status;
1605 uint32_t bufsize=0;
1607 ZERO_STRUCT(r);
1608 r.in.key_handle = handle;
1609 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1610 r.in.values[0].name = talloc(tctx, struct winreg_String);
1611 r.in.values[0].name->name = valuename;
1612 r.in.values[0].offset = 0;
1613 r.in.values[0].length = 0;
1614 r.in.values[0].type = 0;
1616 r.in.num_values = 1;
1617 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1618 *r.in.buffer_size = bufsize;
1619 do {
1620 *r.in.buffer_size = bufsize;
1621 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1622 *r.in.buffer_size);
1624 status = dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r);
1626 if(NT_STATUS_IS_ERR(status))
1627 torture_fail(tctx, "QueryMultipleValues failed");
1629 talloc_free(r.in.buffer);
1630 bufsize += 0x20;
1631 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1633 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1635 return true;
1638 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1639 struct torture_context *tctx,
1640 struct policy_handle *handle,
1641 const char *valuename)
1643 struct winreg_QueryValue r;
1644 NTSTATUS status;
1645 enum winreg_Type zero_type = 0;
1646 uint32_t offered = 0xfff;
1647 uint32_t zero = 0;
1649 ZERO_STRUCT(r);
1650 r.in.handle = handle;
1651 r.in.data = NULL;
1652 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1653 r.in.value_name->name = valuename;
1654 r.in.type = &zero_type;
1655 r.in.data_size = &offered;
1656 r.in.data_length = &zero;
1658 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1659 if (NT_STATUS_IS_ERR(status)) {
1660 torture_fail(tctx, "QueryValue failed");
1663 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1665 return true;
1668 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1669 struct torture_context *tctx,
1670 struct policy_handle *handle,
1671 const char *valuename,
1672 bool existing_value)
1674 struct winreg_QueryValue r;
1675 struct winreg_String value_name;
1676 enum winreg_Type type = REG_NONE;
1677 uint32_t data_size = 0;
1678 uint32_t real_data_size = 0;
1679 uint32_t data_length = 0;
1680 uint8_t *data = NULL;
1681 WERROR expected_error = WERR_BADFILE;
1683 if (valuename == NULL) {
1684 expected_error = WERR_INVALID_PARAM;
1687 ZERO_STRUCT(r);
1689 init_winreg_String(&value_name, NULL);
1691 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1693 r.in.handle = handle;
1694 r.in.value_name = &value_name;
1696 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1697 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1698 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1700 init_winreg_String(&value_name, valuename);
1701 r.in.value_name = &value_name;
1703 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1704 "QueryValue failed");
1705 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1706 "QueryValue failed");
1708 r.in.type = &type;
1709 r.out.type = &type;
1710 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1711 "QueryValue failed");
1712 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1713 "QueryValue failed");
1715 r.in.data_length = &data_length;
1716 r.out.data_length = &data_length;
1717 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1718 "QueryValue failed");
1719 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1720 "QueryValue failed");
1722 r.in.data_size = &data_size;
1723 r.out.data_size = &data_size;
1724 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1725 "QueryValue failed");
1726 if (existing_value) {
1727 torture_assert_werr_ok(tctx, r.out.result,
1728 "QueryValue failed");
1729 } else {
1730 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1731 "QueryValue failed");
1734 real_data_size = *r.out.data_size;
1736 data = talloc_zero_array(tctx, uint8_t, 0);
1737 r.in.data = data;
1738 r.out.data = data;
1739 *r.in.data_size = 0;
1740 *r.out.data_size = 0;
1741 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1742 "QueryValue failed");
1743 if (existing_value) {
1744 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1745 "QueryValue failed");
1746 } else {
1747 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1748 "QueryValue failed");
1751 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1752 r.in.data = data;
1753 r.out.data = data;
1754 r.in.data_size = &real_data_size;
1755 r.out.data_size = &real_data_size;
1756 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1757 "QueryValue failed");
1758 if (existing_value) {
1759 torture_assert_werr_ok(tctx, r.out.result,
1760 "QueryValue failed");
1761 } else {
1762 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1763 "QueryValue failed");
1766 return true;
1769 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1770 struct torture_context *tctx,
1771 struct policy_handle *handle, int max_valnamelen,
1772 int max_valbufsize)
1774 struct winreg_EnumValue r;
1775 enum winreg_Type type = 0;
1776 uint32_t size = max_valbufsize, zero = 0;
1777 bool ret = true;
1778 uint8_t buf8;
1779 struct winreg_ValNameBuf name;
1781 name.name = "";
1782 name.size = 1024;
1784 ZERO_STRUCT(r);
1785 r.in.handle = handle;
1786 r.in.enum_index = 0;
1787 r.in.name = &name;
1788 r.out.name = &name;
1789 r.in.type = &type;
1790 r.in.value = &buf8;
1791 r.in.length = &zero;
1792 r.in.size = &size;
1794 do {
1795 torture_assert_ntstatus_ok(tctx,
1796 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1797 "EnumValue failed");
1799 if (W_ERROR_IS_OK(r.out.result)) {
1800 ret &= test_QueryValue(b, tctx, handle,
1801 r.out.name->name);
1802 ret &= test_QueryMultipleValues(b, tctx, handle,
1803 r.out.name->name);
1806 r.in.enum_index++;
1807 } while (W_ERROR_IS_OK(r.out.result));
1809 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1810 "EnumValue failed");
1812 return ret;
1815 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1816 struct torture_context *tctx)
1818 struct winreg_AbortSystemShutdown r;
1819 uint16_t server = 0x0;
1821 ZERO_STRUCT(r);
1822 r.in.server = &server;
1824 torture_assert_ntstatus_ok(tctx,
1825 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1826 "AbortSystemShutdown failed");
1828 torture_assert_werr_ok(tctx, r.out.result,
1829 "AbortSystemShutdown failed");
1831 return true;
1834 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1835 struct dcerpc_pipe *p)
1837 struct winreg_InitiateSystemShutdown r;
1838 uint16_t hostname = 0x0;
1839 struct dcerpc_binding_handle *b = p->binding_handle;
1841 ZERO_STRUCT(r);
1842 r.in.hostname = &hostname;
1843 r.in.message = talloc(tctx, struct lsa_StringLarge);
1844 init_lsa_StringLarge(r.in.message, "spottyfood");
1845 r.in.force_apps = 1;
1846 r.in.timeout = 30;
1847 r.in.do_reboot = 1;
1849 torture_assert_ntstatus_ok(tctx,
1850 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1851 "InitiateSystemShutdown failed");
1853 torture_assert_werr_ok(tctx, r.out.result,
1854 "InitiateSystemShutdown failed");
1856 return test_AbortSystemShutdown(b, tctx);
1860 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1861 struct dcerpc_pipe *p)
1863 struct winreg_InitiateSystemShutdownEx r;
1864 uint16_t hostname = 0x0;
1865 struct dcerpc_binding_handle *b = p->binding_handle;
1867 ZERO_STRUCT(r);
1868 r.in.hostname = &hostname;
1869 r.in.message = talloc(tctx, struct lsa_StringLarge);
1870 init_lsa_StringLarge(r.in.message, "spottyfood");
1871 r.in.force_apps = 1;
1872 r.in.timeout = 30;
1873 r.in.do_reboot = 1;
1874 r.in.reason = 0;
1876 torture_assert_ntstatus_ok(tctx,
1877 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1878 "InitiateSystemShutdownEx failed");
1880 torture_assert_werr_ok(tctx, r.out.result,
1881 "InitiateSystemShutdownEx failed");
1883 return test_AbortSystemShutdown(b, tctx);
1885 #define MAX_DEPTH 2 /* Only go this far down the tree */
1887 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1888 struct policy_handle *handle, int depth,
1889 bool test_security)
1891 struct dcerpc_binding_handle *b = p->binding_handle;
1893 if (depth == MAX_DEPTH)
1894 return true;
1896 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1899 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1902 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1905 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1908 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1911 test_CloseKey(b, tctx, handle);
1913 return true;
1916 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1917 struct torture_context *tctx,
1918 struct policy_handle *handle)
1920 const char *value_name = TEST_VALUE;
1921 uint32_t value = 0x12345678;
1922 const char *string = "torture";
1923 DATA_BLOB blob;
1924 enum winreg_Type types[] = {
1925 REG_DWORD,
1926 REG_BINARY,
1927 REG_SZ,
1928 REG_MULTI_SZ
1930 int t;
1932 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1934 for (t=0; t < ARRAY_SIZE(types); t++) {
1936 enum winreg_Type w_type;
1937 uint32_t w_size, w_length;
1938 uint8_t *w_data;
1940 switch (types[t]) {
1941 case REG_DWORD:
1942 blob = data_blob_talloc_zero(tctx, 4);
1943 SIVAL(blob.data, 0, value);
1944 break;
1945 case REG_BINARY:
1946 blob = data_blob_string_const("binary_blob");
1947 break;
1948 case REG_SZ:
1949 torture_assert(tctx,
1950 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1951 CH_UNIX, CH_UTF16,
1952 string,
1953 strlen(string)+1,
1954 (void **)&blob.data,
1955 &blob.length,
1956 false), "");
1957 break;
1958 case REG_MULTI_SZ:
1959 torture_assert(tctx,
1960 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1961 CH_UNIX, CH_UTF16,
1962 string,
1963 strlen(string)+1,
1964 (void **)&blob.data,
1965 &blob.length,
1966 false), "");
1967 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1968 memset(&blob.data[blob.length - 2], '\0', 2);
1969 break;
1970 default:
1971 break;
1974 torture_assert(tctx,
1975 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1976 "test_SetValue failed");
1977 torture_assert(tctx,
1978 test_QueryValue_full(b, tctx, handle, value_name, true),
1979 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1980 torture_assert(tctx,
1981 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1982 "test_winreg_QueryValue failed");
1983 torture_assert(tctx,
1984 test_DeleteValue(b, tctx, handle, value_name),
1985 "test_DeleteValue failed");
1987 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1988 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1989 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1990 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1993 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
1995 return true;
1998 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2000 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2001 struct torture_context *tctx,
2002 struct policy_handle *handle)
2004 const char *value_name = TEST_VALUE;
2005 enum winreg_Type types[] = {
2006 REG_NONE,
2007 REG_SZ,
2008 REG_EXPAND_SZ,
2009 REG_BINARY,
2010 REG_DWORD,
2011 REG_DWORD_BIG_ENDIAN,
2012 REG_LINK,
2013 REG_MULTI_SZ,
2014 REG_RESOURCE_LIST,
2015 REG_FULL_RESOURCE_DESCRIPTOR,
2016 REG_RESOURCE_REQUIREMENTS_LIST,
2017 REG_QWORD,
2022 123456,
2023 653210,
2024 __LINE__
2026 int t, l;
2028 if (torture_setting_bool(tctx, "samba3", false) ||
2029 torture_setting_bool(tctx, "samba4", false)) {
2030 torture_skip(tctx, "skipping extended SetValue test against Samba");
2033 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2035 for (t=0; t < ARRAY_SIZE(types); t++) {
2036 for (l=0; l < 32; l++) {
2038 enum winreg_Type w_type;
2039 uint32_t w_size, w_length;
2040 uint8_t *w_data;
2042 uint32_t size;
2043 uint8_t *data;
2045 size = l;
2046 data = talloc_array(tctx, uint8_t, size);
2048 generate_random_buffer(data, size);
2050 torture_assert(tctx,
2051 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2052 "test_SetValue failed");
2054 torture_assert(tctx,
2055 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2056 "test_winreg_QueryValue failed");
2058 torture_assert(tctx,
2059 test_DeleteValue(b, tctx, handle, value_name),
2060 "test_DeleteValue failed");
2062 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2063 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2064 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2065 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2069 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2071 return true;
2074 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2075 #define VALUE_CURRENT_VERSION "CurrentVersion"
2077 static bool test_HKLM_wellknown(struct torture_context *tctx,
2078 struct dcerpc_binding_handle *b,
2079 struct policy_handle *handle)
2081 struct policy_handle newhandle;
2083 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2084 if (torture_setting_bool(tctx, "samba3", false)) {
2085 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2086 KEY_CURRENT_VERSION,
2087 REG_KEYTYPE_NON_VOLATILE,
2088 KEY_QUERY_VALUE,
2089 &newhandle,
2090 WERR_OK),
2091 "failed to open current version key");
2092 } else {
2093 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2094 "failed to open current version key");
2097 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2098 "failed to query current version");
2099 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2100 "failed to query current version");
2101 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2102 "test_QueryValue_full for NULL value failed");
2103 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2104 "test_QueryValue_full for \"\" value failed");
2106 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2107 "failed to close current version key");
2109 return true;
2112 static bool test_volatile_keys(struct torture_context *tctx,
2113 struct dcerpc_binding_handle *b,
2114 struct policy_handle *handle)
2116 struct policy_handle new_handle;
2117 enum winreg_CreateAction action_taken;
2119 torture_comment(tctx, "Testing REG_KEYTYPE_VOLATILE key\n");
2121 torture_assert(tctx,
2122 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2123 REG_KEYTYPE_VOLATILE,
2124 SEC_FLAG_MAXIMUM_ALLOWED,
2125 NULL,
2126 WERR_OK,
2127 &action_taken,
2128 &new_handle),
2129 "failed to create REG_KEYTYPE_VOLATILE type key");
2131 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2133 torture_assert(tctx,
2134 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2135 REG_KEYTYPE_NON_VOLATILE,
2136 SEC_FLAG_MAXIMUM_ALLOWED,
2137 NULL,
2138 WERR_CHILD_MUST_BE_VOLATILE,
2139 NULL,
2140 NULL),
2141 "failed to fail create REG_KEYTYPE_VOLATILE type key");
2143 torture_assert(tctx,
2144 test_CloseKey(b, tctx, &new_handle),
2145 "failed to close");
2147 torture_assert(tctx,
2148 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2149 REG_KEYTYPE_NON_VOLATILE,
2150 SEC_FLAG_MAXIMUM_ALLOWED,
2151 &new_handle,
2152 WERR_OK),
2153 "failed to open volatile key");
2155 torture_assert(tctx,
2156 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2157 "failed to delete key");
2159 torture_assert(tctx,
2160 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2161 REG_KEYTYPE_VOLATILE,
2162 SEC_FLAG_MAXIMUM_ALLOWED,
2163 NULL,
2164 WERR_OK,
2165 &action_taken,
2166 &new_handle),
2167 "failed to create REG_KEYTYPE_VOLATILE type key");
2169 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2171 torture_assert(tctx,
2172 test_CloseKey(b, tctx, &new_handle),
2173 "failed to close");
2175 torture_assert(tctx,
2176 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2177 REG_KEYTYPE_VOLATILE,
2178 SEC_FLAG_MAXIMUM_ALLOWED,
2179 &new_handle,
2180 WERR_OK),
2181 "failed to open volatile key");
2183 torture_assert(tctx,
2184 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2185 "failed to delete key");
2187 torture_assert(tctx,
2188 test_CloseKey(b, tctx, &new_handle),
2189 "failed to close");
2191 return true;
2194 static bool test_symlink_keys(struct torture_context *tctx,
2195 struct dcerpc_binding_handle *b,
2196 struct policy_handle *handle)
2198 struct policy_handle new_handle;
2199 enum winreg_CreateAction action_taken;
2201 /* disable until we know how to *not* screw up a windows registry */
2202 torture_skip(tctx, "symlink test disabled");
2204 torture_comment(tctx, "Testing REG_KEYTYPE_SYMLINK key\n");
2206 test_DeleteKey(b, tctx, handle, TEST_KEY_SYMLINK);
2208 torture_assert(tctx,
2209 test_CreateKey_opts(tctx, b, handle, TEST_KEY_SYMLINK, NULL,
2210 REG_KEYTYPE_SYMLINK,
2211 SEC_FLAG_MAXIMUM_ALLOWED,
2212 NULL,
2213 WERR_OK,
2214 &action_taken,
2215 &new_handle),
2216 "failed to create REG_KEYTYPE_SYMLINK type key");
2218 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2220 torture_assert(tctx,
2221 test_CloseKey(b, tctx, &new_handle),
2222 "failed to close");
2224 torture_assert(tctx,
2225 test_OpenKey_opts(tctx, b, handle, TEST_KEY_SYMLINK,
2226 REG_KEYTYPE_SYMLINK,
2227 SEC_FLAG_MAXIMUM_ALLOWED,
2228 &new_handle,
2229 WERR_OK),
2230 "failed to open symlink key");
2232 torture_assert(tctx,
2233 test_DeleteKey(b, tctx, &new_handle, TEST_KEY_SYMLINK),
2234 "failed to delete key");
2236 return true;
2239 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2240 struct dcerpc_binding_handle *b,
2241 struct policy_handle *handle)
2244 if (torture_setting_bool(tctx, "samba3", false) ||
2245 torture_setting_bool(tctx, "samba4", false)) {
2246 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2249 torture_assert(tctx,
2250 test_volatile_keys(tctx, b, handle),
2251 "failed to test volatile keys");
2253 torture_assert(tctx,
2254 test_symlink_keys(tctx, b, handle),
2255 "failed to test symlink keys");
2257 return true;
2260 static bool test_key_base(struct torture_context *tctx,
2261 struct dcerpc_binding_handle *b,
2262 struct policy_handle *handle)
2264 struct policy_handle newhandle;
2265 bool ret = true, created = false, deleted = false;
2266 bool created3 = false;
2268 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2270 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2271 torture_comment(tctx,
2272 "CreateKey (TEST_KEY_BASE) failed\n");
2275 if (!test_CreateKey(b, tctx, handle, TEST_KEY1, NULL)) {
2276 torture_comment(tctx,
2277 "CreateKey failed - not considering a failure\n");
2278 } else {
2279 created = true;
2282 if (created) {
2283 if (!test_FlushKey(b, tctx, handle)) {
2284 torture_comment(tctx, "FlushKey failed\n");
2285 ret = false;
2288 if (!test_OpenKey(b, tctx, handle, TEST_KEY1, &newhandle)) {
2289 torture_fail(tctx,
2290 "CreateKey failed (OpenKey after Create didn't work)\n");
2293 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2294 "simple SetValue test failed");
2295 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2296 "extended SetValue test failed");
2297 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle),
2298 "keytype test failed");
2300 if (!test_CloseKey(b, tctx, &newhandle)) {
2301 torture_fail(tctx,
2302 "CreateKey failed (CloseKey after Open didn't work)\n");
2305 if (!test_DeleteKey(b, tctx, handle, TEST_KEY1)) {
2306 torture_comment(tctx, "DeleteKey failed\n");
2307 ret = false;
2308 } else {
2309 deleted = true;
2312 if (!test_FlushKey(b, tctx, handle)) {
2313 torture_comment(tctx, "FlushKey failed\n");
2314 ret = false;
2317 if (deleted) {
2318 if (!test_OpenKey_opts(tctx, b, handle, TEST_KEY1,
2319 REG_KEYTYPE_NON_VOLATILE,
2320 SEC_FLAG_MAXIMUM_ALLOWED,
2321 &newhandle,
2322 WERR_BADFILE)) {
2323 torture_comment(tctx,
2324 "DeleteKey failed (OpenKey after Delete "
2325 "did not return WERR_BADFILE)\n");
2326 ret = false;
2330 if (test_CreateKey(b, tctx, handle, TEST_KEY3, NULL)) {
2331 created3 = true;
2334 if (created3) {
2335 if (test_CreateKey(b, tctx, handle, TEST_SUBKEY, NULL)) {
2336 if (!test_DeleteKey(b, tctx, handle, TEST_SUBKEY)) {
2337 torture_comment(tctx, "DeleteKey failed\n");
2338 ret = false;
2342 if (!test_DeleteKey(b, tctx, handle, TEST_KEY3)) {
2343 torture_comment(tctx, "DeleteKey failed\n");
2344 ret = false;
2349 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2351 return ret;
2354 static bool test_key_base_sd(struct torture_context *tctx,
2355 struct dcerpc_pipe *p,
2356 struct policy_handle *handle)
2358 struct policy_handle newhandle;
2359 bool ret = true, created2 = false, created4 = false;
2360 struct dcerpc_binding_handle *b = p->binding_handle;
2362 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2364 if (!test_CreateKey(b, tctx, handle, TEST_KEY_BASE, NULL)) {
2365 torture_comment(tctx,
2366 "CreateKey (TEST_KEY_BASE) failed\n");
2369 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY2,
2370 NULL, &newhandle)) {
2371 created2 = true;
2374 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2375 torture_comment(tctx, "CloseKey failed\n");
2376 ret = false;
2379 if (test_CreateKey_sd(b, tctx, handle, TEST_KEY4, NULL, &newhandle)) {
2380 created4 = true;
2383 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2384 torture_comment(tctx, "CloseKey failed\n");
2385 ret = false;
2388 if (created4 && !test_SecurityDescriptors(p, tctx, handle, TEST_KEY4)) {
2389 ret = false;
2392 if (created4 && !test_DeleteKey(b, tctx, handle, TEST_KEY4)) {
2393 torture_comment(tctx, "DeleteKey failed\n");
2394 ret = false;
2397 if (created2 && !test_DeleteKey(b, tctx, handle, TEST_KEY2)) {
2398 torture_comment(tctx, "DeleteKey failed\n");
2399 ret = false;
2402 test_Cleanup(b, tctx, handle, TEST_KEY_BASE);
2404 return ret;
2407 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2408 void *userdata)
2410 struct policy_handle handle;
2411 bool ret = true;
2412 struct winreg_OpenHKLM r;
2413 struct dcerpc_binding_handle *b = p->binding_handle;
2415 winreg_open_fn open_fn = userdata;
2417 r.in.system_name = 0;
2418 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2419 r.out.handle = &handle;
2421 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2422 "open");
2424 if (!test_GetVersion(b, tctx, &handle)) {
2425 torture_comment(tctx, "GetVersion failed\n");
2426 ret = false;
2429 if (open_fn == (void *)dcerpc_winreg_OpenHKLM_r) {
2430 torture_assert(tctx,
2431 test_HKLM_wellknown(tctx, b, &handle),
2432 "failed to test HKLM wellknown keys");
2435 if (!test_key_base(tctx, b, &handle)) {
2436 torture_warning(tctx, "failed to test TEST_KEY_BASE");
2437 ret = false;
2440 if (!test_key_base_sd(tctx, p, &handle)) {
2441 torture_warning(tctx, "failed to test TEST_KEY_BASE sd");
2442 ret = false;
2445 /* The HKCR hive has a very large fanout */
2446 if (open_fn == (void *)dcerpc_winreg_OpenHKCR_r) {
2447 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2448 ret = false;
2450 } else {
2451 if (!test_key(p, tctx, &handle, 0, false)) {
2452 ret = false;
2456 return ret;
2459 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2461 struct torture_rpc_tcase *tcase;
2462 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2463 struct torture_test *test;
2465 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2466 &ndr_table_winreg);
2468 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2469 test_InitiateSystemShutdown);
2470 test->dangerous = true;
2472 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2473 test_InitiateSystemShutdownEx);
2474 test->dangerous = true;
2476 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
2477 test_Open,
2478 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2479 torture_rpc_tcase_add_test_ex(tcase, "HKU",
2480 test_Open,
2481 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2482 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
2483 test_Open,
2484 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2485 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
2486 test_Open,
2487 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2489 return suite;