s4-smbtorture: add test_CreateKey_opts() to RPC-WINREG test.
[Samba/nascimento.git] / source4 / torture / rpc / winreg.c
blobf218258ad543af5b9f0d4583a267cb18de24b63f
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"
41 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
43 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
45 name->string = s;
48 static void init_winreg_String(struct winreg_String *name, const char *s)
50 name->name = s;
51 if (s) {
52 name->name_len = 2 * (strlen_m(s) + 1);
53 name->name_size = name->name_len;
54 } else {
55 name->name_len = 0;
56 name->name_size = 0;
60 static bool test_GetVersion(struct dcerpc_binding_handle *b,
61 struct torture_context *tctx,
62 struct policy_handle *handle)
64 struct winreg_GetVersion r;
65 uint32_t v;
67 ZERO_STRUCT(r);
68 r.in.handle = handle;
69 r.out.version = &v;
71 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
72 "GetVersion failed");
74 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
76 return true;
79 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
80 struct torture_context *tctx,
81 struct policy_handle *handle)
83 struct winreg_NotifyChangeKeyValue r;
85 ZERO_STRUCT(r);
86 r.in.handle = handle;
87 r.in.watch_subtree = true;
88 r.in.notify_filter = 0;
89 r.in.unknown = r.in.unknown2 = 0;
90 init_winreg_String(&r.in.string1, NULL);
91 init_winreg_String(&r.in.string2, NULL);
93 torture_assert_ntstatus_ok(tctx,
94 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
95 "NotifyChangeKeyValue failed");
97 if (!W_ERROR_IS_OK(r.out.result)) {
98 torture_comment(tctx,
99 "NotifyChangeKeyValue failed - %s - not considering\n",
100 win_errstr(r.out.result));
101 return true;
104 return true;
107 static bool test_CreateKey_opts(struct torture_context *tctx,
108 struct dcerpc_binding_handle *b,
109 struct policy_handle *handle,
110 const char *name,
111 const char *kclass,
112 enum winreg_KeyType options,
113 uint32_t access_mask,
114 struct winreg_SecBuf *secdesc,
115 enum winreg_CreateAction *action_taken_p,
116 struct policy_handle *new_handle_p)
118 struct winreg_CreateKey r;
119 struct policy_handle newhandle;
120 enum winreg_CreateAction action_taken = 0;
122 ZERO_STRUCT(r);
123 r.in.handle = handle;
124 init_winreg_String(&r.in.name, name);
125 init_winreg_String(&r.in.keyclass, kclass);
126 r.in.options = options;
127 r.in.access_mask = access_mask;
128 r.in.action_taken = &action_taken;
129 r.in.secdesc = secdesc;
130 r.out.new_handle = &newhandle;
131 r.out.action_taken = &action_taken;
133 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
134 "CreateKey failed");
136 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
138 if (new_handle_p) {
139 *new_handle_p = newhandle;
141 if (action_taken_p) {
142 *action_taken_p = action_taken;
145 return true;
148 static bool test_CreateKey(struct dcerpc_binding_handle *b,
149 struct torture_context *tctx,
150 struct policy_handle *handle, const char *name,
151 const char *kclass)
153 return test_CreateKey_opts(tctx, b, handle, name, kclass,
154 REG_KEYTYPE_NON_VOLATILE,
155 SEC_FLAG_MAXIMUM_ALLOWED,
156 NULL, /* secdesc */
157 NULL, /* action_taken */
158 NULL /* new_handle */);
162 createkey testing with a SD
164 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
165 struct torture_context *tctx,
166 struct policy_handle *handle, const char *name,
167 const char *kclass,
168 struct policy_handle *newhandle)
170 struct winreg_CreateKey r;
171 enum winreg_CreateAction action_taken = 0;
172 struct security_descriptor *sd;
173 DATA_BLOB sdblob;
174 struct winreg_SecBuf secbuf;
176 sd = security_descriptor_dacl_create(tctx,
178 NULL, NULL,
179 SID_NT_AUTHENTICATED_USERS,
180 SEC_ACE_TYPE_ACCESS_ALLOWED,
181 SEC_GENERIC_ALL,
182 SEC_ACE_FLAG_OBJECT_INHERIT |
183 SEC_ACE_FLAG_CONTAINER_INHERIT,
184 NULL);
186 torture_assert_ndr_success(tctx,
187 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
188 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
189 "Failed to push security_descriptor ?!\n");
191 secbuf.sd.data = sdblob.data;
192 secbuf.sd.len = sdblob.length;
193 secbuf.sd.size = sdblob.length;
194 secbuf.length = sdblob.length-10;
195 secbuf.inherit = 0;
197 ZERO_STRUCT(r);
198 r.in.handle = handle;
199 r.out.new_handle = newhandle;
200 init_winreg_String(&r.in.name, name);
201 init_winreg_String(&r.in.keyclass, kclass);
202 r.in.options = 0x0;
203 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
204 r.in.action_taken = r.out.action_taken = &action_taken;
205 r.in.secdesc = &secbuf;
207 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
208 "CreateKey with sd failed");
210 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
212 return true;
215 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
216 struct torture_context *tctx,
217 struct policy_handle *handle,
218 uint32_t *sec_info_ptr,
219 WERROR get_werr,
220 struct security_descriptor **sd_out)
222 struct winreg_GetKeySecurity r;
223 struct security_descriptor *sd = NULL;
224 uint32_t sec_info;
225 DATA_BLOB sdblob;
226 struct dcerpc_binding_handle *b = p->binding_handle;
228 if (sec_info_ptr) {
229 sec_info = *sec_info_ptr;
230 } else {
231 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
234 ZERO_STRUCT(r);
236 r.in.handle = handle;
237 r.in.sec_info = sec_info;
238 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
239 r.in.sd->size = 0x1000;
241 torture_assert_ntstatus_ok(tctx,
242 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
243 "GetKeySecurity failed");
245 torture_assert_werr_equal(tctx, r.out.result, get_werr,
246 "GetKeySecurity failed");
248 sdblob.data = r.out.sd->data;
249 sdblob.length = r.out.sd->len;
251 sd = talloc_zero(tctx, struct security_descriptor);
253 torture_assert_ndr_success(tctx,
254 ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
255 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
256 "pull_security_descriptor failed");
258 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
259 NDR_PRINT_DEBUG(security_descriptor, sd);
262 if (sd_out) {
263 *sd_out = sd;
264 } else {
265 talloc_free(sd);
268 return true;
271 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
272 struct torture_context *tctx,
273 struct policy_handle *handle,
274 struct security_descriptor **sd_out)
276 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
279 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
280 struct torture_context *tctx,
281 struct policy_handle *handle,
282 uint32_t *sec_info_ptr,
283 struct security_descriptor *sd,
284 WERROR werr)
286 struct winreg_SetKeySecurity r;
287 struct KeySecurityData *sdata = NULL;
288 DATA_BLOB sdblob;
289 uint32_t sec_info;
290 struct dcerpc_binding_handle *b = p->binding_handle;
292 ZERO_STRUCT(r);
294 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
295 NDR_PRINT_DEBUG(security_descriptor, sd);
298 torture_assert_ndr_success(tctx,
299 ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
300 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
301 "push_security_descriptor failed");
303 sdata = talloc_zero(tctx, struct KeySecurityData);
304 sdata->data = sdblob.data;
305 sdata->size = sdblob.length;
306 sdata->len = sdblob.length;
308 if (sec_info_ptr) {
309 sec_info = *sec_info_ptr;
310 } else {
311 sec_info = SECINFO_UNPROTECTED_SACL |
312 SECINFO_UNPROTECTED_DACL;
313 if (sd->owner_sid) {
314 sec_info |= SECINFO_OWNER;
316 if (sd->group_sid) {
317 sec_info |= SECINFO_GROUP;
319 if (sd->sacl) {
320 sec_info |= SECINFO_SACL;
322 if (sd->dacl) {
323 sec_info |= SECINFO_DACL;
327 r.in.handle = handle;
328 r.in.sec_info = sec_info;
329 r.in.sd = sdata;
331 torture_assert_ntstatus_ok(tctx,
332 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
333 "SetKeySecurity failed");
335 torture_assert_werr_equal(tctx, r.out.result, werr,
336 "SetKeySecurity failed");
338 return true;
341 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
342 struct torture_context *tctx,
343 struct policy_handle *handle,
344 struct security_descriptor *sd)
346 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
349 static bool test_CloseKey(struct dcerpc_binding_handle *b,
350 struct torture_context *tctx,
351 struct policy_handle *handle)
353 struct winreg_CloseKey r;
355 ZERO_STRUCT(r);
356 r.in.handle = r.out.handle = handle;
358 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
359 "CloseKey failed");
361 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
363 return true;
366 static bool test_FlushKey(struct dcerpc_binding_handle *b,
367 struct torture_context *tctx,
368 struct policy_handle *handle)
370 struct winreg_FlushKey r;
372 ZERO_STRUCT(r);
373 r.in.handle = handle;
375 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
376 "FlushKey failed");
378 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
380 return true;
383 static bool _test_OpenKey(struct dcerpc_binding_handle *b,
384 struct torture_context *tctx,
385 struct policy_handle *hive_handle,
386 const char *keyname, uint32_t access_mask,
387 struct policy_handle *key_handle,
388 WERROR open_werr,
389 bool *success)
391 struct winreg_OpenKey r;
393 ZERO_STRUCT(r);
394 r.in.parent_handle = hive_handle;
395 init_winreg_String(&r.in.keyname, keyname);
396 r.in.options = REG_KEYTYPE_NON_VOLATILE;
397 r.in.access_mask = access_mask;
398 r.out.handle = key_handle;
400 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
401 "OpenKey failed");
403 torture_assert_werr_equal(tctx, r.out.result, open_werr,
404 "OpenKey failed");
406 if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
407 *success = true;
410 return true;
413 static bool test_OpenKey(struct dcerpc_binding_handle *b,
414 struct torture_context *tctx,
415 struct policy_handle *hive_handle,
416 const char *keyname, struct policy_handle *key_handle)
418 return _test_OpenKey(b, tctx, hive_handle, keyname,
419 SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
420 WERR_OK, NULL);
423 static bool test_Cleanup(struct dcerpc_binding_handle *b,
424 struct torture_context *tctx,
425 struct policy_handle *handle, const char *key)
427 struct winreg_DeleteKey r;
429 ZERO_STRUCT(r);
430 r.in.handle = handle;
432 init_winreg_String(&r.in.key, key);
433 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
435 return true;
438 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
439 struct torture_context *tctx,
440 struct policy_handle *handle,
441 WERROR get_werr,
442 WERROR set_werr)
444 struct security_descriptor *sd = NULL;
446 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
447 return false;
450 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
451 return false;
454 return true;
457 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
458 struct torture_context *tctx,
459 struct policy_handle *handle,
460 const char *key)
462 struct policy_handle new_handle;
463 bool ret = true;
464 struct dcerpc_binding_handle *b = p->binding_handle;
466 torture_comment(tctx, "SecurityDescriptor get & set\n");
468 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
469 return false;
472 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
473 WERR_OK, WERR_OK)) {
474 ret = false;
477 if (!test_CloseKey(b, tctx, &new_handle)) {
478 return false;
481 return ret;
484 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
485 struct torture_context *tctx,
486 struct policy_handle *handle,
487 uint32_t access_mask,
488 const char *key,
489 WERROR open_werr,
490 WERROR get_werr,
491 WERROR set_werr)
493 struct policy_handle new_handle;
494 bool ret = true;
495 bool got_key = false;
496 struct dcerpc_binding_handle *b = p->binding_handle;
498 if (!_test_OpenKey(b, tctx, handle, key, access_mask, &new_handle,
499 open_werr, &got_key)) {
500 return false;
503 if (!got_key) {
504 return true;
507 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
508 get_werr, set_werr)) {
509 ret = false;
512 if (!test_CloseKey(b, tctx, &new_handle)) {
513 return false;
516 return ret;
519 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
520 struct torture_context *tctx,
521 struct policy_handle *handle,
522 const struct dom_sid *sid)
524 struct security_descriptor *sd = NULL;
525 int i;
527 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
528 return false;
531 if (!sd || !sd->dacl) {
532 return false;
535 for (i = 0; i < sd->dacl->num_aces; i++) {
536 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
537 return true;
541 return false;
544 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
545 struct torture_context *tctx,
546 struct policy_handle *handle,
547 const char *key,
548 const struct dom_sid *sid)
550 struct policy_handle new_handle;
551 bool ret = true;
552 struct dcerpc_binding_handle *b = p->binding_handle;
554 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
555 return false;
558 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
560 test_CloseKey(b, tctx, &new_handle);
562 return ret;
565 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
566 struct torture_context *tctx,
567 struct policy_handle *handle,
568 const struct dom_sid *sid)
570 struct security_descriptor *sd = NULL;
571 int i;
572 uint32_t sec_info = SECINFO_SACL;
574 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
575 return false;
578 if (!sd || !sd->sacl) {
579 return false;
582 for (i = 0; i < sd->sacl->num_aces; i++) {
583 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
584 return true;
588 return false;
591 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
592 struct torture_context *tctx,
593 struct policy_handle *handle,
594 const char *key,
595 const struct dom_sid *sid)
597 struct policy_handle new_handle;
598 bool ret = true;
599 struct dcerpc_binding_handle *b = p->binding_handle;
601 if (!_test_OpenKey(b, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
602 &new_handle, WERR_OK, NULL)) {
603 return false;
606 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
608 test_CloseKey(b, tctx, &new_handle);
610 return ret;
613 static bool test_owner_present(struct dcerpc_pipe *p,
614 struct torture_context *tctx,
615 struct policy_handle *handle,
616 const struct dom_sid *sid)
618 struct security_descriptor *sd = NULL;
619 uint32_t sec_info = SECINFO_OWNER;
621 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
622 return false;
625 if (!sd || !sd->owner_sid) {
626 return false;
629 return dom_sid_equal(sd->owner_sid, sid);
632 static bool _test_owner_present(struct dcerpc_pipe *p,
633 struct torture_context *tctx,
634 struct policy_handle *handle,
635 const char *key,
636 const struct dom_sid *sid)
638 struct policy_handle new_handle;
639 bool ret = true;
640 struct dcerpc_binding_handle *b = p->binding_handle;
642 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
643 return false;
646 ret = test_owner_present(p, tctx, &new_handle, sid);
648 test_CloseKey(b, tctx, &new_handle);
650 return ret;
653 static bool test_group_present(struct dcerpc_pipe *p,
654 struct torture_context *tctx,
655 struct policy_handle *handle,
656 const struct dom_sid *sid)
658 struct security_descriptor *sd = NULL;
659 uint32_t sec_info = SECINFO_GROUP;
661 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
662 return false;
665 if (!sd || !sd->group_sid) {
666 return false;
669 return dom_sid_equal(sd->group_sid, sid);
672 static bool _test_group_present(struct dcerpc_pipe *p,
673 struct torture_context *tctx,
674 struct policy_handle *handle,
675 const char *key,
676 const struct dom_sid *sid)
678 struct policy_handle new_handle;
679 bool ret = true;
680 struct dcerpc_binding_handle *b = p->binding_handle;
682 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
683 return false;
686 ret = test_group_present(p, tctx, &new_handle, sid);
688 test_CloseKey(b, tctx, &new_handle);
690 return ret;
693 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
694 struct torture_context *tctx,
695 struct policy_handle *handle,
696 const struct dom_sid *sid,
697 uint8_t flags)
699 struct security_descriptor *sd = NULL;
700 int i;
702 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
703 return false;
706 if (!sd || !sd->dacl) {
707 return false;
710 for (i = 0; i < sd->dacl->num_aces; i++) {
711 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
712 (sd->dacl->aces[i].flags == flags)) {
713 return true;
717 return false;
720 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
721 struct torture_context *tctx,
722 struct policy_handle *handle,
723 const struct security_ace *ace)
725 struct security_descriptor *sd = NULL;
726 int i;
728 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
729 return false;
732 if (!sd || !sd->dacl) {
733 return false;
736 for (i = 0; i < sd->dacl->num_aces; i++) {
737 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
738 return true;
742 return false;
745 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
746 struct torture_context *tctx,
747 struct policy_handle *handle,
748 const char *key,
749 struct security_descriptor *sd)
751 struct policy_handle new_handle;
752 bool ret = true;
753 struct dcerpc_binding_handle *b = p->binding_handle;
755 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
756 return false;
759 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
760 ret = false;
763 if (!test_CloseKey(b, tctx, &new_handle)) {
764 ret = false;
767 return ret;
770 static bool test_BackupSecurity(struct dcerpc_pipe *p,
771 struct torture_context *tctx,
772 struct policy_handle *handle,
773 const char *key,
774 struct security_descriptor **sd)
776 struct policy_handle new_handle;
777 bool ret = true;
778 struct dcerpc_binding_handle *b = p->binding_handle;
780 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
781 return false;
784 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
785 ret = false;
788 if (!test_CloseKey(b, tctx, &new_handle)) {
789 ret = false;
792 return ret;
795 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
796 struct torture_context *tctx,
797 struct policy_handle *handle,
798 const char *key)
800 /* get sd
801 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
802 set sd
803 get sd
804 check ace
805 add subkey
806 get sd
807 check ace
808 add subsubkey
809 get sd
810 check ace
811 del subsubkey
812 del subkey
813 reset sd
816 struct security_descriptor *sd = NULL;
817 struct security_descriptor *sd_orig = NULL;
818 struct security_ace *ace = NULL;
819 struct policy_handle new_handle;
820 bool ret = true;
821 struct dcerpc_binding_handle *b = p->binding_handle;
823 torture_comment(tctx, "SecurityDescriptor inheritance\n");
825 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
826 return false;
829 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
830 return false;
833 sd_orig = security_descriptor_copy(tctx, sd);
834 if (sd_orig == NULL) {
835 return false;
838 ace = security_ace_create(tctx,
839 TEST_SID,
840 SEC_ACE_TYPE_ACCESS_ALLOWED,
841 SEC_STD_REQUIRED,
842 SEC_ACE_FLAG_CONTAINER_INHERIT);
844 torture_assert_ntstatus_ok(tctx,
845 security_descriptor_dacl_add(sd, ace),
846 "failed to add ace");
848 /* FIXME: add further tests for these flags */
849 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
850 SEC_DESC_SACL_AUTO_INHERITED;
852 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
853 return false;
856 torture_assert(tctx,
857 test_dacl_ace_present(p, tctx, &new_handle, ace),
858 "new ACE not present!");
860 if (!test_CloseKey(b, tctx, &new_handle)) {
861 return false;
864 if (!test_CreateKey(b, tctx, handle, TEST_SUBKEY_SD, NULL)) {
865 ret = false;
866 goto out;
869 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
870 ret = false;
871 goto out;
874 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
875 torture_comment(tctx, "inherited ACE not present!\n");
876 ret = false;
877 goto out;
880 test_CloseKey(b, tctx, &new_handle);
881 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
882 ret = false;
883 goto out;
886 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_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 out:
898 test_CloseKey(b, tctx, &new_handle);
899 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
900 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
902 return true;
905 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
906 struct torture_context *tctx,
907 struct policy_handle *handle,
908 const char *key)
910 /* get sd
911 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
912 set sd
913 add subkey/subkey
914 get sd
915 check ace
916 get sd from subkey
917 check ace
918 del subkey/subkey
919 del subkey
920 reset sd
923 struct security_descriptor *sd = NULL;
924 struct security_descriptor *sd_orig = NULL;
925 struct security_ace *ace = NULL;
926 struct policy_handle new_handle;
927 struct dom_sid *sid = NULL;
928 bool ret = true;
929 uint8_t ace_flags = 0x0;
930 struct dcerpc_binding_handle *b = p->binding_handle;
932 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
934 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
935 return false;
938 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
939 return false;
942 sd_orig = security_descriptor_copy(tctx, sd);
943 if (sd_orig == NULL) {
944 return false;
947 ace = security_ace_create(tctx,
948 TEST_SID,
949 SEC_ACE_TYPE_ACCESS_ALLOWED,
950 SEC_STD_REQUIRED,
951 SEC_ACE_FLAG_CONTAINER_INHERIT |
952 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
954 torture_assert_ntstatus_ok(tctx,
955 security_descriptor_dacl_add(sd, ace),
956 "failed to add ace");
958 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
959 return false;
962 torture_assert(tctx,
963 test_dacl_ace_present(p, tctx, &new_handle, ace),
964 "new ACE not present!");
966 if (!test_CloseKey(b, tctx, &new_handle)) {
967 return false;
970 if (!test_CreateKey(b, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
971 return false;
974 if (!test_OpenKey(b, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
975 ret = false;
976 goto out;
979 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
980 torture_comment(tctx, "inherited ACE present but should not!\n");
981 ret = false;
982 goto out;
985 sid = dom_sid_parse_talloc(tctx, TEST_SID);
986 if (sid == NULL) {
987 return false;
990 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
991 torture_comment(tctx, "inherited trustee SID present but should not!\n");
992 ret = false;
993 goto out;
996 test_CloseKey(b, tctx, &new_handle);
998 if (!test_OpenKey(b, tctx, handle, TEST_SUBKEY_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 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1010 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1011 ace_flags);
1012 ret = false;
1013 goto out;
1016 out:
1017 test_CloseKey(b, tctx, &new_handle);
1018 test_Cleanup(b, tctx, handle, TEST_SUBKEY_SD);
1019 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1021 return ret;
1024 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1025 struct torture_context *tctx,
1026 struct policy_handle *handle,
1027 const char *key)
1029 bool ret = true;
1030 int i;
1032 struct winreg_mask_result_table {
1033 uint32_t access_mask;
1034 WERROR open_werr;
1035 WERROR get_werr;
1036 WERROR set_werr;
1037 } sd_mask_tests[] = {
1038 { 0,
1039 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1040 { SEC_FLAG_MAXIMUM_ALLOWED,
1041 WERR_OK, WERR_OK, WERR_OK },
1042 { SEC_STD_WRITE_DAC,
1043 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1044 { SEC_FLAG_SYSTEM_SECURITY,
1045 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1048 /* FIXME: before this test can ever run successfully we need a way to
1049 * correctly read a NULL security_descritpor in ndr, get the required
1050 * length, requery, etc.
1053 return true;
1055 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1057 torture_comment(tctx,
1058 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1059 sd_mask_tests[i].access_mask);
1060 torture_comment(tctx,
1061 "expecting: open %s, get: %s, set: %s\n",
1062 win_errstr(sd_mask_tests[i].open_werr),
1063 win_errstr(sd_mask_tests[i].get_werr),
1064 win_errstr(sd_mask_tests[i].set_werr));
1066 if (_test_SecurityDescriptor(p, tctx, handle,
1067 sd_mask_tests[i].access_mask, key,
1068 sd_mask_tests[i].open_werr,
1069 sd_mask_tests[i].get_werr,
1070 sd_mask_tests[i].set_werr)) {
1071 ret = false;
1075 return ret;
1078 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1079 struct torture_context *,
1080 struct policy_handle *,
1081 const char *,
1082 const struct dom_sid *);
1084 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1085 struct torture_context *tctx,
1086 struct policy_handle *handle,
1087 const char *key,
1088 const char *test,
1089 uint32_t access_mask,
1090 uint32_t sec_info,
1091 struct security_descriptor *sd,
1092 WERROR set_werr,
1093 bool expect_present,
1094 bool (*fn) (struct dcerpc_pipe *,
1095 struct torture_context *,
1096 struct policy_handle *,
1097 const char *,
1098 const struct dom_sid *),
1099 const struct dom_sid *sid)
1101 struct policy_handle new_handle;
1102 bool open_success = false;
1103 struct dcerpc_binding_handle *b = p->binding_handle;
1105 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1106 "0x%08x, access_mask: 0x%08x\n",
1107 test, sec_info, access_mask);
1109 if (!_test_OpenKey(b, tctx, handle, key,
1110 access_mask,
1111 &new_handle,
1112 WERR_OK,
1113 &open_success)) {
1114 return false;
1117 if (!open_success) {
1118 torture_comment(tctx, "key did not open\n");
1119 test_CloseKey(b, tctx, &new_handle);
1120 return false;
1123 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1125 set_werr)) {
1126 torture_warning(tctx,
1127 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1128 sec_info);
1129 smb_panic("");
1130 test_CloseKey(b, tctx, &new_handle);
1131 return false;
1134 test_CloseKey(b, tctx, &new_handle);
1136 if (W_ERROR_IS_OK(set_werr)) {
1137 bool present;
1138 present = fn(p, tctx, handle, key, sid);
1139 if ((expect_present) && (!present)) {
1140 torture_warning(tctx,
1141 "%s sid is not present!\n",
1142 test);
1143 return false;
1145 if ((!expect_present) && (present)) {
1146 torture_warning(tctx,
1147 "%s sid is present but not expected!\n",
1148 test);
1149 return false;
1153 return true;
1156 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1157 struct torture_context *tctx,
1158 struct policy_handle *handle,
1159 const char *key)
1161 struct security_descriptor *sd_orig = NULL;
1162 struct dom_sid *sid = NULL;
1163 bool ret = true;
1164 int i, a;
1166 struct security_descriptor *sd_owner =
1167 security_descriptor_dacl_create(tctx,
1169 TEST_SID, NULL, NULL);
1171 struct security_descriptor *sd_group =
1172 security_descriptor_dacl_create(tctx,
1174 NULL, TEST_SID, NULL);
1176 struct security_descriptor *sd_dacl =
1177 security_descriptor_dacl_create(tctx,
1179 NULL, NULL,
1180 TEST_SID,
1181 SEC_ACE_TYPE_ACCESS_ALLOWED,
1182 SEC_GENERIC_ALL,
1184 SID_NT_AUTHENTICATED_USERS,
1185 SEC_ACE_TYPE_ACCESS_ALLOWED,
1186 SEC_GENERIC_ALL,
1188 NULL);
1190 struct security_descriptor *sd_sacl =
1191 security_descriptor_sacl_create(tctx,
1193 NULL, NULL,
1194 TEST_SID,
1195 SEC_ACE_TYPE_SYSTEM_AUDIT,
1196 SEC_GENERIC_ALL,
1197 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1198 NULL);
1200 struct winreg_secinfo_table {
1201 struct security_descriptor *sd;
1202 uint32_t sec_info;
1203 WERROR set_werr;
1204 bool sid_present;
1205 secinfo_verify_fn fn;
1208 struct winreg_secinfo_table sec_info_owner_tests[] = {
1209 { sd_owner, 0, WERR_OK,
1210 false, (secinfo_verify_fn)_test_owner_present },
1211 { sd_owner, SECINFO_OWNER, WERR_OK,
1212 true, (secinfo_verify_fn)_test_owner_present },
1213 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1214 { sd_owner, SECINFO_DACL, WERR_OK,
1215 true, (secinfo_verify_fn)_test_owner_present },
1216 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1219 uint32_t sd_owner_good_access_masks[] = {
1220 SEC_FLAG_MAXIMUM_ALLOWED,
1221 /* SEC_STD_WRITE_OWNER, */
1224 struct winreg_secinfo_table sec_info_group_tests[] = {
1225 { sd_group, 0, WERR_OK,
1226 false, (secinfo_verify_fn)_test_group_present },
1227 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1228 { sd_group, SECINFO_GROUP, WERR_OK,
1229 true, (secinfo_verify_fn)_test_group_present },
1230 { sd_group, SECINFO_DACL, WERR_OK,
1231 true, (secinfo_verify_fn)_test_group_present },
1232 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1235 uint32_t sd_group_good_access_masks[] = {
1236 SEC_FLAG_MAXIMUM_ALLOWED,
1239 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1240 { sd_dacl, 0, WERR_OK,
1241 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1242 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1243 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1244 { sd_dacl, SECINFO_DACL, WERR_OK,
1245 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1246 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1249 uint32_t sd_dacl_good_access_masks[] = {
1250 SEC_FLAG_MAXIMUM_ALLOWED,
1251 SEC_STD_WRITE_DAC,
1254 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1255 { sd_sacl, 0, WERR_OK,
1256 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1257 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1258 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1259 { sd_sacl, SECINFO_DACL, WERR_OK,
1260 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1261 { sd_sacl, SECINFO_SACL, WERR_OK,
1262 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1265 uint32_t sd_sacl_good_access_masks[] = {
1266 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1267 /* SEC_FLAG_SYSTEM_SECURITY, */
1270 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1271 if (sid == NULL) {
1272 return false;
1275 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1276 return false;
1279 /* OWNER */
1281 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1283 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1285 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1286 key,
1287 "OWNER",
1288 sd_owner_good_access_masks[a],
1289 sec_info_owner_tests[i].sec_info,
1290 sec_info_owner_tests[i].sd,
1291 sec_info_owner_tests[i].set_werr,
1292 sec_info_owner_tests[i].sid_present,
1293 sec_info_owner_tests[i].fn,
1294 sid))
1296 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1297 ret = false;
1298 goto out;
1303 /* GROUP */
1305 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1307 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1309 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1310 key,
1311 "GROUP",
1312 sd_group_good_access_masks[a],
1313 sec_info_group_tests[i].sec_info,
1314 sec_info_group_tests[i].sd,
1315 sec_info_group_tests[i].set_werr,
1316 sec_info_group_tests[i].sid_present,
1317 sec_info_group_tests[i].fn,
1318 sid))
1320 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1321 ret = false;
1322 goto out;
1327 /* DACL */
1329 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1331 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1333 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1334 key,
1335 "DACL",
1336 sd_dacl_good_access_masks[a],
1337 sec_info_dacl_tests[i].sec_info,
1338 sec_info_dacl_tests[i].sd,
1339 sec_info_dacl_tests[i].set_werr,
1340 sec_info_dacl_tests[i].sid_present,
1341 sec_info_dacl_tests[i].fn,
1342 sid))
1344 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1345 ret = false;
1346 goto out;
1351 /* SACL */
1353 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1355 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1357 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1358 key,
1359 "SACL",
1360 sd_sacl_good_access_masks[a],
1361 sec_info_sacl_tests[i].sec_info,
1362 sec_info_sacl_tests[i].sd,
1363 sec_info_sacl_tests[i].set_werr,
1364 sec_info_sacl_tests[i].sid_present,
1365 sec_info_sacl_tests[i].fn,
1366 sid))
1368 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1369 ret = false;
1370 goto out;
1375 out:
1376 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1378 return ret;
1381 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1382 struct torture_context *tctx,
1383 struct policy_handle *handle,
1384 const char *key)
1386 bool ret = true;
1388 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1389 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1390 ret = false;
1393 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1394 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1395 ret = false;
1398 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1399 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1400 ret = false;
1403 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1404 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1405 ret = false;
1408 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1409 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1410 ret = false;
1413 return ret;
1416 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1417 struct torture_context *tctx,
1418 struct policy_handle *handle, const char *key)
1420 NTSTATUS status;
1421 struct winreg_DeleteKey r;
1423 r.in.handle = handle;
1424 init_winreg_String(&r.in.key, key);
1426 status = dcerpc_winreg_DeleteKey_r(b, tctx, &r);
1428 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1429 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1431 return true;
1434 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1435 struct torture_context *tctx,
1436 struct policy_handle *handle, char *kclass)
1438 struct winreg_QueryInfoKey r;
1439 uint32_t num_subkeys, max_subkeylen, max_classlen,
1440 num_values, max_valnamelen, max_valbufsize,
1441 secdescsize;
1442 NTTIME last_changed_time;
1444 ZERO_STRUCT(r);
1445 r.in.handle = handle;
1446 r.out.num_subkeys = &num_subkeys;
1447 r.out.max_subkeylen = &max_subkeylen;
1448 r.out.max_classlen = &max_classlen;
1449 r.out.num_values = &num_values;
1450 r.out.max_valnamelen = &max_valnamelen;
1451 r.out.max_valbufsize = &max_valbufsize;
1452 r.out.secdescsize = &secdescsize;
1453 r.out.last_changed_time = &last_changed_time;
1455 r.out.classname = talloc(tctx, struct winreg_String);
1457 r.in.classname = talloc(tctx, struct winreg_String);
1458 init_winreg_String(r.in.classname, kclass);
1460 torture_assert_ntstatus_ok(tctx,
1461 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1462 "QueryInfoKey failed");
1464 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1466 return true;
1469 static bool test_SetValue(struct dcerpc_binding_handle *b,
1470 struct torture_context *tctx,
1471 struct policy_handle *handle,
1472 const char *value_name,
1473 enum winreg_Type type,
1474 uint8_t *data,
1475 uint32_t size)
1477 struct winreg_SetValue r;
1478 struct winreg_String name;
1480 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1481 value_name, str_regtype(type), size);
1483 init_winreg_String(&name, value_name);
1485 r.in.handle = handle;
1486 r.in.name = name;
1487 r.in.type = type;
1488 r.in.data = data;
1489 r.in.size = size;
1491 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1492 "winreg_SetValue failed");
1493 torture_assert_werr_ok(tctx, r.out.result,
1494 "winreg_SetValue failed");
1496 return true;
1499 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1500 struct torture_context *tctx,
1501 struct policy_handle *handle,
1502 const char *value_name)
1504 struct winreg_DeleteValue r;
1505 struct winreg_String value;
1507 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1509 init_winreg_String(&value, value_name);
1511 r.in.handle = handle;
1512 r.in.value = value;
1514 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1515 "winreg_DeleteValue failed");
1516 torture_assert_werr_ok(tctx, r.out.result,
1517 "winreg_DeleteValue failed");
1519 return true;
1522 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1523 struct policy_handle *handle, int depth,
1524 bool test_security);
1526 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1527 struct policy_handle *handle, int depth,
1528 bool test_security)
1530 struct winreg_EnumKey r;
1531 struct winreg_StringBuf kclass, name;
1532 NTSTATUS status;
1533 NTTIME t = 0;
1534 struct dcerpc_binding_handle *b = p->binding_handle;
1536 kclass.name = "";
1537 kclass.size = 1024;
1539 ZERO_STRUCT(r);
1540 r.in.handle = handle;
1541 r.in.enum_index = 0;
1542 r.in.name = &name;
1543 r.in.keyclass = &kclass;
1544 r.out.name = &name;
1545 r.in.last_changed_time = &t;
1547 do {
1548 name.name = NULL;
1549 name.size = 1024;
1551 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1553 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1554 struct policy_handle key_handle;
1556 torture_comment(tctx, "EnumKey: %d: %s\n",
1557 r.in.enum_index,
1558 r.out.name->name);
1560 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1561 &key_handle)) {
1562 } else {
1563 test_key(p, tctx, &key_handle,
1564 depth + 1, test_security);
1568 r.in.enum_index++;
1570 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1572 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1574 if (!W_ERROR_IS_OK(r.out.result) &&
1575 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1576 torture_fail(tctx, "EnumKey failed");
1579 return true;
1582 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1583 struct torture_context *tctx,
1584 struct policy_handle *handle,
1585 const char *valuename)
1587 struct winreg_QueryMultipleValues r;
1588 NTSTATUS status;
1589 uint32_t bufsize=0;
1591 ZERO_STRUCT(r);
1592 r.in.key_handle = handle;
1593 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1594 r.in.values[0].name = talloc(tctx, struct winreg_String);
1595 r.in.values[0].name->name = valuename;
1596 r.in.values[0].offset = 0;
1597 r.in.values[0].length = 0;
1598 r.in.values[0].type = 0;
1600 r.in.num_values = 1;
1601 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1602 *r.in.buffer_size = bufsize;
1603 do {
1604 *r.in.buffer_size = bufsize;
1605 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1606 *r.in.buffer_size);
1608 status = dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r);
1610 if(NT_STATUS_IS_ERR(status))
1611 torture_fail(tctx, "QueryMultipleValues failed");
1613 talloc_free(r.in.buffer);
1614 bufsize += 0x20;
1615 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1617 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1619 return true;
1622 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1623 struct torture_context *tctx,
1624 struct policy_handle *handle,
1625 const char *valuename)
1627 struct winreg_QueryValue r;
1628 NTSTATUS status;
1629 enum winreg_Type zero_type = 0;
1630 uint32_t offered = 0xfff;
1631 uint32_t zero = 0;
1633 ZERO_STRUCT(r);
1634 r.in.handle = handle;
1635 r.in.data = NULL;
1636 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1637 r.in.value_name->name = valuename;
1638 r.in.type = &zero_type;
1639 r.in.data_size = &offered;
1640 r.in.data_length = &zero;
1642 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1643 if (NT_STATUS_IS_ERR(status)) {
1644 torture_fail(tctx, "QueryValue failed");
1647 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1649 return true;
1652 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1653 struct torture_context *tctx,
1654 struct policy_handle *handle,
1655 const char *valuename,
1656 bool existing_value)
1658 struct winreg_QueryValue r;
1659 struct winreg_String value_name;
1660 enum winreg_Type type = REG_NONE;
1661 uint32_t data_size = 0;
1662 uint32_t real_data_size = 0;
1663 uint32_t data_length = 0;
1664 uint8_t *data = NULL;
1665 WERROR expected_error = WERR_BADFILE;
1667 if (valuename == NULL) {
1668 expected_error = WERR_INVALID_PARAM;
1671 ZERO_STRUCT(r);
1673 init_winreg_String(&value_name, NULL);
1675 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1677 r.in.handle = handle;
1678 r.in.value_name = &value_name;
1680 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1681 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1682 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1684 init_winreg_String(&value_name, valuename);
1685 r.in.value_name = &value_name;
1687 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1688 "QueryValue failed");
1689 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1690 "QueryValue failed");
1692 r.in.type = &type;
1693 r.out.type = &type;
1694 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1695 "QueryValue failed");
1696 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1697 "QueryValue failed");
1699 r.in.data_length = &data_length;
1700 r.out.data_length = &data_length;
1701 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1702 "QueryValue failed");
1703 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1704 "QueryValue failed");
1706 r.in.data_size = &data_size;
1707 r.out.data_size = &data_size;
1708 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1709 "QueryValue failed");
1710 if (existing_value) {
1711 torture_assert_werr_ok(tctx, r.out.result,
1712 "QueryValue failed");
1713 } else {
1714 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1715 "QueryValue failed");
1718 real_data_size = *r.out.data_size;
1720 data = talloc_zero_array(tctx, uint8_t, 0);
1721 r.in.data = data;
1722 r.out.data = data;
1723 *r.in.data_size = 0;
1724 *r.out.data_size = 0;
1725 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1726 "QueryValue failed");
1727 if (existing_value) {
1728 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1729 "QueryValue failed");
1730 } else {
1731 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1732 "QueryValue failed");
1735 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1736 r.in.data = data;
1737 r.out.data = data;
1738 r.in.data_size = &real_data_size;
1739 r.out.data_size = &real_data_size;
1740 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1741 "QueryValue failed");
1742 if (existing_value) {
1743 torture_assert_werr_ok(tctx, r.out.result,
1744 "QueryValue failed");
1745 } else {
1746 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1747 "QueryValue failed");
1750 return true;
1753 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1754 struct torture_context *tctx,
1755 struct policy_handle *handle, int max_valnamelen,
1756 int max_valbufsize)
1758 struct winreg_EnumValue r;
1759 enum winreg_Type type = 0;
1760 uint32_t size = max_valbufsize, zero = 0;
1761 bool ret = true;
1762 uint8_t buf8;
1763 struct winreg_ValNameBuf name;
1765 name.name = "";
1766 name.size = 1024;
1768 ZERO_STRUCT(r);
1769 r.in.handle = handle;
1770 r.in.enum_index = 0;
1771 r.in.name = &name;
1772 r.out.name = &name;
1773 r.in.type = &type;
1774 r.in.value = &buf8;
1775 r.in.length = &zero;
1776 r.in.size = &size;
1778 do {
1779 torture_assert_ntstatus_ok(tctx,
1780 dcerpc_winreg_EnumValue_r(b, tctx, &r),
1781 "EnumValue failed");
1783 if (W_ERROR_IS_OK(r.out.result)) {
1784 ret &= test_QueryValue(b, tctx, handle,
1785 r.out.name->name);
1786 ret &= test_QueryMultipleValues(b, tctx, handle,
1787 r.out.name->name);
1790 r.in.enum_index++;
1791 } while (W_ERROR_IS_OK(r.out.result));
1793 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1794 "EnumValue failed");
1796 return ret;
1799 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
1800 struct torture_context *tctx)
1802 struct winreg_AbortSystemShutdown r;
1803 uint16_t server = 0x0;
1805 ZERO_STRUCT(r);
1806 r.in.server = &server;
1808 torture_assert_ntstatus_ok(tctx,
1809 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
1810 "AbortSystemShutdown failed");
1812 torture_assert_werr_ok(tctx, r.out.result,
1813 "AbortSystemShutdown failed");
1815 return true;
1818 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1819 struct dcerpc_pipe *p)
1821 struct winreg_InitiateSystemShutdown r;
1822 uint16_t hostname = 0x0;
1823 struct dcerpc_binding_handle *b = p->binding_handle;
1825 ZERO_STRUCT(r);
1826 r.in.hostname = &hostname;
1827 r.in.message = talloc(tctx, struct lsa_StringLarge);
1828 init_lsa_StringLarge(r.in.message, "spottyfood");
1829 r.in.force_apps = 1;
1830 r.in.timeout = 30;
1831 r.in.do_reboot = 1;
1833 torture_assert_ntstatus_ok(tctx,
1834 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
1835 "InitiateSystemShutdown failed");
1837 torture_assert_werr_ok(tctx, r.out.result,
1838 "InitiateSystemShutdown failed");
1840 return test_AbortSystemShutdown(b, tctx);
1844 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1845 struct dcerpc_pipe *p)
1847 struct winreg_InitiateSystemShutdownEx r;
1848 uint16_t hostname = 0x0;
1849 struct dcerpc_binding_handle *b = p->binding_handle;
1851 ZERO_STRUCT(r);
1852 r.in.hostname = &hostname;
1853 r.in.message = talloc(tctx, struct lsa_StringLarge);
1854 init_lsa_StringLarge(r.in.message, "spottyfood");
1855 r.in.force_apps = 1;
1856 r.in.timeout = 30;
1857 r.in.do_reboot = 1;
1858 r.in.reason = 0;
1860 torture_assert_ntstatus_ok(tctx,
1861 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
1862 "InitiateSystemShutdownEx failed");
1864 torture_assert_werr_ok(tctx, r.out.result,
1865 "InitiateSystemShutdownEx failed");
1867 return test_AbortSystemShutdown(b, tctx);
1869 #define MAX_DEPTH 2 /* Only go this far down the tree */
1871 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1872 struct policy_handle *handle, int depth,
1873 bool test_security)
1875 struct dcerpc_binding_handle *b = p->binding_handle;
1877 if (depth == MAX_DEPTH)
1878 return true;
1880 if (!test_QueryInfoKey(b, tctx, handle, NULL)) {
1883 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
1886 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1889 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1892 if (!test_EnumValue(b, tctx, handle, 0xFF, 0xFFFF)) {
1895 test_CloseKey(b, tctx, handle);
1897 return true;
1900 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
1901 struct torture_context *tctx,
1902 struct policy_handle *handle)
1904 const char *value_name = TEST_VALUE;
1905 uint32_t value = 0x12345678;
1906 const char *string = "torture";
1907 DATA_BLOB blob;
1908 enum winreg_Type types[] = {
1909 REG_DWORD,
1910 REG_BINARY,
1911 REG_SZ,
1912 REG_MULTI_SZ
1914 int t;
1916 torture_comment(tctx, "Testing SetValue (standard formats)\n");
1918 for (t=0; t < ARRAY_SIZE(types); t++) {
1920 enum winreg_Type w_type;
1921 uint32_t w_size, w_length;
1922 uint8_t *w_data;
1924 switch (types[t]) {
1925 case REG_DWORD:
1926 blob = data_blob_talloc_zero(tctx, 4);
1927 SIVAL(blob.data, 0, value);
1928 break;
1929 case REG_BINARY:
1930 blob = data_blob_string_const("binary_blob");
1931 break;
1932 case REG_SZ:
1933 torture_assert(tctx,
1934 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1935 CH_UNIX, CH_UTF16,
1936 string,
1937 strlen(string)+1,
1938 (void **)&blob.data,
1939 &blob.length,
1940 false), "");
1941 break;
1942 case REG_MULTI_SZ:
1943 torture_assert(tctx,
1944 convert_string_talloc_convenience(tctx, lp_iconv_convenience(tctx->lp_ctx),
1945 CH_UNIX, CH_UTF16,
1946 string,
1947 strlen(string)+1,
1948 (void **)&blob.data,
1949 &blob.length,
1950 false), "");
1951 torture_assert(tctx, data_blob_realloc(tctx, &blob, blob.length + 2), "");
1952 memset(&blob.data[blob.length - 2], '\0', 2);
1953 break;
1954 default:
1955 break;
1958 torture_assert(tctx,
1959 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
1960 "test_SetValue failed");
1961 torture_assert(tctx,
1962 test_QueryValue_full(b, tctx, handle, value_name, true),
1963 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
1964 torture_assert(tctx,
1965 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
1966 "test_winreg_QueryValue failed");
1967 torture_assert(tctx,
1968 test_DeleteValue(b, tctx, handle, value_name),
1969 "test_DeleteValue failed");
1971 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
1972 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
1973 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
1974 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
1977 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
1979 return true;
1982 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
1984 static bool test_Open_Security(struct torture_context *tctx,
1985 struct dcerpc_pipe *p, void *userdata)
1987 struct policy_handle handle, newhandle;
1988 bool ret = true, created2 = false;
1989 bool created4 = false;
1990 struct winreg_OpenHKLM r;
1991 struct dcerpc_binding_handle *b = p->binding_handle;
1993 winreg_open_fn open_fn = userdata;
1995 ZERO_STRUCT(r);
1996 r.in.system_name = 0;
1997 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1998 r.out.handle = &handle;
2000 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2001 "open");
2003 test_Cleanup(b, tctx, &handle, TEST_KEY_BASE);
2005 if (!test_CreateKey(b, tctx, &handle, TEST_KEY_BASE, NULL)) {
2006 torture_comment(tctx,
2007 "CreateKey (TEST_KEY_BASE) failed\n");
2010 if (test_CreateKey_sd(b, tctx, &handle, TEST_KEY2,
2011 NULL, &newhandle)) {
2012 created2 = true;
2015 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
2016 torture_comment(tctx, "CloseKey failed\n");
2017 ret = false;
2020 if (test_CreateKey_sd(b, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
2021 created4 = true;
2024 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
2025 torture_comment(tctx, "CloseKey failed\n");
2026 ret = false;
2029 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
2030 ret = false;
2033 if (created4 && !test_DeleteKey(b, tctx, &handle, TEST_KEY4)) {
2034 torture_comment(tctx, "DeleteKey failed\n");
2035 ret = false;
2038 if (created2 && !test_DeleteKey(b, tctx, &handle, TEST_KEY2)) {
2039 torture_comment(tctx, "DeleteKey failed\n");
2040 ret = false;
2043 /* The HKCR hive has a very large fanout */
2044 if (open_fn == (void *)dcerpc_winreg_OpenHKCR_r) {
2045 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
2046 ret = false;
2048 } else {
2049 if (!test_key(p, tctx, &handle, 0, true)) {
2050 ret = false;
2054 test_Cleanup(b, tctx, &handle, TEST_KEY_BASE);
2056 return ret;
2059 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2060 struct torture_context *tctx,
2061 struct policy_handle *handle)
2063 const char *value_name = TEST_VALUE;
2064 enum winreg_Type types[] = {
2065 REG_NONE,
2066 REG_SZ,
2067 REG_EXPAND_SZ,
2068 REG_BINARY,
2069 REG_DWORD,
2070 REG_DWORD_BIG_ENDIAN,
2071 REG_LINK,
2072 REG_MULTI_SZ,
2073 REG_RESOURCE_LIST,
2074 REG_FULL_RESOURCE_DESCRIPTOR,
2075 REG_RESOURCE_REQUIREMENTS_LIST,
2076 REG_QWORD,
2081 123456,
2082 653210,
2083 __LINE__
2085 int t, l;
2087 if (torture_setting_bool(tctx, "samba3", false) ||
2088 torture_setting_bool(tctx, "samba4", false)) {
2089 torture_skip(tctx, "skipping extended SetValue test against Samba");
2092 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2094 for (t=0; t < ARRAY_SIZE(types); t++) {
2095 for (l=0; l < 32; l++) {
2097 enum winreg_Type w_type;
2098 uint32_t w_size, w_length;
2099 uint8_t *w_data;
2101 uint32_t size;
2102 uint8_t *data;
2104 size = l;
2105 data = talloc_array(tctx, uint8_t, size);
2107 generate_random_buffer(data, size);
2109 torture_assert(tctx,
2110 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2111 "test_SetValue failed");
2113 torture_assert(tctx,
2114 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2115 "test_winreg_QueryValue failed");
2117 torture_assert(tctx,
2118 test_DeleteValue(b, tctx, handle, value_name),
2119 "test_DeleteValue failed");
2121 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2122 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2123 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2124 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2128 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2130 return true;
2133 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2134 #define VALUE_CURRENT_VERSION "CurrentVersion"
2136 static bool test_HKLM_wellknown(struct torture_context *tctx,
2137 struct dcerpc_binding_handle *b,
2138 struct policy_handle *handle)
2140 struct policy_handle newhandle;
2142 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2143 if (torture_setting_bool(tctx, "samba3", false)) {
2144 torture_assert(tctx, _test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, KEY_QUERY_VALUE, &newhandle, WERR_OK, NULL),
2145 "failed to open current version key");
2146 } else {
2147 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2148 "failed to open current version key");
2151 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2152 "failed to query current version");
2153 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2154 "failed to query current version");
2155 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2156 "test_QueryValue_full for NULL value failed");
2157 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2158 "test_QueryValue_full for \"\" value failed");
2160 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2161 "failed to close current version key");
2163 return true;
2166 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
2167 void *userdata)
2169 struct policy_handle handle, newhandle;
2170 bool ret = true, created = false, deleted = false;
2171 bool created3 = false, created_subkey = false;
2172 struct winreg_OpenHKLM r;
2173 struct dcerpc_binding_handle *b = p->binding_handle;
2175 winreg_open_fn open_fn = userdata;
2177 ZERO_STRUCT(r);
2178 r.in.system_name = 0;
2179 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2180 r.out.handle = &handle;
2182 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
2183 "open");
2185 if (open_fn == (void *)dcerpc_winreg_OpenHKLM_r) {
2186 torture_assert(tctx,
2187 test_HKLM_wellknown(tctx, b, &handle),
2188 "failed to test HKLM wellknown keys");
2191 test_Cleanup(b, tctx, &handle, TEST_KEY_BASE);
2193 if (!test_CreateKey(b, tctx, &handle, TEST_KEY_BASE, NULL)) {
2194 torture_comment(tctx,
2195 "CreateKey (TEST_KEY_BASE) failed\n");
2198 if (!test_CreateKey(b, tctx, &handle, TEST_KEY1, NULL)) {
2199 torture_comment(tctx,
2200 "CreateKey failed - not considering a failure\n");
2201 } else {
2202 created = true;
2205 if (created && !test_FlushKey(b, tctx, &handle)) {
2206 torture_comment(tctx, "FlushKey failed\n");
2207 ret = false;
2210 if (created && !test_OpenKey(b, tctx, &handle, TEST_KEY1, &newhandle))
2211 torture_fail(tctx,
2212 "CreateKey failed (OpenKey after Create didn't work)\n");
2214 if (created) {
2215 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2216 "simple SetValue test failed");
2217 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2218 "extended SetValue test failed");
2221 if (created && !test_CloseKey(b, tctx, &newhandle))
2222 torture_fail(tctx,
2223 "CreateKey failed (CloseKey after Open didn't work)\n");
2225 if (created && !test_DeleteKey(b, tctx, &handle, TEST_KEY1)) {
2226 torture_comment(tctx, "DeleteKey failed\n");
2227 ret = false;
2228 } else {
2229 deleted = true;
2232 if (created && !test_FlushKey(b, tctx, &handle)) {
2233 torture_comment(tctx, "FlushKey failed\n");
2234 ret = false;
2237 if (created && deleted &&
2238 !_test_OpenKey(b, tctx, &handle, TEST_KEY1,
2239 SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
2240 WERR_BADFILE, NULL)) {
2241 torture_comment(tctx,
2242 "DeleteKey failed (OpenKey after Delete "
2243 "did not return WERR_BADFILE)\n");
2244 ret = false;
2247 if (!test_GetVersion(b, tctx, &handle)) {
2248 torture_comment(tctx, "GetVersion failed\n");
2249 ret = false;
2252 if (created && test_CreateKey(b, tctx, &handle, TEST_KEY3, NULL)) {
2253 created3 = true;
2256 if (created3 &&
2257 test_CreateKey(b, tctx, &handle, TEST_SUBKEY, NULL)) {
2258 created_subkey = true;
2261 if (created_subkey &&
2262 !test_DeleteKey(b, tctx, &handle, TEST_KEY3)) {
2263 torture_comment(tctx, "DeleteKey failed\n");
2264 ret = false;
2267 /* The HKCR hive has a very large fanout */
2268 if (open_fn == (void *)dcerpc_winreg_OpenHKCR_r) {
2269 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
2270 ret = false;
2272 } else {
2273 if (!test_key(p, tctx, &handle, 0, false)) {
2274 ret = false;
2278 test_Cleanup(b, tctx, &handle, TEST_KEY_BASE);
2280 return ret;
2283 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
2285 struct torture_rpc_tcase *tcase;
2286 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
2287 struct torture_test *test;
2289 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
2290 &ndr_table_winreg);
2292 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
2293 test_InitiateSystemShutdown);
2294 test->dangerous = true;
2296 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
2297 test_InitiateSystemShutdownEx);
2298 test->dangerous = true;
2300 /* Basic tests without security descriptors */
2301 torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
2302 test_Open,
2303 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2304 torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
2305 test_Open,
2306 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2307 torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
2308 test_Open,
2309 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2310 torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
2311 test_Open,
2312 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2314 /* Security descriptor tests */
2315 torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
2316 test_Open_Security,
2317 (winreg_open_fn)dcerpc_winreg_OpenHKLM_r);
2318 torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
2319 test_Open_Security,
2320 (winreg_open_fn)dcerpc_winreg_OpenHKU_r);
2321 torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
2322 test_Open_Security,
2323 (winreg_open_fn)dcerpc_winreg_OpenHKCR_r);
2324 torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
2325 test_Open_Security,
2326 (winreg_open_fn)dcerpc_winreg_OpenHKCU_r);
2328 return suite;