s3:libsmb: Plumb cli_smb2_query_security_descriptor() inside cli_query_security_descr...
[Samba.git] / source4 / torture / rpc / winreg.c
blob55164cdadfc16ec1ef6252578283ead039a89b4a
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for winreg rpc operations
5 Copyright (C) Tim Potter 2003
6 Copyright (C) Jelmer Vernooij 2004-2007
7 Copyright (C) Günther Deschner 2007,2010
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "librpc/gen_ndr/ndr_winreg_c.h"
25 #include "librpc/gen_ndr/ndr_security.h"
26 #include "libcli/security/security.h"
27 #include "torture/rpc/torture_rpc.h"
28 #include "param/param.h"
29 #include "lib/registry/registry.h"
31 #define TEST_KEY_BASE "winreg_torture_test"
32 #define TEST_KEY1 "spottyfoot"
33 #define TEST_KEY2 "with a SD (#1)"
34 #define TEST_KEY3 "with a subkey"
35 #define TEST_KEY4 "sd_tests"
36 #define TEST_SUBKEY "subkey"
37 #define TEST_SUBKEY_SD "subkey_sd"
38 #define TEST_SUBSUBKEY_SD "subkey_sd\\subsubkey_sd"
39 #define TEST_VALUE "torture_value_name"
40 #define TEST_KEY_VOLATILE "torture_volatile_key"
41 #define TEST_SUBKEY_VOLATILE "torture_volatile_subkey"
42 #define TEST_KEY_SYMLINK "torture_symlink_key"
43 #define TEST_KEY_SYMLINK_DEST "torture_symlink_dest"
45 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
47 static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
49 name->string = s;
52 static void init_winreg_String(struct winreg_String *name, const char *s)
54 name->name = s;
55 if (s) {
56 name->name_len = 2 * (strlen_m(s) + 1);
57 name->name_size = name->name_len;
58 } else {
59 name->name_len = 0;
60 name->name_size = 0;
64 static bool test_GetVersion(struct dcerpc_binding_handle *b,
65 struct torture_context *tctx,
66 struct policy_handle *handle)
68 struct winreg_GetVersion r;
69 uint32_t v;
71 torture_comment(tctx, "Testing GetVersion\n");
73 ZERO_STRUCT(r);
74 r.in.handle = handle;
75 r.out.version = &v;
77 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion_r(b, tctx, &r),
78 "GetVersion failed");
80 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
82 return true;
85 static bool test_NotifyChangeKeyValue(struct dcerpc_binding_handle *b,
86 struct torture_context *tctx,
87 struct policy_handle *handle)
89 struct winreg_NotifyChangeKeyValue r;
91 ZERO_STRUCT(r);
92 r.in.handle = handle;
93 r.in.watch_subtree = true;
94 r.in.notify_filter = 0;
95 r.in.unknown = r.in.unknown2 = 0;
96 init_winreg_String(&r.in.string1, NULL);
97 init_winreg_String(&r.in.string2, NULL);
99 torture_assert_ntstatus_ok(tctx,
100 dcerpc_winreg_NotifyChangeKeyValue_r(b, tctx, &r),
101 "NotifyChangeKeyValue failed");
103 if (!W_ERROR_IS_OK(r.out.result)) {
104 torture_comment(tctx,
105 "NotifyChangeKeyValue failed - %s - not considering\n",
106 win_errstr(r.out.result));
107 return true;
110 return true;
113 static bool test_CreateKey_opts(struct torture_context *tctx,
114 struct dcerpc_binding_handle *b,
115 struct policy_handle *handle,
116 const char *name,
117 const char *kclass,
118 uint32_t options,
119 uint32_t access_mask,
120 struct winreg_SecBuf *secdesc,
121 WERROR expected_result,
122 enum winreg_CreateAction *action_taken_p,
123 struct policy_handle *new_handle_p)
125 struct winreg_CreateKey r;
126 struct policy_handle newhandle;
127 enum winreg_CreateAction action_taken = 0;
129 torture_comment(tctx, "Testing CreateKey(%s)\n", name);
131 ZERO_STRUCT(r);
132 r.in.handle = handle;
133 init_winreg_String(&r.in.name, name);
134 init_winreg_String(&r.in.keyclass, kclass);
135 r.in.options = options;
136 r.in.access_mask = access_mask;
137 r.in.action_taken = &action_taken;
138 r.in.secdesc = secdesc;
139 r.out.new_handle = &newhandle;
140 r.out.action_taken = &action_taken;
142 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
143 "CreateKey failed");
145 torture_assert_werr_equal(tctx, r.out.result, expected_result, "CreateKey failed");
147 if (new_handle_p) {
148 *new_handle_p = newhandle;
150 if (action_taken_p) {
151 *action_taken_p = *r.out.action_taken;
154 return true;
157 static bool test_CreateKey(struct dcerpc_binding_handle *b,
158 struct torture_context *tctx,
159 struct policy_handle *handle, const char *name,
160 const char *kclass)
162 return test_CreateKey_opts(tctx, b, handle, name, kclass,
163 REG_OPTION_NON_VOLATILE,
164 SEC_FLAG_MAXIMUM_ALLOWED,
165 NULL, /* secdesc */
166 WERR_OK,
167 NULL, /* action_taken */
168 NULL /* new_handle */);
172 createkey testing with a SD
174 static bool test_CreateKey_sd(struct dcerpc_binding_handle *b,
175 struct torture_context *tctx,
176 struct policy_handle *handle, const char *name,
177 const char *kclass,
178 struct policy_handle *newhandle)
180 struct winreg_CreateKey r;
181 enum winreg_CreateAction action_taken = 0;
182 struct security_descriptor *sd;
183 DATA_BLOB sdblob;
184 struct winreg_SecBuf secbuf;
186 sd = security_descriptor_dacl_create(tctx,
188 NULL, NULL,
189 SID_NT_AUTHENTICATED_USERS,
190 SEC_ACE_TYPE_ACCESS_ALLOWED,
191 SEC_GENERIC_ALL,
192 SEC_ACE_FLAG_OBJECT_INHERIT |
193 SEC_ACE_FLAG_CONTAINER_INHERIT,
194 NULL);
196 torture_assert_ndr_success(tctx,
197 ndr_push_struct_blob(&sdblob, tctx, sd,
198 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
199 "Failed to push security_descriptor ?!\n");
201 secbuf.sd.data = sdblob.data;
202 secbuf.sd.len = sdblob.length;
203 secbuf.sd.size = sdblob.length;
204 secbuf.length = sdblob.length-10;
205 secbuf.inherit = 0;
207 ZERO_STRUCT(r);
208 r.in.handle = handle;
209 r.out.new_handle = newhandle;
210 init_winreg_String(&r.in.name, name);
211 init_winreg_String(&r.in.keyclass, kclass);
212 r.in.options = 0x0;
213 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
214 r.in.action_taken = r.out.action_taken = &action_taken;
215 r.in.secdesc = &secbuf;
217 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey_r(b, tctx, &r),
218 "CreateKey with sd failed");
220 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
222 return true;
225 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
226 struct torture_context *tctx,
227 struct policy_handle *handle,
228 uint32_t *sec_info_ptr,
229 WERROR get_werr,
230 struct security_descriptor **sd_out)
232 struct winreg_GetKeySecurity r;
233 struct security_descriptor *sd = NULL;
234 uint32_t sec_info;
235 DATA_BLOB sdblob;
236 struct dcerpc_binding_handle *b = p->binding_handle;
238 if (sec_info_ptr) {
239 sec_info = *sec_info_ptr;
240 } else {
241 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
244 ZERO_STRUCT(r);
246 r.in.handle = handle;
247 r.in.sec_info = sec_info;
248 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
249 r.in.sd->size = 0x1000;
251 torture_assert_ntstatus_ok(tctx,
252 dcerpc_winreg_GetKeySecurity_r(b, tctx, &r),
253 "GetKeySecurity failed");
255 torture_assert_werr_equal(tctx, r.out.result, get_werr,
256 "GetKeySecurity failed");
258 sdblob.data = r.out.sd->data;
259 sdblob.length = r.out.sd->len;
261 sd = talloc_zero(tctx, struct security_descriptor);
263 torture_assert_ndr_success(tctx,
264 ndr_pull_struct_blob(&sdblob, tctx, sd,
265 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
266 "pull_security_descriptor failed");
268 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
269 NDR_PRINT_DEBUG(security_descriptor, sd);
272 if (sd_out) {
273 *sd_out = sd;
274 } else {
275 talloc_free(sd);
278 return true;
281 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
282 struct torture_context *tctx,
283 struct policy_handle *handle,
284 struct security_descriptor **sd_out)
286 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
289 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
290 struct torture_context *tctx,
291 struct policy_handle *handle,
292 uint32_t *sec_info_ptr,
293 struct security_descriptor *sd,
294 WERROR werr)
296 struct winreg_SetKeySecurity r;
297 struct KeySecurityData *sdata = NULL;
298 DATA_BLOB sdblob;
299 uint32_t sec_info;
300 struct dcerpc_binding_handle *b = p->binding_handle;
302 ZERO_STRUCT(r);
304 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
305 NDR_PRINT_DEBUG(security_descriptor, sd);
308 torture_assert_ndr_success(tctx,
309 ndr_push_struct_blob(&sdblob, tctx, sd,
310 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
311 "push_security_descriptor failed");
313 sdata = talloc_zero(tctx, struct KeySecurityData);
314 sdata->data = sdblob.data;
315 sdata->size = sdblob.length;
316 sdata->len = sdblob.length;
318 if (sec_info_ptr) {
319 sec_info = *sec_info_ptr;
320 } else {
321 sec_info = SECINFO_UNPROTECTED_SACL |
322 SECINFO_UNPROTECTED_DACL;
323 if (sd->owner_sid) {
324 sec_info |= SECINFO_OWNER;
326 if (sd->group_sid) {
327 sec_info |= SECINFO_GROUP;
329 if (sd->sacl) {
330 sec_info |= SECINFO_SACL;
332 if (sd->dacl) {
333 sec_info |= SECINFO_DACL;
337 r.in.handle = handle;
338 r.in.sec_info = sec_info;
339 r.in.sd = sdata;
341 torture_assert_ntstatus_ok(tctx,
342 dcerpc_winreg_SetKeySecurity_r(b, tctx, &r),
343 "SetKeySecurity failed");
345 torture_assert_werr_equal(tctx, r.out.result, werr,
346 "SetKeySecurity failed");
348 return true;
351 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
352 struct torture_context *tctx,
353 struct policy_handle *handle,
354 struct security_descriptor *sd)
356 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
359 static bool test_CloseKey(struct dcerpc_binding_handle *b,
360 struct torture_context *tctx,
361 struct policy_handle *handle)
363 struct winreg_CloseKey r;
365 ZERO_STRUCT(r);
366 r.in.handle = r.out.handle = handle;
368 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey_r(b, tctx, &r),
369 "CloseKey failed");
371 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
373 return true;
376 static bool test_FlushKey(struct dcerpc_binding_handle *b,
377 struct torture_context *tctx,
378 struct policy_handle *handle)
380 struct winreg_FlushKey r;
382 ZERO_STRUCT(r);
383 r.in.handle = handle;
385 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey_r(b, tctx, &r),
386 "FlushKey failed");
388 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
390 return true;
393 static bool test_OpenKey_opts(struct torture_context *tctx,
394 struct dcerpc_binding_handle *b,
395 struct policy_handle *hive_handle,
396 const char *keyname,
397 uint32_t options,
398 uint32_t access_mask,
399 struct policy_handle *key_handle,
400 WERROR expected_result)
402 struct winreg_OpenKey r;
404 ZERO_STRUCT(r);
405 r.in.parent_handle = hive_handle;
406 init_winreg_String(&r.in.keyname, keyname);
407 r.in.options = options;
408 r.in.access_mask = access_mask;
409 r.out.handle = key_handle;
411 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey_r(b, tctx, &r),
412 "OpenKey failed");
414 torture_assert_werr_equal(tctx, r.out.result, expected_result,
415 "OpenKey failed");
417 return true;
420 static bool test_OpenKey(struct dcerpc_binding_handle *b,
421 struct torture_context *tctx,
422 struct policy_handle *hive_handle,
423 const char *keyname, struct policy_handle *key_handle)
425 return test_OpenKey_opts(tctx, b, hive_handle, keyname,
426 REG_OPTION_NON_VOLATILE,
427 SEC_FLAG_MAXIMUM_ALLOWED,
428 key_handle,
429 WERR_OK);
432 static bool test_Cleanup(struct dcerpc_binding_handle *b,
433 struct torture_context *tctx,
434 struct policy_handle *handle, const char *key)
436 struct winreg_DeleteKey r;
438 ZERO_STRUCT(r);
439 r.in.handle = handle;
441 init_winreg_String(&r.in.key, key);
442 dcerpc_winreg_DeleteKey_r(b, tctx, &r);
444 return true;
447 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
448 struct torture_context *tctx,
449 struct policy_handle *handle,
450 WERROR get_werr,
451 WERROR set_werr)
453 struct security_descriptor *sd = NULL;
455 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
456 return false;
459 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
460 return false;
463 return true;
466 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
467 struct torture_context *tctx,
468 struct policy_handle *handle,
469 const char *key)
471 struct policy_handle new_handle;
472 bool ret = true;
473 struct dcerpc_binding_handle *b = p->binding_handle;
475 torture_comment(tctx, "SecurityDescriptor get & set\n");
477 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
478 return false;
481 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
482 WERR_OK, WERR_OK)) {
483 ret = false;
486 if (!test_CloseKey(b, tctx, &new_handle)) {
487 return false;
490 return ret;
493 static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
494 struct torture_context *tctx,
495 struct policy_handle *handle,
496 uint32_t access_mask,
497 const char *key,
498 WERROR open_werr,
499 WERROR get_werr,
500 WERROR set_werr)
502 struct policy_handle new_handle;
503 bool ret = true;
504 struct dcerpc_binding_handle *b = p->binding_handle;
506 torture_assert(tctx,
507 test_OpenKey_opts(tctx, b, handle, key,
508 REG_OPTION_NON_VOLATILE,
509 access_mask,
510 &new_handle,
511 open_werr),
512 "failed to open key");
514 if (!W_ERROR_IS_OK(open_werr)) {
515 return true;
518 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
519 get_werr, set_werr)) {
520 ret = false;
523 if (!test_CloseKey(b, tctx, &new_handle)) {
524 return false;
527 return ret;
530 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
531 struct torture_context *tctx,
532 struct policy_handle *handle,
533 const struct dom_sid *sid)
535 struct security_descriptor *sd = NULL;
536 int i;
538 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
539 return false;
542 if (!sd || !sd->dacl) {
543 return false;
546 for (i = 0; i < sd->dacl->num_aces; i++) {
547 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
548 return true;
552 return false;
555 static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
556 struct torture_context *tctx,
557 struct policy_handle *handle,
558 const char *key,
559 const struct dom_sid *sid)
561 struct policy_handle new_handle;
562 bool ret = true;
563 struct dcerpc_binding_handle *b = p->binding_handle;
565 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
566 return false;
569 ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
571 test_CloseKey(b, tctx, &new_handle);
573 return ret;
576 static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
577 struct torture_context *tctx,
578 struct policy_handle *handle,
579 const struct dom_sid *sid)
581 struct security_descriptor *sd = NULL;
582 int i;
583 uint32_t sec_info = SECINFO_SACL;
585 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
586 return false;
589 if (!sd || !sd->sacl) {
590 return false;
593 for (i = 0; i < sd->sacl->num_aces; i++) {
594 if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
595 return true;
599 return false;
602 static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
603 struct torture_context *tctx,
604 struct policy_handle *handle,
605 const char *key,
606 const struct dom_sid *sid)
608 struct policy_handle new_handle;
609 bool ret = true;
610 struct dcerpc_binding_handle *b = p->binding_handle;
612 torture_assert(tctx,
613 test_OpenKey_opts(tctx, b, handle, key,
614 REG_OPTION_NON_VOLATILE,
615 SEC_FLAG_SYSTEM_SECURITY,
616 &new_handle,
617 WERR_OK),
618 "failed to open key");
620 ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
622 test_CloseKey(b, tctx, &new_handle);
624 return ret;
627 static bool test_owner_present(struct dcerpc_pipe *p,
628 struct torture_context *tctx,
629 struct policy_handle *handle,
630 const struct dom_sid *sid)
632 struct security_descriptor *sd = NULL;
633 uint32_t sec_info = SECINFO_OWNER;
635 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
636 return false;
639 if (!sd || !sd->owner_sid) {
640 return false;
643 return dom_sid_equal(sd->owner_sid, sid);
646 static bool _test_owner_present(struct dcerpc_pipe *p,
647 struct torture_context *tctx,
648 struct policy_handle *handle,
649 const char *key,
650 const struct dom_sid *sid)
652 struct policy_handle new_handle;
653 bool ret = true;
654 struct dcerpc_binding_handle *b = p->binding_handle;
656 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
657 return false;
660 ret = test_owner_present(p, tctx, &new_handle, sid);
662 test_CloseKey(b, tctx, &new_handle);
664 return ret;
667 static bool test_group_present(struct dcerpc_pipe *p,
668 struct torture_context *tctx,
669 struct policy_handle *handle,
670 const struct dom_sid *sid)
672 struct security_descriptor *sd = NULL;
673 uint32_t sec_info = SECINFO_GROUP;
675 if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
676 return false;
679 if (!sd || !sd->group_sid) {
680 return false;
683 return dom_sid_equal(sd->group_sid, sid);
686 static bool _test_group_present(struct dcerpc_pipe *p,
687 struct torture_context *tctx,
688 struct policy_handle *handle,
689 const char *key,
690 const struct dom_sid *sid)
692 struct policy_handle new_handle;
693 bool ret = true;
694 struct dcerpc_binding_handle *b = p->binding_handle;
696 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
697 return false;
700 ret = test_group_present(p, tctx, &new_handle, sid);
702 test_CloseKey(b, tctx, &new_handle);
704 return ret;
707 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
708 struct torture_context *tctx,
709 struct policy_handle *handle,
710 const struct dom_sid *sid,
711 uint8_t flags)
713 struct security_descriptor *sd = NULL;
714 int i;
716 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
717 return false;
720 if (!sd || !sd->dacl) {
721 return false;
724 for (i = 0; i < sd->dacl->num_aces; i++) {
725 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
726 (sd->dacl->aces[i].flags == flags)) {
727 return true;
731 return false;
734 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
735 struct torture_context *tctx,
736 struct policy_handle *handle,
737 const struct security_ace *ace)
739 struct security_descriptor *sd = NULL;
740 int i;
742 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
743 return false;
746 if (!sd || !sd->dacl) {
747 return false;
750 for (i = 0; i < sd->dacl->num_aces; i++) {
751 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
752 return true;
756 return false;
759 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
760 struct torture_context *tctx,
761 struct policy_handle *handle,
762 const char *key,
763 struct security_descriptor *sd)
765 struct policy_handle new_handle;
766 bool ret = true;
767 struct dcerpc_binding_handle *b = p->binding_handle;
769 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
770 return false;
773 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
774 ret = false;
777 if (!test_CloseKey(b, tctx, &new_handle)) {
778 ret = false;
781 return ret;
784 static bool test_BackupSecurity(struct dcerpc_pipe *p,
785 struct torture_context *tctx,
786 struct policy_handle *handle,
787 const char *key,
788 struct security_descriptor **sd)
790 struct policy_handle new_handle;
791 bool ret = true;
792 struct dcerpc_binding_handle *b = p->binding_handle;
794 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
795 return false;
798 if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
799 ret = false;
802 if (!test_CloseKey(b, tctx, &new_handle)) {
803 ret = false;
806 return ret;
809 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
810 struct torture_context *tctx,
811 struct policy_handle *handle,
812 const char *key)
814 /* get sd
815 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
816 set sd
817 get sd
818 check ace
819 add subkey
820 get sd
821 check ace
822 add subsubkey
823 get sd
824 check ace
825 del subsubkey
826 del subkey
827 reset sd
830 struct security_descriptor *sd = NULL;
831 struct security_descriptor *sd_orig = NULL;
832 struct security_ace *ace = NULL;
833 struct policy_handle new_handle;
834 bool ret = true;
835 struct dcerpc_binding_handle *b = p->binding_handle;
836 const char *test_subkey_sd;
837 const char *test_subsubkey_sd;
839 torture_comment(tctx, "SecurityDescriptor inheritance\n");
841 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
842 return false;
845 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
846 return false;
849 sd_orig = security_descriptor_copy(tctx, sd);
850 if (sd_orig == NULL) {
851 return false;
854 ace = security_ace_create(tctx,
855 TEST_SID,
856 SEC_ACE_TYPE_ACCESS_ALLOWED,
857 SEC_STD_REQUIRED,
858 SEC_ACE_FLAG_CONTAINER_INHERIT);
860 torture_assert_ntstatus_ok(tctx,
861 security_descriptor_dacl_add(sd, ace),
862 "failed to add ace");
864 /* FIXME: add further tests for these flags */
865 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
866 SEC_DESC_SACL_AUTO_INHERITED;
868 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
869 return false;
872 torture_assert(tctx,
873 test_dacl_ace_present(p, tctx, &new_handle, ace),
874 "new ACE not present!");
876 if (!test_CloseKey(b, tctx, &new_handle)) {
877 return false;
880 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
882 if (!test_CreateKey(b, tctx, handle, test_subkey_sd, NULL)) {
883 ret = false;
884 goto out;
887 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
888 ret = false;
889 goto out;
892 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
893 torture_comment(tctx, "inherited ACE not present!\n");
894 ret = false;
895 goto out;
898 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
900 test_CloseKey(b, tctx, &new_handle);
901 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
902 ret = false;
903 goto out;
906 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
907 ret = false;
908 goto out;
911 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
912 torture_comment(tctx, "inherited ACE not present!\n");
913 ret = false;
914 goto out;
917 out:
918 test_CloseKey(b, tctx, &new_handle);
919 test_Cleanup(b, tctx, handle, test_subkey_sd);
920 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
922 return ret;
925 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
926 struct torture_context *tctx,
927 struct policy_handle *handle,
928 const char *key)
930 /* get sd
931 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
932 set sd
933 add subkey/subkey
934 get sd
935 check ace
936 get sd from subkey
937 check ace
938 del subkey/subkey
939 del subkey
940 reset sd
943 struct security_descriptor *sd = NULL;
944 struct security_descriptor *sd_orig = NULL;
945 struct security_ace *ace = NULL;
946 struct policy_handle new_handle;
947 struct dom_sid *sid = NULL;
948 bool ret = true;
949 uint8_t ace_flags = 0x0;
950 struct dcerpc_binding_handle *b = p->binding_handle;
951 const char *test_subkey_sd;
952 const char *test_subsubkey_sd;
954 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
956 if (!test_OpenKey(b, tctx, handle, key, &new_handle)) {
957 return false;
960 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
961 return false;
964 sd_orig = security_descriptor_copy(tctx, sd);
965 if (sd_orig == NULL) {
966 return false;
969 ace = security_ace_create(tctx,
970 TEST_SID,
971 SEC_ACE_TYPE_ACCESS_ALLOWED,
972 SEC_STD_REQUIRED,
973 SEC_ACE_FLAG_CONTAINER_INHERIT |
974 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
976 torture_assert_ntstatus_ok(tctx,
977 security_descriptor_dacl_add(sd, ace),
978 "failed to add ace");
980 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
981 return false;
984 torture_assert(tctx,
985 test_dacl_ace_present(p, tctx, &new_handle, ace),
986 "new ACE not present!");
988 if (!test_CloseKey(b, tctx, &new_handle)) {
989 return false;
992 test_subkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBKEY_SD);
993 test_subsubkey_sd = talloc_asprintf(tctx, "%s\\%s", key, TEST_SUBSUBKEY_SD);
995 if (!test_CreateKey(b, tctx, handle, test_subsubkey_sd, NULL)) {
996 return false;
999 if (!test_OpenKey(b, tctx, handle, test_subsubkey_sd, &new_handle)) {
1000 ret = false;
1001 goto out;
1004 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1005 torture_comment(tctx, "inherited ACE present but should not!\n");
1006 ret = false;
1007 goto out;
1010 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1011 if (sid == NULL) {
1012 return false;
1015 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
1016 torture_comment(tctx, "inherited trustee SID present but should not!\n");
1017 ret = false;
1018 goto out;
1021 test_CloseKey(b, tctx, &new_handle);
1023 if (!test_OpenKey(b, tctx, handle, test_subkey_sd, &new_handle)) {
1024 ret = false;
1025 goto out;
1028 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
1029 torture_comment(tctx, "inherited ACE present but should not!\n");
1030 ret = false;
1031 goto out;
1034 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
1035 torture_comment(tctx, "inherited trustee SID with flags 0x%02x not present!\n",
1036 ace_flags);
1037 ret = false;
1038 goto out;
1041 out:
1042 test_CloseKey(b, tctx, &new_handle);
1043 test_Cleanup(b, tctx, handle, test_subkey_sd);
1044 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1046 return ret;
1049 static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
1050 struct torture_context *tctx,
1051 struct policy_handle *handle,
1052 const char *key)
1054 bool ret = true;
1055 int i;
1057 struct winreg_mask_result_table {
1058 uint32_t access_mask;
1059 WERROR open_werr;
1060 WERROR get_werr;
1061 WERROR set_werr;
1062 } sd_mask_tests[] = {
1063 { 0,
1064 WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1065 { SEC_FLAG_MAXIMUM_ALLOWED,
1066 WERR_OK, WERR_OK, WERR_OK },
1067 { SEC_STD_WRITE_DAC,
1068 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1069 { SEC_FLAG_SYSTEM_SECURITY,
1070 WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1073 /* FIXME: before this test can ever run successfully we need a way to
1074 * correctly read a NULL security_descritpor in ndr, get the required
1075 * length, requery, etc.
1078 return true;
1080 for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1082 torture_comment(tctx,
1083 "SecurityDescriptor get & set with access_mask: 0x%08x\n",
1084 sd_mask_tests[i].access_mask);
1085 torture_comment(tctx,
1086 "expecting: open %s, get: %s, set: %s\n",
1087 win_errstr(sd_mask_tests[i].open_werr),
1088 win_errstr(sd_mask_tests[i].get_werr),
1089 win_errstr(sd_mask_tests[i].set_werr));
1091 if (_test_SecurityDescriptor(p, tctx, handle,
1092 sd_mask_tests[i].access_mask, key,
1093 sd_mask_tests[i].open_werr,
1094 sd_mask_tests[i].get_werr,
1095 sd_mask_tests[i].set_werr)) {
1096 ret = false;
1100 return ret;
1103 typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1104 struct torture_context *,
1105 struct policy_handle *,
1106 const char *,
1107 const struct dom_sid *);
1109 static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1110 struct torture_context *tctx,
1111 struct policy_handle *handle,
1112 const char *key,
1113 const char *test,
1114 uint32_t access_mask,
1115 uint32_t sec_info,
1116 struct security_descriptor *sd,
1117 WERROR set_werr,
1118 bool expect_present,
1119 bool (*fn) (struct dcerpc_pipe *,
1120 struct torture_context *,
1121 struct policy_handle *,
1122 const char *,
1123 const struct dom_sid *),
1124 const struct dom_sid *sid)
1126 struct policy_handle new_handle;
1127 struct dcerpc_binding_handle *b = p->binding_handle;
1129 torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1130 "0x%08x, access_mask: 0x%08x\n",
1131 test, sec_info, access_mask);
1133 torture_assert(tctx,
1134 test_OpenKey_opts(tctx, b, handle, key,
1135 REG_OPTION_NON_VOLATILE,
1136 access_mask,
1137 &new_handle,
1138 WERR_OK),
1139 "failed to open key");
1141 if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1143 set_werr)) {
1144 torture_warning(tctx,
1145 "SetKeySecurity with secinfo: 0x%08x has failed\n",
1146 sec_info);
1147 smb_panic("");
1148 test_CloseKey(b, tctx, &new_handle);
1149 return false;
1152 test_CloseKey(b, tctx, &new_handle);
1154 if (W_ERROR_IS_OK(set_werr)) {
1155 bool present;
1156 present = fn(p, tctx, handle, key, sid);
1157 if ((expect_present) && (!present)) {
1158 torture_warning(tctx,
1159 "%s sid is not present!\n",
1160 test);
1161 return false;
1163 if ((!expect_present) && (present)) {
1164 torture_warning(tctx,
1165 "%s sid is present but not expected!\n",
1166 test);
1167 return false;
1171 return true;
1174 static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1175 struct torture_context *tctx,
1176 struct policy_handle *handle,
1177 const char *key)
1179 struct security_descriptor *sd_orig = NULL;
1180 struct dom_sid *sid = NULL;
1181 bool ret = true;
1182 int i, a;
1184 struct security_descriptor *sd_owner =
1185 security_descriptor_dacl_create(tctx,
1187 TEST_SID, NULL, NULL);
1189 struct security_descriptor *sd_group =
1190 security_descriptor_dacl_create(tctx,
1192 NULL, TEST_SID, NULL);
1194 struct security_descriptor *sd_dacl =
1195 security_descriptor_dacl_create(tctx,
1197 NULL, NULL,
1198 TEST_SID,
1199 SEC_ACE_TYPE_ACCESS_ALLOWED,
1200 SEC_GENERIC_ALL,
1202 SID_NT_AUTHENTICATED_USERS,
1203 SEC_ACE_TYPE_ACCESS_ALLOWED,
1204 SEC_GENERIC_ALL,
1206 NULL);
1208 struct security_descriptor *sd_sacl =
1209 security_descriptor_sacl_create(tctx,
1211 NULL, NULL,
1212 TEST_SID,
1213 SEC_ACE_TYPE_SYSTEM_AUDIT,
1214 SEC_GENERIC_ALL,
1215 SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1216 NULL);
1218 struct winreg_secinfo_table {
1219 struct security_descriptor *sd;
1220 uint32_t sec_info;
1221 WERROR set_werr;
1222 bool sid_present;
1223 secinfo_verify_fn fn;
1226 struct winreg_secinfo_table sec_info_owner_tests[] = {
1227 { sd_owner, 0, WERR_OK,
1228 false, (secinfo_verify_fn)_test_owner_present },
1229 { sd_owner, SECINFO_OWNER, WERR_OK,
1230 true, (secinfo_verify_fn)_test_owner_present },
1231 { sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1232 { sd_owner, SECINFO_DACL, WERR_OK,
1233 true, (secinfo_verify_fn)_test_owner_present },
1234 { sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1237 uint32_t sd_owner_good_access_masks[] = {
1238 SEC_FLAG_MAXIMUM_ALLOWED,
1239 /* SEC_STD_WRITE_OWNER, */
1242 struct winreg_secinfo_table sec_info_group_tests[] = {
1243 { sd_group, 0, WERR_OK,
1244 false, (secinfo_verify_fn)_test_group_present },
1245 { sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1246 { sd_group, SECINFO_GROUP, WERR_OK,
1247 true, (secinfo_verify_fn)_test_group_present },
1248 { sd_group, SECINFO_DACL, WERR_OK,
1249 true, (secinfo_verify_fn)_test_group_present },
1250 { sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1253 uint32_t sd_group_good_access_masks[] = {
1254 SEC_FLAG_MAXIMUM_ALLOWED,
1257 struct winreg_secinfo_table sec_info_dacl_tests[] = {
1258 { sd_dacl, 0, WERR_OK,
1259 false, (secinfo_verify_fn)_test_dacl_trustee_present },
1260 { sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1261 { sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1262 { sd_dacl, SECINFO_DACL, WERR_OK,
1263 true, (secinfo_verify_fn)_test_dacl_trustee_present },
1264 { sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1267 uint32_t sd_dacl_good_access_masks[] = {
1268 SEC_FLAG_MAXIMUM_ALLOWED,
1269 SEC_STD_WRITE_DAC,
1272 struct winreg_secinfo_table sec_info_sacl_tests[] = {
1273 { sd_sacl, 0, WERR_OK,
1274 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1275 { sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1276 { sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1277 { sd_sacl, SECINFO_DACL, WERR_OK,
1278 false, (secinfo_verify_fn)_test_sacl_trustee_present },
1279 { sd_sacl, SECINFO_SACL, WERR_OK,
1280 true, (secinfo_verify_fn)_test_sacl_trustee_present },
1283 uint32_t sd_sacl_good_access_masks[] = {
1284 SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1285 /* SEC_FLAG_SYSTEM_SECURITY, */
1288 sid = dom_sid_parse_talloc(tctx, TEST_SID);
1289 if (sid == NULL) {
1290 return false;
1293 if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1294 return false;
1297 /* OWNER */
1299 for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1301 for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1303 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1304 key,
1305 "OWNER",
1306 sd_owner_good_access_masks[a],
1307 sec_info_owner_tests[i].sec_info,
1308 sec_info_owner_tests[i].sd,
1309 sec_info_owner_tests[i].set_werr,
1310 sec_info_owner_tests[i].sid_present,
1311 sec_info_owner_tests[i].fn,
1312 sid))
1314 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1315 ret = false;
1316 goto out;
1321 /* GROUP */
1323 for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1325 for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1327 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1328 key,
1329 "GROUP",
1330 sd_group_good_access_masks[a],
1331 sec_info_group_tests[i].sec_info,
1332 sec_info_group_tests[i].sd,
1333 sec_info_group_tests[i].set_werr,
1334 sec_info_group_tests[i].sid_present,
1335 sec_info_group_tests[i].fn,
1336 sid))
1338 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1339 ret = false;
1340 goto out;
1345 /* DACL */
1347 for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1349 for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1351 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1352 key,
1353 "DACL",
1354 sd_dacl_good_access_masks[a],
1355 sec_info_dacl_tests[i].sec_info,
1356 sec_info_dacl_tests[i].sd,
1357 sec_info_dacl_tests[i].set_werr,
1358 sec_info_dacl_tests[i].sid_present,
1359 sec_info_dacl_tests[i].fn,
1360 sid))
1362 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1363 ret = false;
1364 goto out;
1369 /* SACL */
1371 for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1373 for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1375 if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1376 key,
1377 "SACL",
1378 sd_sacl_good_access_masks[a],
1379 sec_info_sacl_tests[i].sec_info,
1380 sec_info_sacl_tests[i].sd,
1381 sec_info_sacl_tests[i].set_werr,
1382 sec_info_sacl_tests[i].sid_present,
1383 sec_info_sacl_tests[i].fn,
1384 sid))
1386 torture_comment(tctx, "test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1387 ret = false;
1388 goto out;
1393 out:
1394 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1396 return ret;
1399 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1400 struct torture_context *tctx,
1401 struct policy_handle *handle,
1402 const char *key)
1404 bool ret = true;
1406 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1407 torture_comment(tctx, "test_SecurityDescriptor failed\n");
1408 ret = false;
1411 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1412 torture_comment(tctx, "test_SecurityDescriptorInheritance failed\n");
1413 ret = false;
1416 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1417 torture_comment(tctx, "test_SecurityDescriptorBlockInheritance failed\n");
1418 ret = false;
1421 if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1422 torture_comment(tctx, "test_SecurityDescriptorsSecInfo failed\n");
1423 ret = false;
1426 if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1427 torture_comment(tctx, "test_SecurityDescriptorsMasks failed\n");
1428 ret = false;
1431 return ret;
1434 static bool test_DeleteKey_opts(struct dcerpc_binding_handle *b,
1435 struct torture_context *tctx,
1436 struct policy_handle *handle,
1437 const char *key,
1438 WERROR expected_result)
1440 struct winreg_DeleteKey r;
1442 torture_comment(tctx, "Testing DeleteKey(%s)\n", key);
1444 r.in.handle = handle;
1445 init_winreg_String(&r.in.key, key);
1447 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey_r(b, tctx, &r),
1448 "Delete Key failed");
1449 torture_assert_werr_equal(tctx, r.out.result, expected_result,
1450 "DeleteKey failed");
1452 return true;
1455 static bool test_DeleteKey(struct dcerpc_binding_handle *b,
1456 struct torture_context *tctx,
1457 struct policy_handle *handle, const char *key)
1459 return test_DeleteKey_opts(b, tctx, handle, key, WERR_OK);
1462 static bool test_QueryInfoKey(struct dcerpc_binding_handle *b,
1463 struct torture_context *tctx,
1464 struct policy_handle *handle,
1465 char *kclass,
1466 uint32_t *pmax_valnamelen,
1467 uint32_t *pmax_valbufsize)
1469 struct winreg_QueryInfoKey r;
1470 uint32_t num_subkeys, max_subkeylen, max_classlen,
1471 num_values, max_valnamelen, max_valbufsize,
1472 secdescsize;
1473 NTTIME last_changed_time;
1475 ZERO_STRUCT(r);
1476 r.in.handle = handle;
1477 r.out.num_subkeys = &num_subkeys;
1478 r.out.max_subkeylen = &max_subkeylen;
1479 r.out.max_classlen = &max_classlen;
1480 r.out.num_values = &num_values;
1481 r.out.max_valnamelen = &max_valnamelen;
1482 r.out.max_valbufsize = &max_valbufsize;
1483 r.out.secdescsize = &secdescsize;
1484 r.out.last_changed_time = &last_changed_time;
1486 r.out.classname = talloc(tctx, struct winreg_String);
1488 r.in.classname = talloc(tctx, struct winreg_String);
1489 init_winreg_String(r.in.classname, kclass);
1491 torture_assert_ntstatus_ok(tctx,
1492 dcerpc_winreg_QueryInfoKey_r(b, tctx, &r),
1493 "QueryInfoKey failed");
1495 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1497 if (pmax_valnamelen) {
1498 *pmax_valnamelen = max_valnamelen;
1501 if (pmax_valbufsize) {
1502 *pmax_valbufsize = max_valbufsize;
1505 return true;
1508 static bool test_SetValue(struct dcerpc_binding_handle *b,
1509 struct torture_context *tctx,
1510 struct policy_handle *handle,
1511 const char *value_name,
1512 enum winreg_Type type,
1513 uint8_t *data,
1514 uint32_t size)
1516 struct winreg_SetValue r;
1517 struct winreg_String name;
1519 torture_comment(tctx, "Testing SetValue(%s), type: %s, offered: 0x%08x)\n",
1520 value_name, str_regtype(type), size);
1522 init_winreg_String(&name, value_name);
1524 r.in.handle = handle;
1525 r.in.name = name;
1526 r.in.type = type;
1527 r.in.data = data;
1528 r.in.size = size;
1530 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_SetValue_r(b, tctx, &r),
1531 "winreg_SetValue failed");
1532 torture_assert_werr_ok(tctx, r.out.result,
1533 "winreg_SetValue failed");
1535 return true;
1538 static bool test_DeleteValue(struct dcerpc_binding_handle *b,
1539 struct torture_context *tctx,
1540 struct policy_handle *handle,
1541 const char *value_name)
1543 struct winreg_DeleteValue r;
1544 struct winreg_String value;
1546 torture_comment(tctx, "Testing DeleteValue(%s)\n", value_name);
1548 init_winreg_String(&value, value_name);
1550 r.in.handle = handle;
1551 r.in.value = value;
1553 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteValue_r(b, tctx, &r),
1554 "winreg_DeleteValue failed");
1555 torture_assert_werr_ok(tctx, r.out.result,
1556 "winreg_DeleteValue failed");
1558 return true;
1561 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1562 struct policy_handle *handle, int depth,
1563 bool test_security);
1565 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1566 struct policy_handle *handle, int depth,
1567 bool test_security)
1569 struct winreg_EnumKey r;
1570 struct winreg_StringBuf kclass, name;
1571 NTSTATUS status;
1572 NTTIME t = 0;
1573 struct dcerpc_binding_handle *b = p->binding_handle;
1575 kclass.name = "";
1576 kclass.size = 1024;
1578 ZERO_STRUCT(r);
1579 r.in.handle = handle;
1580 r.in.enum_index = 0;
1581 r.in.name = &name;
1582 r.in.keyclass = &kclass;
1583 r.out.name = &name;
1584 r.in.last_changed_time = &t;
1586 do {
1587 name.name = NULL;
1588 name.size = 1024;
1590 status = dcerpc_winreg_EnumKey_r(b, tctx, &r);
1592 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1593 struct policy_handle key_handle;
1595 torture_comment(tctx, "EnumKey: %d: %s\n",
1596 r.in.enum_index,
1597 r.out.name->name);
1599 if (!test_OpenKey(b, tctx, handle, r.out.name->name,
1600 &key_handle)) {
1601 } else {
1602 test_key(p, tctx, &key_handle,
1603 depth + 1, test_security);
1607 r.in.enum_index++;
1609 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1611 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1613 if (!W_ERROR_IS_OK(r.out.result) &&
1614 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1615 torture_fail(tctx, "EnumKey failed");
1618 return true;
1621 static bool test_QueryMultipleValues(struct dcerpc_binding_handle *b,
1622 struct torture_context *tctx,
1623 struct policy_handle *handle,
1624 const char *valuename)
1626 struct winreg_QueryMultipleValues r;
1627 uint32_t bufsize=0;
1629 ZERO_STRUCT(r);
1631 r.in.key_handle = handle;
1632 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1633 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1634 r.in.values_in[0].ve_valuename->name = valuename;
1635 /* size needs to be set manually for winreg_ValNameBuf */
1636 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1638 r.in.num_values = 1;
1639 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1640 *r.in.buffer_size = bufsize;
1641 do {
1642 *r.in.buffer_size = bufsize;
1643 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1644 *r.in.buffer_size);
1646 torture_assert_ntstatus_ok(tctx,
1647 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1648 "QueryMultipleValues failed");
1650 talloc_free(r.in.buffer);
1651 bufsize += 0x20;
1652 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1654 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1656 return true;
1659 static bool test_QueryMultipleValues_full(struct dcerpc_binding_handle *b,
1660 struct torture_context *tctx,
1661 struct policy_handle *handle,
1662 uint32_t num_values,
1663 const char * const *valuenames,
1664 bool existing_value)
1666 struct winreg_QueryMultipleValues r;
1667 uint32_t bufsize = 0;
1668 int i;
1670 torture_comment(tctx, "Testing QueryMultipleValues\n");
1672 ZERO_STRUCT(r);
1674 r.in.key_handle = handle;
1675 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1676 r.in.buffer_size = r.out.buffer_size = &bufsize;
1678 torture_assert_ntstatus_ok(tctx,
1679 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1680 "QueryMultipleValues failed");
1681 torture_assert_werr_ok(tctx, r.out.result,
1682 "QueryMultipleValues failed");
1684 /* this test crashes w2k8 remote registry */
1685 #if 0
1686 r.in.num_values = num_values;
1687 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1689 torture_assert_ntstatus_ok(tctx,
1690 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1691 "QueryMultipleValues failed");
1692 torture_assert_werr_ok(tctx, r.out.result,
1693 "QueryMultipleValues failed");
1694 #endif
1695 r.in.num_values = num_values;
1696 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1697 for (i=0; i < r.in.num_values; i++) {
1698 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1699 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1700 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1703 torture_assert_ntstatus_ok(tctx,
1704 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1705 "QueryMultipleValues failed");
1706 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1707 "QueryMultipleValues failed");
1709 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1710 return true;
1713 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1714 *r.in.buffer_size = 0xff;
1715 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.buffer_size);
1717 torture_assert_ntstatus_ok(tctx,
1718 dcerpc_winreg_QueryMultipleValues_r(b, tctx, &r),
1719 "QueryMultipleValues failed");
1722 torture_assert_werr_ok(tctx, r.out.result,
1723 "QueryMultipleValues failed");
1725 return true;
1729 static bool test_QueryMultipleValues2_full(struct dcerpc_binding_handle *b,
1730 struct torture_context *tctx,
1731 struct policy_handle *handle,
1732 uint32_t num_values,
1733 const char * const *valuenames,
1734 bool existing_value)
1736 struct winreg_QueryMultipleValues2 r;
1737 uint32_t offered = 0, needed;
1738 int i;
1740 torture_comment(tctx, "Testing QueryMultipleValues2\n");
1742 ZERO_STRUCT(r);
1744 r.in.key_handle = handle;
1745 r.in.offered = &offered;
1746 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 0);
1747 r.out.needed = &needed;
1749 torture_assert_ntstatus_ok(tctx,
1750 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1751 "QueryMultipleValues2 failed");
1752 torture_assert_werr_ok(tctx, r.out.result,
1753 "QueryMultipleValues2 failed");
1755 /* this test crashes w2k8 remote registry */
1756 #if 0
1757 r.in.num_values = num_values;
1758 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1760 torture_assert_ntstatus_ok(tctx,
1761 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1762 "QueryMultipleValues2 failed");
1763 torture_assert_werr_ok(tctx, r.out.result,
1764 "QueryMultipleValues2 failed");
1765 #endif
1766 r.in.num_values = num_values;
1767 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, num_values);
1768 for (i=0; i < r.in.num_values; i++) {
1769 r.in.values_in[i].ve_valuename = talloc_zero(tctx, struct winreg_ValNameBuf);
1770 r.in.values_in[i].ve_valuename->name = talloc_strdup(tctx, valuenames[i]);
1771 r.in.values_in[i].ve_valuename->size = strlen_m_term(r.in.values_in[i].ve_valuename->name)*2;
1774 torture_assert_ntstatus_ok(tctx,
1775 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1776 "QueryMultipleValues2 failed");
1777 torture_assert_werr_equal(tctx, r.out.result, existing_value ? WERR_MORE_DATA : WERR_BADFILE,
1778 "QueryMultipleValues2 failed");
1780 if (W_ERROR_EQUAL(r.out.result, WERR_BADFILE)) {
1781 return true;
1784 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1785 *r.in.offered = *r.out.needed;
1786 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1788 torture_assert_ntstatus_ok(tctx,
1789 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1790 "QueryMultipleValues2 failed");
1793 torture_assert_werr_ok(tctx, r.out.result,
1794 "QueryMultipleValues2 failed");
1796 return true;
1799 static bool test_QueryMultipleValues2(struct dcerpc_binding_handle *b,
1800 struct torture_context *tctx,
1801 struct policy_handle *handle,
1802 const char *valuename)
1804 struct winreg_QueryMultipleValues2 r;
1805 uint32_t offered = 0, needed;
1807 ZERO_STRUCT(r);
1809 r.in.key_handle = handle;
1810 r.in.values_in = r.out.values_out = talloc_zero_array(tctx, struct QueryMultipleValue, 1);
1811 r.in.values_in[0].ve_valuename = talloc(tctx, struct winreg_ValNameBuf);
1812 r.in.values_in[0].ve_valuename->name = valuename;
1813 /* size needs to be set manually for winreg_ValNameBuf */
1814 r.in.values_in[0].ve_valuename->size = strlen_m_term(valuename)*2;
1816 r.in.num_values = 1;
1817 r.in.offered = &offered;
1818 r.out.needed = &needed;
1820 torture_assert_ntstatus_ok(tctx,
1821 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1822 "QueryMultipleValues2 failed");
1823 if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
1824 *r.in.offered = *r.out.needed;
1825 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t, *r.in.offered);
1827 torture_assert_ntstatus_ok(tctx,
1828 dcerpc_winreg_QueryMultipleValues2_r(b, tctx, &r),
1829 "QueryMultipleValues2 failed");
1832 torture_assert_werr_ok(tctx, r.out.result,
1833 "QueryMultipleValues2 failed");
1835 return true;
1838 static bool test_QueryValue(struct dcerpc_binding_handle *b,
1839 struct torture_context *tctx,
1840 struct policy_handle *handle,
1841 const char *valuename)
1843 struct winreg_QueryValue r;
1844 NTSTATUS status;
1845 enum winreg_Type zero_type = 0;
1846 uint32_t offered = 0xfff;
1847 uint32_t zero = 0;
1849 ZERO_STRUCT(r);
1850 r.in.handle = handle;
1851 r.in.data = NULL;
1852 r.in.value_name = talloc_zero(tctx, struct winreg_String);
1853 r.in.value_name->name = valuename;
1854 r.in.type = &zero_type;
1855 r.in.data_size = &offered;
1856 r.in.data_length = &zero;
1858 status = dcerpc_winreg_QueryValue_r(b, tctx, &r);
1859 if (NT_STATUS_IS_ERR(status)) {
1860 torture_fail(tctx, "QueryValue failed");
1863 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1865 return true;
1868 static bool test_QueryValue_full(struct dcerpc_binding_handle *b,
1869 struct torture_context *tctx,
1870 struct policy_handle *handle,
1871 const char *valuename,
1872 bool existing_value)
1874 struct winreg_QueryValue r;
1875 struct winreg_String value_name;
1876 enum winreg_Type type = REG_NONE;
1877 uint32_t data_size = 0;
1878 uint32_t real_data_size = 0;
1879 uint32_t data_length = 0;
1880 uint8_t *data = NULL;
1881 WERROR expected_error = WERR_BADFILE;
1882 const char *errmsg_nonexisting = "expected WERR_BADFILE for nonexisting value";
1884 if (valuename == NULL) {
1885 expected_error = WERR_INVALID_PARAM;
1886 errmsg_nonexisting = "expected WERR_INVALID_PARAM for NULL valuename";
1889 ZERO_STRUCT(r);
1891 init_winreg_String(&value_name, NULL);
1893 torture_comment(tctx, "Testing QueryValue(%s)\n", valuename);
1895 r.in.handle = handle;
1896 r.in.value_name = &value_name;
1898 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r), "QueryValue failed");
1899 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1900 "expected WERR_INVALID_PARAM for NULL winreg_String.name");
1902 init_winreg_String(&value_name, valuename);
1903 r.in.value_name = &value_name;
1905 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1906 "QueryValue failed");
1907 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1908 "expected WERR_INVALID_PARAM for missing type length and size");
1910 r.in.type = &type;
1911 r.out.type = &type;
1912 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1913 "QueryValue failed");
1914 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1915 "expected WERR_INVALID_PARAM for missing length and size");
1917 r.in.data_length = &data_length;
1918 r.out.data_length = &data_length;
1919 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1920 "QueryValue failed");
1921 torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
1922 "expected WERR_INVALID_PARAM for missing size");
1924 r.in.data_size = &data_size;
1925 r.out.data_size = &data_size;
1926 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1927 "QueryValue failed");
1928 if (existing_value) {
1929 torture_assert_werr_ok(tctx, r.out.result,
1930 "QueryValue failed");
1931 } else {
1932 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1933 errmsg_nonexisting);
1936 real_data_size = *r.out.data_size;
1938 data = talloc_zero_array(tctx, uint8_t, 0);
1939 r.in.data = data;
1940 r.out.data = data;
1941 *r.in.data_size = 0;
1942 *r.out.data_size = 0;
1943 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1944 "QueryValue failed");
1945 if (existing_value) {
1946 torture_assert_werr_equal(tctx, r.out.result, WERR_MORE_DATA,
1947 "expected WERR_MORE_DATA for query with too small buffer");
1948 } else {
1949 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1950 errmsg_nonexisting);
1953 data = talloc_zero_array(tctx, uint8_t, real_data_size);
1954 r.in.data = data;
1955 r.out.data = data;
1956 r.in.data_size = &real_data_size;
1957 r.out.data_size = &real_data_size;
1958 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_QueryValue_r(b, tctx, &r),
1959 "QueryValue failed");
1960 if (existing_value) {
1961 torture_assert_werr_ok(tctx, r.out.result,
1962 "QueryValue failed");
1963 } else {
1964 torture_assert_werr_equal(tctx, r.out.result, expected_error,
1965 errmsg_nonexisting);
1968 return true;
1971 static bool test_EnumValue(struct dcerpc_binding_handle *b,
1972 struct torture_context *tctx,
1973 struct policy_handle *handle, int max_valnamelen,
1974 int max_valbufsize)
1976 struct winreg_EnumValue r;
1977 enum winreg_Type type = 0;
1978 uint32_t size = max_valbufsize, zero = 0;
1979 bool ret = true;
1980 uint8_t *data = NULL;
1981 struct winreg_ValNameBuf name;
1982 char n = '\0';
1984 ZERO_STRUCT(r);
1985 r.in.handle = handle;
1986 r.in.enum_index = 0;
1987 r.in.name = &name;
1988 r.out.name = &name;
1989 r.in.type = &type;
1990 r.in.length = &zero;
1991 r.in.size = &size;
1993 do {
1994 name.name = &n;
1995 name.size = max_valnamelen + 2;
1996 name.length = 0;
1998 data = NULL;
1999 if (size) {
2000 data = (uint8_t *) talloc_array(tctx, uint8_t *, size);
2002 r.in.value = data;
2004 torture_assert_ntstatus_ok(tctx,
2005 dcerpc_winreg_EnumValue_r(b, tctx, &r),
2006 "EnumValue failed");
2008 if (W_ERROR_IS_OK(r.out.result)) {
2009 ret &= test_QueryValue(b, tctx, handle,
2010 r.out.name->name);
2011 ret &= test_QueryMultipleValues(b, tctx, handle,
2012 r.out.name->name);
2013 ret &= test_QueryMultipleValues2(b, tctx, handle,
2014 r.out.name->name);
2017 talloc_free(data);
2019 r.in.enum_index++;
2020 } while (W_ERROR_IS_OK(r.out.result));
2022 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
2023 "EnumValue failed");
2025 return ret;
2028 static bool test_AbortSystemShutdown(struct dcerpc_binding_handle *b,
2029 struct torture_context *tctx)
2031 struct winreg_AbortSystemShutdown r;
2032 uint16_t server = 0x0;
2034 ZERO_STRUCT(r);
2035 r.in.server = &server;
2037 torture_assert_ntstatus_ok(tctx,
2038 dcerpc_winreg_AbortSystemShutdown_r(b, tctx, &r),
2039 "AbortSystemShutdown failed");
2041 torture_assert_werr_ok(tctx, r.out.result,
2042 "AbortSystemShutdown failed");
2044 return true;
2047 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
2048 struct dcerpc_pipe *p)
2050 struct winreg_InitiateSystemShutdown r;
2051 uint16_t hostname = 0x0;
2052 struct dcerpc_binding_handle *b = p->binding_handle;
2054 ZERO_STRUCT(r);
2055 r.in.hostname = &hostname;
2056 r.in.message = talloc(tctx, struct lsa_StringLarge);
2057 init_lsa_StringLarge(r.in.message, "spottyfood");
2058 r.in.force_apps = 1;
2059 r.in.timeout = 30;
2060 r.in.do_reboot = 1;
2062 torture_assert_ntstatus_ok(tctx,
2063 dcerpc_winreg_InitiateSystemShutdown_r(b, tctx, &r),
2064 "InitiateSystemShutdown failed");
2066 torture_assert_werr_ok(tctx, r.out.result,
2067 "InitiateSystemShutdown failed");
2069 return test_AbortSystemShutdown(b, tctx);
2073 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
2074 struct dcerpc_pipe *p)
2076 struct winreg_InitiateSystemShutdownEx r;
2077 uint16_t hostname = 0x0;
2078 struct dcerpc_binding_handle *b = p->binding_handle;
2080 ZERO_STRUCT(r);
2081 r.in.hostname = &hostname;
2082 r.in.message = talloc(tctx, struct lsa_StringLarge);
2083 init_lsa_StringLarge(r.in.message, "spottyfood");
2084 r.in.force_apps = 1;
2085 r.in.timeout = 30;
2086 r.in.do_reboot = 1;
2087 r.in.reason = 0;
2089 torture_assert_ntstatus_ok(tctx,
2090 dcerpc_winreg_InitiateSystemShutdownEx_r(b, tctx, &r),
2091 "InitiateSystemShutdownEx failed");
2093 torture_assert_werr_ok(tctx, r.out.result,
2094 "InitiateSystemShutdownEx failed");
2096 return test_AbortSystemShutdown(b, tctx);
2098 #define MAX_DEPTH 2 /* Only go this far down the tree */
2100 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
2101 struct policy_handle *handle, int depth,
2102 bool test_security)
2104 struct dcerpc_binding_handle *b = p->binding_handle;
2105 uint32_t max_valnamelen = 0;
2106 uint32_t max_valbufsize = 0;
2108 if (depth == MAX_DEPTH)
2109 return true;
2111 if (!test_QueryInfoKey(b, tctx, handle, NULL,
2112 &max_valnamelen, &max_valbufsize)) {
2115 if (!test_NotifyChangeKeyValue(b, tctx, handle)) {
2118 if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
2121 if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
2124 if (!test_EnumValue(b, tctx, handle, max_valnamelen, max_valbufsize)) {
2127 if (!test_EnumValue(b, tctx, handle, max_valnamelen, 0xFFFF)) {
2130 test_CloseKey(b, tctx, handle);
2132 return true;
2135 static bool test_SetValue_simple(struct dcerpc_binding_handle *b,
2136 struct torture_context *tctx,
2137 struct policy_handle *handle)
2139 const char *value_name = TEST_VALUE;
2140 uint32_t value = 0x12345678;
2141 uint64_t value2 = 0x12345678;
2142 const char *string = "torture";
2143 const char *array[2];
2144 DATA_BLOB blob;
2145 enum winreg_Type types[] = {
2146 REG_DWORD,
2147 REG_DWORD_BIG_ENDIAN,
2148 REG_QWORD,
2149 REG_BINARY,
2150 REG_SZ,
2151 REG_MULTI_SZ
2153 int t;
2155 array[0] = "array0";
2156 array[1] = NULL;
2158 torture_comment(tctx, "Testing SetValue (standard formats)\n");
2160 for (t=0; t < ARRAY_SIZE(types); t++) {
2162 enum winreg_Type w_type;
2163 uint32_t w_size, w_length;
2164 uint8_t *w_data;
2166 switch (types[t]) {
2167 case REG_DWORD:
2168 case REG_DWORD_BIG_ENDIAN:
2169 blob = data_blob_talloc_zero(tctx, 4);
2170 SIVAL(blob.data, 0, value);
2171 break;
2172 case REG_QWORD:
2173 blob = data_blob_talloc_zero(tctx, 8);
2174 SBVAL(blob.data, 0, value2);
2175 break;
2176 case REG_BINARY:
2177 blob = data_blob_string_const("binary_blob");
2178 break;
2179 case REG_SZ:
2180 torture_assert(tctx, push_reg_sz(tctx, &blob, string), "failed to push REG_SZ");
2181 break;
2182 case REG_MULTI_SZ:
2183 torture_assert(tctx, push_reg_multi_sz(tctx, &blob, array), "failed to push REG_MULTI_SZ");
2184 break;
2185 default:
2186 break;
2189 torture_assert(tctx,
2190 test_SetValue(b, tctx, handle, value_name, types[t], blob.data, blob.length),
2191 "test_SetValue failed");
2192 torture_assert(tctx,
2193 test_QueryValue_full(b, tctx, handle, value_name, true),
2194 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", value_name));
2195 torture_assert(tctx,
2196 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2197 "test_winreg_QueryValue failed");
2198 torture_assert(tctx,
2199 test_DeleteValue(b, tctx, handle, value_name),
2200 "test_DeleteValue failed");
2202 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2203 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2204 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2205 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2208 torture_comment(tctx, "Testing SetValue (standard formats) succeeded\n");
2210 return true;
2213 static bool test_SetValue_values(struct dcerpc_binding_handle *b,
2214 struct torture_context *tctx,
2215 struct policy_handle *handle)
2217 DATA_BLOB blob;
2218 const char *values[] = {
2219 "torture_value",
2220 "torture value",
2221 "torture,value",
2222 "torture;value",
2223 "torture/value",
2224 "torture\\value",
2225 "torture_value_name",
2226 "torture value name",
2227 "torture,value,name",
2228 "torture;value;name",
2229 "torture/value/name",
2230 "torture\\value\\name",
2232 int i;
2234 torture_comment(tctx, "Testing SetValue (values)\n");
2236 for (i=0; i < ARRAY_SIZE(values); i++) {
2238 enum winreg_Type w_type;
2239 uint32_t w_size, w_length;
2240 uint8_t *w_data;
2242 blob = data_blob_talloc(tctx, NULL, 32);
2244 generate_random_buffer(blob.data, 32);
2246 torture_assert(tctx,
2247 test_SetValue(b, tctx, handle, values[i], REG_BINARY, blob.data, blob.length),
2248 "test_SetValue failed");
2249 torture_assert(tctx,
2250 test_QueryValue_full(b, tctx, handle, values[i], true),
2251 talloc_asprintf(tctx, "test_QueryValue_full for %s value failed", values[i]));
2252 torture_assert(tctx,
2253 test_winreg_QueryValue(tctx, b, handle, values[i], &w_type, &w_size, &w_length, &w_data),
2254 "test_winreg_QueryValue failed");
2255 torture_assert(tctx,
2256 test_DeleteValue(b, tctx, handle, values[i]),
2257 "test_DeleteValue failed");
2259 torture_assert_int_equal(tctx, w_type, REG_BINARY, "winreg type mismatch");
2260 torture_assert_int_equal(tctx, w_size, blob.length, "winreg size mismatch");
2261 torture_assert_int_equal(tctx, w_length, blob.length, "winreg length mismatch");
2262 torture_assert_mem_equal(tctx, w_data, blob.data, blob.length, "winreg buffer mismatch");
2265 torture_comment(tctx, "Testing SetValue (values) succeeded\n");
2267 return true;
2270 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_binding_handle *, TALLOC_CTX *, void *);
2272 static bool test_SetValue_extended(struct dcerpc_binding_handle *b,
2273 struct torture_context *tctx,
2274 struct policy_handle *handle)
2276 const char *value_name = TEST_VALUE;
2277 enum winreg_Type types[] = {
2278 REG_NONE,
2279 REG_SZ,
2280 REG_EXPAND_SZ,
2281 REG_BINARY,
2282 REG_DWORD,
2283 REG_DWORD_BIG_ENDIAN,
2284 REG_LINK,
2285 REG_MULTI_SZ,
2286 REG_RESOURCE_LIST,
2287 REG_FULL_RESOURCE_DESCRIPTOR,
2288 REG_RESOURCE_REQUIREMENTS_LIST,
2289 REG_QWORD,
2294 123456,
2295 653210,
2296 __LINE__
2298 int t, l;
2300 if (torture_setting_bool(tctx, "samba4", false)) {
2301 torture_skip(tctx, "skipping extended SetValue test against Samba4");
2304 torture_comment(tctx, "Testing SetValue (extended formats)\n");
2306 for (t=0; t < ARRAY_SIZE(types); t++) {
2307 for (l=0; l < 16; l++) {
2309 enum winreg_Type w_type;
2310 uint32_t w_size, w_length;
2311 uint8_t *w_data;
2313 uint32_t size;
2314 uint8_t *data;
2316 size = l;
2317 data = talloc_array(tctx, uint8_t, size);
2319 generate_random_buffer(data, size);
2321 torture_assert(tctx,
2322 test_SetValue(b, tctx, handle, value_name, types[t], data, size),
2323 "test_SetValue failed");
2325 torture_assert(tctx,
2326 test_winreg_QueryValue(tctx, b, handle, value_name, &w_type, &w_size, &w_length, &w_data),
2327 "test_winreg_QueryValue failed");
2329 torture_assert(tctx,
2330 test_DeleteValue(b, tctx, handle, value_name),
2331 "test_DeleteValue failed");
2333 torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
2334 torture_assert_int_equal(tctx, w_size, size, "winreg size mismatch");
2335 torture_assert_int_equal(tctx, w_length, size, "winreg length mismatch");
2336 torture_assert_mem_equal(tctx, w_data, data, size, "winreg buffer mismatch");
2340 torture_comment(tctx, "Testing SetValue (extended formats) succeeded\n");
2342 return true;
2345 static bool test_create_keynames(struct dcerpc_binding_handle *b,
2346 struct torture_context *tctx,
2347 struct policy_handle *handle)
2349 const char *keys[] = {
2350 "torture_key",
2351 "torture key",
2352 "torture,key",
2353 "torture/key",
2354 "torture\\key",
2356 int i;
2358 for (i=0; i < ARRAY_SIZE(keys); i++) {
2360 enum winreg_CreateAction action_taken;
2361 struct policy_handle new_handle;
2362 char *q, *tmp;
2364 torture_assert(tctx,
2365 test_CreateKey_opts(tctx, b, handle, keys[i], NULL,
2366 REG_OPTION_NON_VOLATILE,
2367 SEC_FLAG_MAXIMUM_ALLOWED,
2368 NULL,
2369 WERR_OK,
2370 &action_taken,
2371 &new_handle),
2372 talloc_asprintf(tctx, "failed to create '%s' key", keys[i]));
2374 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2376 torture_assert(tctx,
2377 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_OK),
2378 "failed to delete key");
2380 torture_assert(tctx,
2381 test_DeleteKey_opts(b, tctx, handle, keys[i], WERR_BADFILE),
2382 "failed 2nd delete key");
2384 tmp = talloc_strdup(tctx, keys[i]);
2386 q = strchr(tmp, '\\');
2387 if (q != NULL) {
2388 *q = '\0';
2389 q++;
2391 torture_assert(tctx,
2392 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_OK),
2393 "failed to delete key");
2395 torture_assert(tctx,
2396 test_DeleteKey_opts(b, tctx, handle, tmp, WERR_BADFILE),
2397 "failed 2nd delete key");
2401 return true;
2404 #define KEY_CURRENT_VERSION "SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION"
2405 #define VALUE_CURRENT_VERSION "CurrentVersion"
2406 #define VALUE_SYSTEM_ROOT "SystemRoot"
2408 static const struct {
2409 const char *values[3];
2410 uint32_t num_values;
2411 bool existing_value;
2412 const char *error_message;
2413 } multiple_values_tests[] = {
2415 .values = { VALUE_CURRENT_VERSION, NULL, NULL },
2416 .num_values = 1,
2417 .existing_value = true,
2418 .error_message = NULL
2420 .values = { VALUE_SYSTEM_ROOT, NULL, NULL },
2421 .num_values = 1,
2422 .existing_value = true,
2423 .error_message = NULL
2425 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT, NULL },
2426 .num_values = 2,
2427 .existing_value = true,
2428 .error_message = NULL
2430 .values = { VALUE_CURRENT_VERSION, VALUE_SYSTEM_ROOT,
2431 VALUE_CURRENT_VERSION },
2432 .num_values = 3,
2433 .existing_value = true,
2434 .error_message = NULL
2436 .values = { VALUE_CURRENT_VERSION, NULL, VALUE_SYSTEM_ROOT },
2437 .num_values = 3,
2438 .existing_value = false,
2439 .error_message = NULL
2441 .values = { VALUE_CURRENT_VERSION, "", VALUE_SYSTEM_ROOT },
2442 .num_values = 3,
2443 .existing_value = false,
2444 .error_message = NULL
2446 .values = { "IDoNotExist", NULL, NULL },
2447 .num_values = 1,
2448 .existing_value = false,
2449 .error_message = NULL
2451 .values = { "IDoNotExist", VALUE_CURRENT_VERSION, NULL },
2452 .num_values = 2,
2453 .existing_value = false,
2454 .error_message = NULL
2456 .values = { VALUE_CURRENT_VERSION, "IDoNotExist", NULL },
2457 .num_values = 2,
2458 .existing_value = false,
2459 .error_message = NULL
2463 static bool test_HKLM_wellknown(struct torture_context *tctx,
2464 struct dcerpc_binding_handle *b,
2465 struct policy_handle *handle)
2467 struct policy_handle newhandle;
2468 int i;
2470 /* FIXME: s3 does not support SEC_FLAG_MAXIMUM_ALLOWED yet */
2471 if (torture_setting_bool(tctx, "samba3", false)) {
2472 torture_assert(tctx, test_OpenKey_opts(tctx, b, handle,
2473 KEY_CURRENT_VERSION,
2474 REG_OPTION_NON_VOLATILE,
2475 KEY_QUERY_VALUE,
2476 &newhandle,
2477 WERR_OK),
2478 "failed to open current version key");
2479 } else {
2480 torture_assert(tctx, test_OpenKey(b, tctx, handle, KEY_CURRENT_VERSION, &newhandle),
2481 "failed to open current version key");
2484 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, VALUE_CURRENT_VERSION, true),
2485 "failed to query current version");
2486 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "IDoNotExist", false),
2487 "succeeded to query nonexistent value");
2488 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, NULL, false),
2489 "succeeded to query value with NULL name");
2490 torture_assert(tctx, test_QueryValue_full(b, tctx, &newhandle, "", false),
2491 "succeeded to query nonexistent default value (\"\")");
2493 if (torture_setting_bool(tctx, "samba4", false)) {
2494 torture_comment(tctx, "skipping QueryMultipleValues{2} tests against Samba4\n");
2495 goto close_key;
2498 for (i=0; i < ARRAY_SIZE(multiple_values_tests); i++) {
2499 const char *msg;
2500 msg = talloc_asprintf(tctx,
2501 "failed to query %d %sexisting values\n",
2502 multiple_values_tests[i].num_values,
2503 multiple_values_tests[i].existing_value ? "":"non");
2505 torture_assert(tctx,
2506 test_QueryMultipleValues_full(b, tctx, &newhandle,
2507 multiple_values_tests[i].num_values,
2508 multiple_values_tests[i].values,
2509 multiple_values_tests[i].existing_value),
2510 msg);
2511 torture_assert(tctx,
2512 test_QueryMultipleValues2_full(b, tctx, &newhandle,
2513 multiple_values_tests[i].num_values,
2514 multiple_values_tests[i].values,
2515 multiple_values_tests[i].existing_value),
2516 msg);
2519 close_key:
2520 torture_assert(tctx, test_CloseKey(b, tctx, &newhandle),
2521 "failed to close current version key");
2523 return true;
2526 static bool test_OpenHive(struct torture_context *tctx,
2527 struct dcerpc_binding_handle *b,
2528 struct policy_handle *handle,
2529 int hkey)
2531 struct winreg_OpenHKLM r;
2533 r.in.system_name = 0;
2534 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2535 r.out.handle = handle;
2537 switch (hkey) {
2538 case HKEY_LOCAL_MACHINE:
2539 torture_assert_ntstatus_ok(tctx,
2540 dcerpc_winreg_OpenHKLM_r(b, tctx, &r),
2541 "failed to open HKLM");
2542 torture_assert_werr_ok(tctx, r.out.result,
2543 "failed to open HKLM");
2544 break;
2545 case HKEY_CURRENT_USER:
2546 torture_assert_ntstatus_ok(tctx,
2547 dcerpc_winreg_OpenHKCU_r(b, tctx, (struct winreg_OpenHKCU *)(void *)&r),
2548 "failed to open HKCU");
2549 torture_assert_werr_ok(tctx, r.out.result,
2550 "failed to open HKCU");
2551 break;
2552 case HKEY_USERS:
2553 torture_assert_ntstatus_ok(tctx,
2554 dcerpc_winreg_OpenHKU_r(b, tctx, (struct winreg_OpenHKU *)(void *)&r),
2555 "failed to open HKU");
2556 torture_assert_werr_ok(tctx, r.out.result,
2557 "failed to open HKU");
2558 break;
2559 case HKEY_CLASSES_ROOT:
2560 torture_assert_ntstatus_ok(tctx,
2561 dcerpc_winreg_OpenHKCR_r(b, tctx, (struct winreg_OpenHKCR *)(void *)&r),
2562 "failed to open HKCR");
2563 torture_assert_werr_ok(tctx, r.out.result,
2564 "failed to open HKCR");
2565 break;
2566 default:
2567 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2568 return false;
2571 return true;
2574 static bool test_volatile_keys(struct torture_context *tctx,
2575 struct dcerpc_binding_handle *b,
2576 struct policy_handle *handle,
2577 int hkey)
2579 struct policy_handle new_handle, hive_handle;
2580 enum winreg_CreateAction action_taken;
2582 torture_comment(tctx, "Testing VOLATILE key\n");
2584 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE);
2586 torture_assert(tctx,
2587 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2588 REG_OPTION_VOLATILE,
2589 SEC_FLAG_MAXIMUM_ALLOWED,
2590 NULL,
2591 WERR_OK,
2592 &action_taken,
2593 &new_handle),
2594 "failed to create REG_OPTION_VOLATILE type key");
2596 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2598 torture_assert(tctx,
2599 test_CreateKey_opts(tctx, b, &new_handle, TEST_SUBKEY_VOLATILE, NULL,
2600 REG_OPTION_NON_VOLATILE,
2601 SEC_FLAG_MAXIMUM_ALLOWED,
2602 NULL,
2603 WERR_CHILD_MUST_BE_VOLATILE,
2604 NULL,
2605 NULL),
2606 "failed to fail create REG_OPTION_VOLATILE type key");
2608 torture_assert(tctx,
2609 test_CloseKey(b, tctx, &new_handle),
2610 "failed to close");
2612 torture_assert(tctx,
2613 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2614 REG_OPTION_NON_VOLATILE,
2615 SEC_FLAG_MAXIMUM_ALLOWED,
2616 &new_handle,
2617 WERR_OK),
2618 "failed to open volatile key");
2620 torture_assert(tctx,
2621 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2622 "failed to delete key");
2624 torture_assert(tctx,
2625 test_CreateKey_opts(tctx, b, handle, TEST_KEY_VOLATILE, NULL,
2626 REG_OPTION_VOLATILE,
2627 SEC_FLAG_MAXIMUM_ALLOWED,
2628 NULL,
2629 WERR_OK,
2630 &action_taken,
2631 &new_handle),
2632 "failed to create REG_OPTION_VOLATILE type key");
2634 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2636 torture_assert(tctx,
2637 test_CloseKey(b, tctx, &new_handle),
2638 "failed to close");
2640 torture_assert(tctx,
2641 test_OpenKey_opts(tctx, b, handle, TEST_KEY_VOLATILE,
2642 REG_OPTION_VOLATILE,
2643 SEC_FLAG_MAXIMUM_ALLOWED,
2644 &new_handle,
2645 WERR_OK),
2646 "failed to open volatile key");
2648 torture_assert(tctx,
2649 test_CloseKey(b, tctx, &new_handle),
2650 "failed to close");
2652 torture_assert(tctx,
2653 test_OpenHive(tctx, b, &hive_handle, hkey),
2654 "failed top open hive");
2656 torture_assert(tctx,
2657 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2658 REG_OPTION_VOLATILE,
2659 SEC_FLAG_MAXIMUM_ALLOWED,
2660 &new_handle,
2661 WERR_BADFILE),
2662 "failed to open volatile key");
2664 torture_assert(tctx,
2665 test_OpenKey_opts(tctx, b, &hive_handle, TEST_KEY_VOLATILE,
2666 REG_OPTION_NON_VOLATILE,
2667 SEC_FLAG_MAXIMUM_ALLOWED,
2668 &new_handle,
2669 WERR_BADFILE),
2670 "failed to open volatile key");
2672 torture_assert(tctx,
2673 test_CloseKey(b, tctx, &hive_handle),
2674 "failed to close");
2676 torture_assert(tctx,
2677 test_DeleteKey(b, tctx, handle, TEST_KEY_VOLATILE),
2678 "failed to delete key");
2681 torture_comment(tctx, "Testing VOLATILE key succeeded\n");
2683 return true;
2686 static const char *kernel_mode_registry_path(struct torture_context *tctx,
2687 int hkey,
2688 const char *sid_string,
2689 const char *path)
2691 switch (hkey) {
2692 case HKEY_LOCAL_MACHINE:
2693 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\%s", path);
2694 case HKEY_CURRENT_USER:
2695 return talloc_asprintf(tctx, "\\Registry\\USER\\%s\\%s", sid_string, path);
2696 case HKEY_USERS:
2697 return talloc_asprintf(tctx, "\\Registry\\USER\\%s", path);
2698 case HKEY_CLASSES_ROOT:
2699 return talloc_asprintf(tctx, "\\Registry\\MACHINE\\Software\\Classes\\%s", path);
2700 default:
2701 torture_warning(tctx, "unsupported hkey: 0x%08x\n", hkey);
2702 return NULL;
2706 static bool test_symlink_keys(struct torture_context *tctx,
2707 struct dcerpc_binding_handle *b,
2708 struct policy_handle *handle,
2709 const char *key,
2710 int hkey)
2712 struct policy_handle new_handle;
2713 enum winreg_CreateAction action_taken;
2714 DATA_BLOB blob;
2715 uint32_t value = 42;
2716 const char *test_key_symlink_dest;
2717 const char *test_key_symlink;
2718 const char *kernel_mode_path;
2720 /* disable until we know how to delete a symbolic link */
2721 torture_skip(tctx, "symlink test disabled");
2723 torture_comment(tctx, "Testing REG_OPTION_CREATE_LINK key\n");
2725 /* create destination key with testvalue */
2726 test_key_symlink = talloc_asprintf(tctx, "%s\\%s",
2727 key, TEST_KEY_SYMLINK);
2728 test_key_symlink_dest = talloc_asprintf(tctx, "%s\\%s",
2729 key, TEST_KEY_SYMLINK_DEST);
2731 test_DeleteKey(b, tctx, handle, test_key_symlink);
2733 torture_assert(tctx,
2734 test_CreateKey_opts(tctx, b, handle, test_key_symlink_dest, NULL,
2736 SEC_FLAG_MAXIMUM_ALLOWED,
2737 NULL,
2738 WERR_OK,
2739 &action_taken,
2740 &new_handle),
2741 "failed to create symlink destination");
2743 blob = data_blob_talloc_zero(tctx, 4);
2744 SIVAL(blob.data, 0, value);
2746 torture_assert(tctx,
2747 test_SetValue(b, tctx, &new_handle, "TestValue", REG_DWORD, blob.data, blob.length),
2748 "failed to create TestValue");
2750 torture_assert(tctx,
2751 test_CloseKey(b, tctx, &new_handle),
2752 "failed to close");
2754 /* create symlink */
2756 torture_assert(tctx,
2757 test_CreateKey_opts(tctx, b, handle, test_key_symlink, NULL,
2758 REG_OPTION_CREATE_LINK | REG_OPTION_VOLATILE,
2759 SEC_FLAG_MAXIMUM_ALLOWED,
2760 NULL,
2761 WERR_OK,
2762 &action_taken,
2763 &new_handle),
2764 "failed to create REG_OPTION_CREATE_LINK type key");
2766 torture_assert_int_equal(tctx, action_taken, REG_CREATED_NEW_KEY, "unexpected action");
2768 kernel_mode_path = kernel_mode_registry_path(tctx, hkey, NULL, test_key_symlink_dest);
2770 torture_assert(tctx,
2771 convert_string_talloc(tctx, CH_UNIX, CH_UTF16,
2772 kernel_mode_path,
2773 strlen(kernel_mode_path), /* not NULL terminated */
2774 &blob.data, &blob.length),
2775 "failed to convert");
2777 torture_assert(tctx,
2778 test_SetValue(b, tctx, &new_handle, "SymbolicLinkValue", REG_LINK, blob.data, blob.length),
2779 "failed to create SymbolicLinkValue value");
2781 torture_assert(tctx,
2782 test_CloseKey(b, tctx, &new_handle),
2783 "failed to close");
2785 /* test follow symlink */
2787 torture_assert(tctx,
2788 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2790 SEC_FLAG_MAXIMUM_ALLOWED,
2791 &new_handle,
2792 WERR_OK),
2793 "failed to follow symlink key");
2795 torture_assert(tctx,
2796 test_QueryValue(b, tctx, &new_handle, "TestValue"),
2797 "failed to query value");
2799 torture_assert(tctx,
2800 test_CloseKey(b, tctx, &new_handle),
2801 "failed to close");
2803 /* delete link */
2805 torture_assert(tctx,
2806 test_OpenKey_opts(tctx, b, handle, test_key_symlink,
2807 REG_OPTION_OPEN_LINK | REG_OPTION_VOLATILE,
2808 SEC_FLAG_MAXIMUM_ALLOWED,
2809 &new_handle,
2810 WERR_OK),
2811 "failed to open symlink key");
2813 torture_assert(tctx,
2814 test_DeleteValue(b, tctx, &new_handle, "SymbolicLinkValue"),
2815 "failed to delete value SymbolicLinkValue");
2817 torture_assert(tctx,
2818 test_CloseKey(b, tctx, &new_handle),
2819 "failed to close");
2821 torture_assert(tctx,
2822 test_DeleteKey(b, tctx, handle, test_key_symlink),
2823 "failed to delete key");
2825 /* delete destination */
2827 torture_assert(tctx,
2828 test_DeleteKey(b, tctx, handle, test_key_symlink_dest),
2829 "failed to delete key");
2831 return true;
2834 static bool test_CreateKey_keytypes(struct torture_context *tctx,
2835 struct dcerpc_binding_handle *b,
2836 struct policy_handle *handle,
2837 const char *key,
2838 int hkey)
2841 if (torture_setting_bool(tctx, "samba3", false) ||
2842 torture_setting_bool(tctx, "samba4", false)) {
2843 torture_skip(tctx, "skipping CreateKey keytypes test against Samba");
2846 torture_assert(tctx,
2847 test_volatile_keys(tctx, b, handle, hkey),
2848 "failed to test volatile keys");
2850 torture_assert(tctx,
2851 test_symlink_keys(tctx, b, handle, key, hkey),
2852 "failed to test symlink keys");
2854 return true;
2857 static bool test_key_base(struct torture_context *tctx,
2858 struct dcerpc_binding_handle *b,
2859 struct policy_handle *handle,
2860 const char *base_key,
2861 int hkey)
2863 struct policy_handle newhandle;
2864 bool ret = true, created = false, deleted = false;
2865 bool created3 = false;
2866 const char *test_key1;
2867 const char *test_key3;
2868 const char *test_subkey;
2870 test_Cleanup(b, tctx, handle, base_key);
2872 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2873 torture_comment(tctx,
2874 "CreateKey(%s) failed\n", base_key);
2877 test_key1 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY1);
2879 if (!test_CreateKey(b, tctx, handle, test_key1, NULL)) {
2880 torture_comment(tctx,
2881 "CreateKey failed - not considering a failure\n");
2882 } else {
2883 created = true;
2886 if (created) {
2887 if (!test_FlushKey(b, tctx, handle)) {
2888 torture_comment(tctx, "FlushKey failed\n");
2889 ret = false;
2892 if (!test_OpenKey(b, tctx, handle, test_key1, &newhandle)) {
2893 torture_fail(tctx,
2894 "CreateKey failed (OpenKey after Create didn't work)\n");
2897 if (hkey == HKEY_CURRENT_USER) {
2898 torture_assert(tctx, test_SetValue_simple(b, tctx, &newhandle),
2899 "simple SetValue test failed");
2900 torture_assert(tctx, test_SetValue_values(b, tctx, &newhandle),
2901 "values SetValue test failed");
2902 torture_assert(tctx, test_SetValue_extended(b, tctx, &newhandle),
2903 "extended SetValue test failed");
2904 torture_assert(tctx, test_create_keynames(b, tctx, &newhandle),
2905 "keyname CreateKey test failed");
2906 } else {
2907 torture_assert(tctx, test_CreateKey_keytypes(tctx, b, &newhandle, test_key1, hkey),
2908 "keytype test failed");
2911 if (!test_CloseKey(b, tctx, &newhandle)) {
2912 torture_fail(tctx,
2913 "CreateKey failed (CloseKey after Open didn't work)\n");
2916 if (!test_DeleteKey(b, tctx, handle, test_key1)) {
2917 torture_comment(tctx, "DeleteKey(%s) failed\n",
2918 test_key1);
2919 ret = false;
2920 } else {
2921 deleted = true;
2924 if (!test_FlushKey(b, tctx, handle)) {
2925 torture_comment(tctx, "FlushKey failed\n");
2926 ret = false;
2929 if (deleted) {
2930 if (!test_OpenKey_opts(tctx, b, handle, test_key1,
2931 REG_OPTION_NON_VOLATILE,
2932 SEC_FLAG_MAXIMUM_ALLOWED,
2933 &newhandle,
2934 WERR_BADFILE)) {
2935 torture_comment(tctx,
2936 "DeleteKey failed (OpenKey after Delete "
2937 "did not return WERR_BADFILE)\n");
2938 ret = false;
2942 test_key3 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY3);
2944 if (test_CreateKey(b, tctx, handle, test_key3, NULL)) {
2945 created3 = true;
2948 test_subkey = talloc_asprintf(tctx, "%s\\%s", test_key3, TEST_SUBKEY);
2950 if (created3) {
2951 if (test_CreateKey(b, tctx, handle, test_subkey, NULL)) {
2952 if (!test_DeleteKey(b, tctx, handle, test_subkey)) {
2953 torture_comment(tctx, "DeleteKey(%s) failed\n", test_subkey);
2954 ret = false;
2958 if (!test_DeleteKey(b, tctx, handle, test_key3)) {
2959 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key3);
2960 ret = false;
2965 test_Cleanup(b, tctx, handle, base_key);
2967 return ret;
2970 static bool test_key_base_sd(struct torture_context *tctx,
2971 struct dcerpc_pipe *p,
2972 struct policy_handle *handle,
2973 const char *base_key)
2975 struct policy_handle newhandle;
2976 bool ret = true, created2 = false, created4 = false;
2977 struct dcerpc_binding_handle *b = p->binding_handle;
2978 const char *test_key2;
2979 const char *test_key4;
2981 torture_skip(tctx, "security descriptor test disabled\n");
2983 if (torture_setting_bool(tctx, "samba3", false) ||
2984 torture_setting_bool(tctx, "samba4", false)) {
2985 torture_skip(tctx, "skipping security descriptor tests against Samba");
2988 test_Cleanup(b, tctx, handle, base_key);
2990 if (!test_CreateKey(b, tctx, handle, base_key, NULL)) {
2991 torture_comment(tctx,
2992 "CreateKey(%s) failed\n", base_key);
2995 test_key2 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY2);
2997 if (test_CreateKey_sd(b, tctx, handle, test_key2,
2998 NULL, &newhandle)) {
2999 created2 = true;
3002 if (created2 && !test_CloseKey(b, tctx, &newhandle)) {
3003 torture_comment(tctx, "CloseKey failed\n");
3004 ret = false;
3007 test_key4 = talloc_asprintf(tctx, "%s\\%s", base_key, TEST_KEY4);
3009 if (test_CreateKey_sd(b, tctx, handle, test_key4, NULL, &newhandle)) {
3010 created4 = true;
3013 if (created4 && !test_CloseKey(b, tctx, &newhandle)) {
3014 torture_comment(tctx, "CloseKey failed\n");
3015 ret = false;
3018 if (created4 && !test_SecurityDescriptors(p, tctx, handle, test_key4)) {
3019 ret = false;
3022 if (created4 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3023 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3024 ret = false;
3027 if (created2 && !test_DeleteKey(b, tctx, handle, test_key4)) {
3028 torture_comment(tctx, "DeleteKey(%s) failed\n", test_key4);
3029 ret = false;
3032 test_Cleanup(b, tctx, handle, base_key);
3034 return ret;
3037 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
3038 void *userdata)
3040 struct policy_handle handle;
3041 bool ret = true;
3042 struct winreg_OpenHKLM r;
3043 struct dcerpc_binding_handle *b = p->binding_handle;
3044 const char *torture_base_key;
3045 int hkey = 0;
3047 winreg_open_fn open_fn = (winreg_open_fn)userdata;
3049 r.in.system_name = 0;
3050 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3051 r.out.handle = &handle;
3053 torture_assert_ntstatus_ok(tctx, open_fn(b, tctx, &r),
3054 "open");
3056 if (!test_GetVersion(b, tctx, &handle)) {
3057 torture_comment(tctx, "GetVersion failed\n");
3058 ret = false;
3061 if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKLM_r) {
3062 hkey = HKEY_LOCAL_MACHINE;
3063 torture_base_key = "SOFTWARE\\Samba\\" TEST_KEY_BASE;
3064 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKU_r) {
3065 hkey = HKEY_USERS;
3066 torture_base_key = TEST_KEY_BASE;
3067 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCR_r) {
3068 hkey = HKEY_CLASSES_ROOT;
3069 torture_base_key = TEST_KEY_BASE;
3070 } else if (open_fn == (winreg_open_fn)dcerpc_winreg_OpenHKCU_r) {
3071 hkey = HKEY_CURRENT_USER;
3072 torture_base_key = TEST_KEY_BASE;
3073 } else {
3074 torture_fail(tctx, "unsupported hkey");
3077 if (hkey == HKEY_LOCAL_MACHINE) {
3078 torture_assert(tctx,
3079 test_HKLM_wellknown(tctx, b, &handle),
3080 "failed to test HKLM wellknown keys");
3083 if (!test_key_base(tctx, b, &handle, torture_base_key, hkey)) {
3084 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s)",
3085 torture_base_key);
3086 ret = false;
3089 if (!test_key_base_sd(tctx, p, &handle, torture_base_key)) {
3090 torture_warning(tctx, "failed to test TEST_KEY_BASE(%s) sd",
3091 torture_base_key);
3092 ret = false;
3095 /* The HKCR hive has a very large fanout */
3096 if (hkey == HKEY_CLASSES_ROOT) {
3097 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
3098 ret = false;
3100 } else if (hkey == HKEY_LOCAL_MACHINE) {
3101 /* FIXME we are not allowed to enum values in the HKLM root */
3102 } else {
3103 if (!test_key(p, tctx, &handle, 0, false)) {
3104 ret = false;
3108 return ret;
3111 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
3113 struct torture_rpc_tcase *tcase;
3114 struct torture_suite *suite = torture_suite_create(mem_ctx, "winreg");
3115 struct torture_test *test;
3117 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
3118 &ndr_table_winreg);
3120 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
3121 test_InitiateSystemShutdown);
3122 test->dangerous = true;
3124 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
3125 test_InitiateSystemShutdownEx);
3126 test->dangerous = true;
3128 torture_rpc_tcase_add_test_ex(tcase, "HKLM",
3129 test_Open,
3130 (void *)dcerpc_winreg_OpenHKLM_r);
3131 torture_rpc_tcase_add_test_ex(tcase, "HKU",
3132 test_Open,
3133 (void *)dcerpc_winreg_OpenHKU_r);
3134 torture_rpc_tcase_add_test_ex(tcase, "HKCR",
3135 test_Open,
3136 (void *)dcerpc_winreg_OpenHKCR_r);
3137 torture_rpc_tcase_add_test_ex(tcase, "HKCU",
3138 test_Open,
3139 (void *)dcerpc_winreg_OpenHKCU_r);
3141 return suite;