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
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "torture/torture.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"
29 #define TEST_KEY_BASE "smbtorture test"
30 #define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
31 #define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
32 #define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
33 #define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
34 #define TEST_SUBKEY TEST_KEY3 "\\subkey"
35 #define TEST_SUBKEY_SD TEST_KEY4 "\\subkey_sd"
36 #define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
38 #define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
40 static void init_initshutdown_String(TALLOC_CTX *mem_ctx,
41 struct initshutdown_String *name,
44 name->name = talloc(mem_ctx, struct initshutdown_String_sub);
48 static void init_winreg_String(struct winreg_String *name, const char *s)
52 name->name_len = 2 * (strlen_m(s) + 1);
53 name->name_size = name->name_len;
60 static bool test_GetVersion(struct dcerpc_pipe *p,
61 struct torture_context *tctx,
62 struct policy_handle *handle)
64 struct winreg_GetVersion r;
71 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
74 torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
79 static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
80 struct torture_context *tctx,
81 struct policy_handle *handle)
83 struct winreg_NotifyChangeKeyValue r;
86 r.in.watch_subtree = true;
87 r.in.notify_filter = 0;
88 r.in.unknown = r.in.unknown2 = 0;
89 init_winreg_String(&r.in.string1, NULL);
90 init_winreg_String(&r.in.string2, NULL);
92 torture_assert_ntstatus_ok(tctx,
93 dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
94 "NotifyChangeKeyValue failed");
96 if (!W_ERROR_IS_OK(r.out.result)) {
98 "NotifyChangeKeyValue failed - %s - not considering\n",
99 win_errstr(r.out.result));
106 static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
107 struct policy_handle *handle, const char *name,
110 struct winreg_CreateKey r;
111 struct policy_handle newhandle;
112 enum winreg_CreateAction action_taken = 0;
114 r.in.handle = handle;
115 r.out.new_handle = &newhandle;
116 init_winreg_String(&r.in.name, name);
117 init_winreg_String(&r.in.keyclass, class);
119 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120 r.in.action_taken = r.out.action_taken = &action_taken;
123 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
126 torture_assert_werr_ok(tctx, r.out.result, "CreateKey failed");
133 createkey testing with a SD
135 static bool test_CreateKey_sd(struct dcerpc_pipe *p,
136 struct torture_context *tctx,
137 struct policy_handle *handle, const char *name,
139 struct policy_handle *newhandle)
141 struct winreg_CreateKey r;
142 enum winreg_CreateAction action_taken = 0;
143 struct security_descriptor *sd;
145 struct winreg_SecBuf secbuf;
147 sd = security_descriptor_dacl_create(tctx,
150 SID_NT_AUTHENTICATED_USERS,
151 SEC_ACE_TYPE_ACCESS_ALLOWED,
153 SEC_ACE_FLAG_OBJECT_INHERIT |
154 SEC_ACE_FLAG_CONTAINER_INHERIT,
157 torture_assert_ntstatus_ok(tctx,
158 ndr_push_struct_blob(&sdblob, tctx, sd,
159 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
160 "Failed to push security_descriptor ?!\n");
162 secbuf.sd.data = sdblob.data;
163 secbuf.sd.len = sdblob.length;
164 secbuf.sd.size = sdblob.length;
165 secbuf.length = sdblob.length-10;
168 r.in.handle = handle;
169 r.out.new_handle = newhandle;
170 init_winreg_String(&r.in.name, name);
171 init_winreg_String(&r.in.keyclass, class);
173 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
174 r.in.action_taken = r.out.action_taken = &action_taken;
175 r.in.secdesc = &secbuf;
177 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
178 "CreateKey with sd failed");
180 torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
185 static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
186 struct torture_context *tctx,
187 struct policy_handle *handle,
188 uint32_t *sec_info_ptr,
190 struct security_descriptor **sd_out)
192 struct winreg_GetKeySecurity r;
193 struct security_descriptor *sd = NULL;
198 sec_info = *sec_info_ptr;
200 sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
205 r.in.handle = handle;
206 r.in.sec_info = sec_info;
207 r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
208 r.in.sd->size = 0x1000;
210 torture_assert_ntstatus_ok(tctx,
211 dcerpc_winreg_GetKeySecurity(p, tctx, &r),
212 "GetKeySecurity failed");
214 torture_assert_werr_equal(tctx, r.out.result, get_werr,
215 "GetKeySecurity failed");
217 sdblob.data = r.out.sd->data;
218 sdblob.length = r.out.sd->len;
220 sd = talloc_zero(tctx, struct security_descriptor);
222 torture_assert_ntstatus_ok(tctx,
223 ndr_pull_struct_blob(&sdblob, tctx, sd,
224 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
225 "pull_security_descriptor failed");
227 if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
228 NDR_PRINT_DEBUG(security_descriptor, sd);
240 static bool test_GetKeySecurity(struct dcerpc_pipe *p,
241 struct torture_context *tctx,
242 struct policy_handle *handle,
243 struct security_descriptor **sd_out)
245 return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
248 static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
249 struct torture_context *tctx,
250 struct policy_handle *handle,
251 uint32_t *sec_info_ptr,
252 struct security_descriptor *sd,
255 struct winreg_SetKeySecurity r;
256 struct KeySecurityData *sdata = NULL;
262 if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
263 NDR_PRINT_DEBUG(security_descriptor, sd);
266 torture_assert_ntstatus_ok(tctx,
267 ndr_push_struct_blob(&sdblob, tctx, sd,
268 (ndr_push_flags_fn_t)ndr_push_security_descriptor),
269 "push_security_descriptor failed");
271 sdata = talloc_zero(tctx, struct KeySecurityData);
272 sdata->data = sdblob.data;
273 sdata->size = sdblob.length;
274 sdata->len = sdblob.length;
277 sec_info = *sec_info_ptr;
279 sec_info = SECINFO_UNPROTECTED_SACL |
280 SECINFO_UNPROTECTED_DACL;
282 sec_info |= SECINFO_OWNER;
285 sec_info |= SECINFO_GROUP;
288 sec_info |= SECINFO_SACL;
291 sec_info |= SECINFO_DACL;
295 r.in.handle = handle;
296 r.in.sec_info = sec_info;
299 torture_assert_ntstatus_ok(tctx,
300 dcerpc_winreg_SetKeySecurity(p, tctx, &r),
301 "SetKeySecurity failed");
303 torture_assert_werr_equal(tctx, r.out.result, werr,
304 "SetKeySecurity failed");
309 static bool test_SetKeySecurity(struct dcerpc_pipe *p,
310 struct torture_context *tctx,
311 struct policy_handle *handle,
312 struct security_descriptor *sd)
314 return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
317 static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
318 struct policy_handle *handle)
320 struct winreg_CloseKey r;
322 r.in.handle = r.out.handle = handle;
324 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
327 torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
332 static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
333 struct policy_handle *handle)
335 struct winreg_FlushKey r;
337 r.in.handle = handle;
339 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
342 torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
347 static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
348 struct policy_handle *hive_handle,
349 const char *keyname, struct policy_handle *key_handle)
351 struct winreg_OpenKey r;
353 r.in.parent_handle = hive_handle;
354 init_winreg_String(&r.in.keyname, keyname);
355 r.in.unknown = 0x00000000;
356 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
357 r.out.handle = key_handle;
359 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
362 torture_assert_werr_ok(tctx, r.out.result, "OpenKey failed");
367 static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
368 struct policy_handle *handle, const char *key)
370 struct winreg_DeleteKey r;
372 r.in.handle = handle;
374 init_winreg_String(&r.in.key, key);
375 dcerpc_winreg_DeleteKey(p, tctx, &r);
380 static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
381 struct torture_context *tctx,
382 struct policy_handle *handle,
386 struct security_descriptor *sd = NULL;
388 if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
392 if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
399 static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
400 struct torture_context *tctx,
401 struct policy_handle *handle,
404 struct policy_handle new_handle;
407 torture_comment(tctx, "SecurityDescriptor get & set\n");
409 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
413 if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
418 if (!test_CloseKey(p, tctx, &new_handle)) {
425 static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
426 struct torture_context *tctx,
427 struct policy_handle *handle,
428 const struct dom_sid *sid)
430 struct security_descriptor *sd = NULL;
433 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
437 if (!sd || !sd->dacl) {
441 for (i = 0; i < sd->dacl->num_aces; i++) {
442 if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
450 static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
451 struct torture_context *tctx,
452 struct policy_handle *handle,
453 const struct dom_sid *sid,
456 struct security_descriptor *sd = NULL;
459 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
463 if (!sd || !sd->dacl) {
467 for (i = 0; i < sd->dacl->num_aces; i++) {
468 if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
469 (sd->dacl->aces[i].flags == flags)) {
477 static bool test_dacl_ace_present(struct dcerpc_pipe *p,
478 struct torture_context *tctx,
479 struct policy_handle *handle,
480 const struct security_ace *ace)
482 struct security_descriptor *sd = NULL;
485 if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
489 if (!sd || !sd->dacl) {
493 for (i = 0; i < sd->dacl->num_aces; i++) {
494 if (security_ace_equal(&sd->dacl->aces[i], ace)) {
502 static bool test_RestoreSecurity(struct dcerpc_pipe *p,
503 struct torture_context *tctx,
504 struct policy_handle *handle,
506 struct security_descriptor *sd)
508 struct policy_handle new_handle;
511 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
515 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
519 if (!test_CloseKey(p, tctx, &new_handle)) {
526 static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
527 struct torture_context *tctx,
528 struct policy_handle *handle,
532 add ace SEC_ACE_FLAG_CONTAINER_INHERIT
547 struct security_descriptor *sd = NULL;
548 struct security_descriptor *sd_orig = NULL;
549 struct security_ace *ace = NULL;
550 struct policy_handle new_handle;
554 torture_comment(tctx, "SecurityDescriptor inheritance\n");
556 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
560 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
564 sd_orig = security_descriptor_copy(tctx, sd);
565 if (sd_orig == NULL) {
569 ace = security_ace_create(tctx,
571 SEC_ACE_TYPE_ACCESS_ALLOWED,
573 SEC_ACE_FLAG_CONTAINER_INHERIT);
575 status = security_descriptor_dacl_add(sd, ace);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("failed to add ace: %s\n", nt_errstr(status));
581 /* FIXME: add further tests for these flags */
582 sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
583 SEC_DESC_SACL_AUTO_INHERITED;
585 if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
589 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
590 printf("new ACE not present!\n");
594 if (!test_CloseKey(p, tctx, &new_handle)) {
598 if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
603 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
608 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
609 printf("inherited ACE not present!\n");
614 test_CloseKey(p, tctx, &new_handle);
615 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
620 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
625 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
626 printf("inherited ACE not present!\n");
632 test_CloseKey(p, tctx, &new_handle);
633 test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
634 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
635 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
640 static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
641 struct torture_context *tctx,
642 struct policy_handle *handle,
646 add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
658 struct security_descriptor *sd = NULL;
659 struct security_descriptor *sd_orig = NULL;
660 struct security_ace *ace = NULL;
661 struct policy_handle new_handle;
662 struct dom_sid *sid = NULL;
665 uint8_t ace_flags = 0x0;
667 torture_comment(tctx, "SecurityDescriptor inheritance block\n");
669 if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
673 if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
677 sd_orig = security_descriptor_copy(tctx, sd);
678 if (sd_orig == NULL) {
682 ace = security_ace_create(tctx,
684 SEC_ACE_TYPE_ACCESS_ALLOWED,
686 SEC_ACE_FLAG_CONTAINER_INHERIT |
687 SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
689 status = security_descriptor_dacl_add(sd, ace);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("failed to add ace: %s\n", nt_errstr(status));
695 if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
699 if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
700 printf("new ACE not present!\n");
704 if (!test_CloseKey(p, tctx, &new_handle)) {
708 if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
712 if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
717 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
718 printf("inherited ACE present but should not!\n");
723 sid = dom_sid_parse_talloc(tctx, TEST_SID);
728 if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
729 printf("inherited trustee SID present but should not!\n");
734 test_CloseKey(p, tctx, &new_handle);
736 if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
741 if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
742 printf("inherited ACE present but should not!\n");
747 if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
748 printf("inherited trustee SID with flags 0x%02x not present!\n",
755 test_CloseKey(p, tctx, &new_handle);
756 test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
757 test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
758 test_RestoreSecurity(p, tctx, handle, key, sd_orig);
763 static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
764 struct torture_context *tctx,
765 struct policy_handle *handle,
770 if (!test_SecurityDescriptor(p, tctx, handle, key)) {
771 printf("test_SecurityDescriptor failed\n");
775 if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
776 printf("test_SecurityDescriptorInheritance failed\n");
780 if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
781 printf("test_SecurityDescriptorBlockInheritance failed\n");
788 static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
789 struct policy_handle *handle, const char *key)
792 struct winreg_DeleteKey r;
794 r.in.handle = handle;
795 init_winreg_String(&r.in.key, key);
797 status = dcerpc_winreg_DeleteKey(p, tctx, &r);
799 torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
800 torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
805 /* DeleteKey on a key with subkey(s) should
806 * return WERR_ACCESS_DENIED. */
807 static bool test_DeleteKeyWithSubkey(struct dcerpc_pipe *p,
808 struct torture_context *tctx,
809 struct policy_handle *handle,
812 struct winreg_DeleteKey r;
814 r.in.handle = handle;
815 init_winreg_String(&r.in.key, key);
817 torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey(p, tctx, &r),
818 "DeleteKeyWithSubkey failed");
820 torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
821 "DeleteKeyWithSubkey failed");
826 static bool test_QueryInfoKey(struct dcerpc_pipe *p,
827 struct torture_context *tctx,
828 struct policy_handle *handle, char *class)
830 struct winreg_QueryInfoKey r;
831 uint32_t num_subkeys, max_subkeylen, max_subkeysize,
832 num_values, max_valnamelen, max_valbufsize,
834 NTTIME last_changed_time;
837 r.in.handle = handle;
838 r.out.num_subkeys = &num_subkeys;
839 r.out.max_subkeylen = &max_subkeylen;
840 r.out.max_subkeysize = &max_subkeysize;
841 r.out.num_values = &num_values;
842 r.out.max_valnamelen = &max_valnamelen;
843 r.out.max_valbufsize = &max_valbufsize;
844 r.out.secdescsize = &secdescsize;
845 r.out.last_changed_time = &last_changed_time;
847 r.out.classname = talloc(tctx, struct winreg_String);
849 r.in.classname = talloc(tctx, struct winreg_String);
850 init_winreg_String(r.in.classname, class);
852 torture_assert_ntstatus_ok(tctx,
853 dcerpc_winreg_QueryInfoKey(p, tctx, &r),
854 "QueryInfoKey failed");
856 torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
861 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
862 struct policy_handle *handle, int depth);
864 static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
865 struct policy_handle *handle, int depth)
867 struct winreg_EnumKey r;
868 struct winreg_StringBuf class, name;
875 r.in.handle = handle;
878 r.in.keyclass = &class;
880 r.in.last_changed_time = &t;
886 status = dcerpc_winreg_EnumKey(p, tctx, &r);
888 if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
889 struct policy_handle key_handle;
891 torture_comment(tctx, "EnumKey: %d: %s\n",
895 if (!test_OpenKey(p, tctx, handle, r.out.name->name,
898 test_key(p, tctx, &key_handle, depth + 1);
904 } while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
906 torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
908 if (!W_ERROR_IS_OK(r.out.result) &&
909 !W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
910 torture_fail(tctx, "EnumKey failed");
916 static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
917 struct torture_context *tctx,
918 struct policy_handle *handle,
919 const char *valuename)
921 struct winreg_QueryMultipleValues r;
925 r.in.key_handle = handle;
926 r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
927 r.in.values[0].name = talloc(tctx, struct winreg_String);
928 r.in.values[0].name->name = valuename;
929 r.in.values[0].offset = 0;
930 r.in.values[0].length = 0;
931 r.in.values[0].type = 0;
934 r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
935 *r.in.buffer_size = bufsize;
937 *r.in.buffer_size = bufsize;
938 r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
941 status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
943 if(NT_STATUS_IS_ERR(status))
944 torture_fail(tctx, "QueryMultipleValues failed");
946 talloc_free(r.in.buffer);
948 } while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
950 torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
955 static bool test_QueryValue(struct dcerpc_pipe *p,
956 struct torture_context *tctx,
957 struct policy_handle *handle,
958 const char *valuename)
960 struct winreg_QueryValue r;
962 enum winreg_Type zero_type = 0;
963 uint32_t offered = 0xfff;
966 r.in.handle = handle;
968 r.in.value_name.name = valuename;
969 r.in.type = &zero_type;
970 r.in.size = &offered;
973 status = dcerpc_winreg_QueryValue(p, tctx, &r);
974 if (NT_STATUS_IS_ERR(status)) {
975 torture_fail(tctx, "QueryValue failed");
978 torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
983 static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
984 struct policy_handle *handle, int max_valnamelen,
987 struct winreg_EnumValue r;
988 enum winreg_Type type = 0;
989 uint32_t size = max_valbufsize, zero = 0;
992 struct winreg_StringBuf name;
997 r.in.handle = handle;
1003 r.in.length = &zero;
1007 torture_assert_ntstatus_ok(tctx,
1008 dcerpc_winreg_EnumValue(p, tctx, &r),
1009 "EnumValue failed");
1011 if (W_ERROR_IS_OK(r.out.result)) {
1012 ret &= test_QueryValue(p, tctx, handle,
1014 ret &= test_QueryMultipleValues(p, tctx, handle,
1019 } while (W_ERROR_IS_OK(r.out.result));
1021 torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1022 "EnumValue failed");
1027 static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1028 struct torture_context *tctx)
1030 struct winreg_AbortSystemShutdown r;
1031 uint16_t server = 0x0;
1033 r.in.server = &server;
1035 torture_assert_ntstatus_ok(tctx,
1036 dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1037 "AbortSystemShutdown failed");
1039 torture_assert_werr_ok(tctx, r.out.result,
1040 "AbortSystemShutdown failed");
1045 static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1046 struct dcerpc_pipe *p)
1048 struct winreg_InitiateSystemShutdown r;
1049 uint16_t hostname = 0x0;
1051 r.in.hostname = &hostname;
1052 r.in.message = talloc(tctx, struct initshutdown_String);
1053 init_initshutdown_String(tctx, r.in.message, "spottyfood");
1054 r.in.force_apps = 1;
1058 torture_assert_ntstatus_ok(tctx,
1059 dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1060 "InitiateSystemShutdown failed");
1062 torture_assert_werr_ok(tctx, r.out.result,
1063 "InitiateSystemShutdown failed");
1065 return test_AbortSystemShutdown(p, tctx);
1069 static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1070 struct dcerpc_pipe *p)
1072 struct winreg_InitiateSystemShutdownEx r;
1073 uint16_t hostname = 0x0;
1075 r.in.hostname = &hostname;
1076 r.in.message = talloc(tctx, struct initshutdown_String);
1077 init_initshutdown_String(tctx, r.in.message, "spottyfood");
1078 r.in.force_apps = 1;
1083 torture_assert_ntstatus_ok(tctx,
1084 dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1085 "InitiateSystemShutdownEx failed");
1087 torture_assert_werr_ok(tctx, r.out.result,
1088 "InitiateSystemShutdownEx failed");
1090 return test_AbortSystemShutdown(p, tctx);
1092 #define MAX_DEPTH 2 /* Only go this far down the tree */
1094 static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1095 struct policy_handle *handle, int depth)
1097 if (depth == MAX_DEPTH)
1100 if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1103 if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1106 if (!test_GetKeySecurity(p, tctx, handle, NULL)) {
1109 if (!test_EnumKey(p, tctx, handle, depth)) {
1112 if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1115 test_CloseKey(p, tctx, handle);
1120 typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1122 static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1125 struct policy_handle handle, newhandle;
1126 bool ret = true, created = false, created2 = false, deleted = false;
1127 bool created3 = false, created_subkey = false;
1128 bool created4 = false;
1129 struct winreg_OpenHKLM r;
1131 winreg_open_fn open_fn = userdata;
1133 r.in.system_name = 0;
1134 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1135 r.out.handle = &handle;
1137 torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1140 test_Cleanup(p, tctx, &handle, TEST_KEY1);
1141 test_Cleanup(p, tctx, &handle, TEST_SUBSUBKEY_SD);
1142 test_Cleanup(p, tctx, &handle, TEST_SUBKEY_SD);
1143 test_Cleanup(p, tctx, &handle, TEST_KEY4);
1144 test_Cleanup(p, tctx, &handle, TEST_KEY2);
1145 test_Cleanup(p, tctx, &handle, TEST_SUBKEY);
1146 test_Cleanup(p, tctx, &handle, TEST_KEY3);
1147 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1149 if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1150 torture_comment(tctx,
1151 "CreateKey failed - not considering a failure\n");
1156 if (created && !test_FlushKey(p, tctx, &handle)) {
1157 torture_comment(tctx, "FlushKey failed\n");
1161 if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1163 "CreateKey failed (OpenKey after Create didn't work)\n");
1165 if (created && !test_CloseKey(p, tctx, &newhandle))
1167 "CreateKey failed (CloseKey after Open didn't work)\n");
1169 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1170 torture_comment(tctx, "DeleteKey failed\n");
1176 if (created && !test_FlushKey(p, tctx, &handle)) {
1177 torture_comment(tctx, "FlushKey failed\n");
1181 if (created && deleted &&
1182 test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle)) {
1183 torture_comment(tctx,
1184 "DeleteKey failed (OpenKey after Delete worked)\n");
1188 if (!test_GetVersion(p, tctx, &handle)) {
1189 torture_comment(tctx, "GetVersion failed\n");
1193 if (created && test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1194 NULL, &newhandle)) {
1198 if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1199 printf("CloseKey failed\n");
1203 if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1207 if (!created4 && !test_CloseKey(p, tctx, &newhandle)) {
1208 printf("CloseKey failed\n");
1212 if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1216 if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1217 printf("DeleteKey failed\n");
1222 if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1223 printf("DeleteKey failed\n");
1227 if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1232 test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1233 created_subkey = true;
1236 if (created_subkey &&
1237 !test_DeleteKeyWithSubkey(p, tctx, &handle, TEST_KEY3)) {
1238 printf("DeleteKeyWithSubkey failed "
1239 "(DeleteKey didn't return ACCESS_DENIED)\n");
1243 if (created_subkey &&
1244 !test_DeleteKey(p, tctx, &handle, TEST_SUBKEY)) {
1245 printf("DeleteKey failed\n");
1250 !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1251 printf("DeleteKey failed\n");
1255 /* The HKCR hive has a very large fanout */
1256 if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1257 if(!test_key(p, tctx, &handle, MAX_DEPTH - 1)) {
1262 if (!test_key(p, tctx, &handle, 0)) {
1266 test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1271 struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1276 } open_fns[] = {{"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
1277 {"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
1278 {"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR },
1279 {"OpenHKCU", (winreg_open_fn)dcerpc_winreg_OpenHKCU }};
1281 struct torture_rpc_tcase *tcase;
1282 struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1283 struct torture_test *test;
1285 tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1288 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1289 test_InitiateSystemShutdown);
1290 test->dangerous = true;
1292 test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1293 test_InitiateSystemShutdownEx);
1294 test->dangerous = true;
1296 for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
1297 torture_rpc_tcase_add_test_ex(tcase, open_fns[i].name,
1298 test_Open, open_fns[i].fn);