• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/torture/rpc/
1/*
2   Unix SMB/CIFS implementation.
3   test suite for winreg rpc operations
4
5   Copyright (C) Tim Potter 2003
6   Copyright (C) Jelmer Vernooij 2004-2007
7   Copyright (C) G��nther Deschner 2007
8
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.
13
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.
18
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/>.
21*/
22
23#include "includes.h"
24#include "torture/torture.h"
25#include "librpc/gen_ndr/ndr_winreg_c.h"
26#include "librpc/gen_ndr/ndr_security.h"
27#include "libcli/security/security.h"
28#include "torture/rpc/rpc.h"
29
30#define TEST_KEY_BASE "smbtorture test"
31#define TEST_KEY1 TEST_KEY_BASE "\\spottyfoot"
32#define TEST_KEY2 TEST_KEY_BASE "\\with a SD (#1)"
33#define TEST_KEY3 TEST_KEY_BASE "\\with a subkey"
34#define TEST_KEY4 TEST_KEY_BASE "\\sd_tests"
35#define TEST_SUBKEY TEST_KEY3 "\\subkey"
36#define TEST_SUBKEY_SD  TEST_KEY4 "\\subkey_sd"
37#define TEST_SUBSUBKEY_SD TEST_KEY4 "\\subkey_sd\\subsubkey_sd"
38
39#define TEST_SID "S-1-5-21-1234567890-1234567890-1234567890-500"
40
41static void init_lsa_StringLarge(struct lsa_StringLarge *name, const char *s)
42{
43	name->string = s;
44}
45
46static void init_winreg_String(struct winreg_String *name, const char *s)
47{
48	name->name = s;
49	if (s) {
50		name->name_len = 2 * (strlen_m(s) + 1);
51		name->name_size = name->name_len;
52	} else {
53		name->name_len = 0;
54		name->name_size = 0;
55	}
56}
57
58static bool test_GetVersion(struct dcerpc_pipe *p,
59			    struct torture_context *tctx,
60			    struct policy_handle *handle)
61{
62	struct winreg_GetVersion r;
63	uint32_t v;
64
65	ZERO_STRUCT(r);
66	r.in.handle = handle;
67	r.out.version = &v;
68
69	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_GetVersion(p, tctx, &r),
70				   "GetVersion failed");
71
72	torture_assert_werr_ok(tctx, r.out.result, "GetVersion failed");
73
74	return true;
75}
76
77static bool test_NotifyChangeKeyValue(struct dcerpc_pipe *p,
78				      struct torture_context *tctx,
79				      struct policy_handle *handle)
80{
81	struct winreg_NotifyChangeKeyValue r;
82
83	ZERO_STRUCT(r);
84	r.in.handle = handle;
85	r.in.watch_subtree = true;
86	r.in.notify_filter = 0;
87	r.in.unknown = r.in.unknown2 = 0;
88	init_winreg_String(&r.in.string1, NULL);
89	init_winreg_String(&r.in.string2, NULL);
90
91	torture_assert_ntstatus_ok(tctx,
92				   dcerpc_winreg_NotifyChangeKeyValue(p, tctx, &r),
93				   "NotifyChangeKeyValue failed");
94
95	if (!W_ERROR_IS_OK(r.out.result)) {
96		torture_comment(tctx,
97				"NotifyChangeKeyValue failed - %s - not considering\n",
98				win_errstr(r.out.result));
99		return true;
100	}
101
102	return true;
103}
104
105static bool test_CreateKey(struct dcerpc_pipe *p, struct torture_context *tctx,
106			   struct policy_handle *handle, const char *name,
107			   const char *kclass)
108{
109	struct winreg_CreateKey r;
110	struct policy_handle newhandle;
111	enum winreg_CreateAction action_taken = 0;
112
113	ZERO_STRUCT(r);
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, kclass);
118	r.in.options = 0x0;
119	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120	r.in.action_taken = r.out.action_taken = &action_taken;
121	r.in.secdesc = NULL;
122
123	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
124				   "CreateKey failed");
125
126	torture_assert_werr_ok(tctx,  r.out.result, "CreateKey failed");
127
128	return true;
129}
130
131
132/*
133  createkey testing with a SD
134*/
135static bool test_CreateKey_sd(struct dcerpc_pipe *p,
136			      struct torture_context *tctx,
137			      struct policy_handle *handle, const char *name,
138			      const char *kclass,
139			      struct policy_handle *newhandle)
140{
141	struct winreg_CreateKey r;
142	enum winreg_CreateAction action_taken = 0;
143	struct security_descriptor *sd;
144	DATA_BLOB sdblob;
145	struct winreg_SecBuf secbuf;
146
147	sd = security_descriptor_dacl_create(tctx,
148					0,
149					NULL, NULL,
150					SID_NT_AUTHENTICATED_USERS,
151					SEC_ACE_TYPE_ACCESS_ALLOWED,
152					SEC_GENERIC_ALL,
153					SEC_ACE_FLAG_OBJECT_INHERIT |
154					SEC_ACE_FLAG_CONTAINER_INHERIT,
155					NULL);
156
157	torture_assert_ndr_success(tctx,
158		ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
159				     (ndr_push_flags_fn_t)ndr_push_security_descriptor),
160				     "Failed to push security_descriptor ?!\n");
161
162	secbuf.sd.data = sdblob.data;
163	secbuf.sd.len = sdblob.length;
164	secbuf.sd.size = sdblob.length;
165	secbuf.length = sdblob.length-10;
166	secbuf.inherit = 0;
167
168	ZERO_STRUCT(r);
169	r.in.handle = handle;
170	r.out.new_handle = newhandle;
171	init_winreg_String(&r.in.name, name);
172	init_winreg_String(&r.in.keyclass, kclass);
173	r.in.options = 0x0;
174	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
175	r.in.action_taken = r.out.action_taken = &action_taken;
176	r.in.secdesc = &secbuf;
177
178	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CreateKey(p, tctx, &r),
179				   "CreateKey with sd failed");
180
181	torture_assert_werr_ok(tctx, r.out.result, "CreateKey with sd failed");
182
183	return true;
184}
185
186static bool _test_GetKeySecurity(struct dcerpc_pipe *p,
187				 struct torture_context *tctx,
188				 struct policy_handle *handle,
189				 uint32_t *sec_info_ptr,
190				 WERROR get_werr,
191				 struct security_descriptor **sd_out)
192{
193	struct winreg_GetKeySecurity r;
194	struct security_descriptor *sd = NULL;
195	uint32_t sec_info;
196	DATA_BLOB sdblob;
197
198	if (sec_info_ptr) {
199		sec_info = *sec_info_ptr;
200	} else {
201		sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
202	}
203
204	ZERO_STRUCT(r);
205
206	r.in.handle = handle;
207	r.in.sec_info = sec_info;
208	r.in.sd = r.out.sd = talloc_zero(tctx, struct KeySecurityData);
209	r.in.sd->size = 0x1000;
210
211	torture_assert_ntstatus_ok(tctx,
212				   dcerpc_winreg_GetKeySecurity(p, tctx, &r),
213				   "GetKeySecurity failed");
214
215	torture_assert_werr_equal(tctx, r.out.result, get_werr,
216				  "GetKeySecurity failed");
217
218	sdblob.data = r.out.sd->data;
219	sdblob.length = r.out.sd->len;
220
221	sd = talloc_zero(tctx, struct security_descriptor);
222
223	torture_assert_ndr_success(tctx,
224		ndr_pull_struct_blob(&sdblob, tctx, NULL, sd,
225				     (ndr_pull_flags_fn_t)ndr_pull_security_descriptor),
226				     "pull_security_descriptor failed");
227
228	if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
229		NDR_PRINT_DEBUG(security_descriptor, sd);
230	}
231
232	if (sd_out) {
233		*sd_out = sd;
234	} else {
235		talloc_free(sd);
236	}
237
238	return true;
239}
240
241static bool test_GetKeySecurity(struct dcerpc_pipe *p,
242				struct torture_context *tctx,
243				struct policy_handle *handle,
244				struct security_descriptor **sd_out)
245{
246	return _test_GetKeySecurity(p, tctx, handle, NULL, WERR_OK, sd_out);
247}
248
249static bool _test_SetKeySecurity(struct dcerpc_pipe *p,
250				 struct torture_context *tctx,
251				 struct policy_handle *handle,
252				 uint32_t *sec_info_ptr,
253				 struct security_descriptor *sd,
254				 WERROR werr)
255{
256	struct winreg_SetKeySecurity r;
257	struct KeySecurityData *sdata = NULL;
258	DATA_BLOB sdblob;
259	uint32_t sec_info;
260
261	ZERO_STRUCT(r);
262
263	if (sd && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
264		NDR_PRINT_DEBUG(security_descriptor, sd);
265	}
266
267	torture_assert_ndr_success(tctx,
268		ndr_push_struct_blob(&sdblob, tctx, NULL, sd,
269				     (ndr_push_flags_fn_t)ndr_push_security_descriptor),
270				     "push_security_descriptor failed");
271
272	sdata = talloc_zero(tctx, struct KeySecurityData);
273	sdata->data = sdblob.data;
274	sdata->size = sdblob.length;
275	sdata->len = sdblob.length;
276
277	if (sec_info_ptr) {
278		sec_info = *sec_info_ptr;
279	} else {
280		sec_info = SECINFO_UNPROTECTED_SACL |
281			   SECINFO_UNPROTECTED_DACL;
282		if (sd->owner_sid) {
283			sec_info |= SECINFO_OWNER;
284		}
285		if (sd->group_sid) {
286			sec_info |= SECINFO_GROUP;
287		}
288		if (sd->sacl) {
289			sec_info |= SECINFO_SACL;
290		}
291		if (sd->dacl) {
292			sec_info |= SECINFO_DACL;
293		}
294	}
295
296	r.in.handle = handle;
297	r.in.sec_info = sec_info;
298	r.in.sd = sdata;
299
300	torture_assert_ntstatus_ok(tctx,
301				   dcerpc_winreg_SetKeySecurity(p, tctx, &r),
302				   "SetKeySecurity failed");
303
304	torture_assert_werr_equal(tctx, r.out.result, werr,
305				  "SetKeySecurity failed");
306
307	return true;
308}
309
310static bool test_SetKeySecurity(struct dcerpc_pipe *p,
311				struct torture_context *tctx,
312				struct policy_handle *handle,
313				struct security_descriptor *sd)
314{
315	return _test_SetKeySecurity(p, tctx, handle, NULL, sd, WERR_OK);
316}
317
318static bool test_CloseKey(struct dcerpc_pipe *p, struct torture_context *tctx,
319			  struct policy_handle *handle)
320{
321	struct winreg_CloseKey r;
322
323	ZERO_STRUCT(r);
324	r.in.handle = r.out.handle = handle;
325
326	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_CloseKey(p, tctx, &r),
327				   "CloseKey failed");
328
329	torture_assert_werr_ok(tctx, r.out.result, "CloseKey failed");
330
331	return true;
332}
333
334static bool test_FlushKey(struct dcerpc_pipe *p, struct torture_context *tctx,
335			  struct policy_handle *handle)
336{
337	struct winreg_FlushKey r;
338
339	ZERO_STRUCT(r);
340	r.in.handle = handle;
341
342	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_FlushKey(p, tctx, &r),
343				   "FlushKey failed");
344
345	torture_assert_werr_ok(tctx, r.out.result, "FlushKey failed");
346
347	return true;
348}
349
350static bool _test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
351			  struct policy_handle *hive_handle,
352			  const char *keyname, uint32_t access_mask,
353			  struct policy_handle *key_handle,
354			  WERROR open_werr,
355			  bool *success)
356{
357	struct winreg_OpenKey r;
358
359	ZERO_STRUCT(r);
360	r.in.parent_handle = hive_handle;
361	init_winreg_String(&r.in.keyname, keyname);
362	r.in.unknown = 0x00000000;
363	r.in.access_mask = access_mask;
364	r.out.handle = key_handle;
365
366	torture_assert_ntstatus_ok(tctx, dcerpc_winreg_OpenKey(p, tctx, &r),
367				   "OpenKey failed");
368
369	torture_assert_werr_equal(tctx, r.out.result, open_werr,
370				  "OpenKey failed");
371
372	if (success && W_ERROR_EQUAL(r.out.result, WERR_OK)) {
373		*success = true;
374	}
375
376	return true;
377}
378
379static bool test_OpenKey(struct dcerpc_pipe *p, struct torture_context *tctx,
380			 struct policy_handle *hive_handle,
381			 const char *keyname, struct policy_handle *key_handle)
382{
383	return _test_OpenKey(p, tctx, hive_handle, keyname,
384			     SEC_FLAG_MAXIMUM_ALLOWED, key_handle,
385			     WERR_OK, NULL);
386}
387
388static bool test_Cleanup(struct dcerpc_pipe *p, struct torture_context *tctx,
389			 struct policy_handle *handle, const char *key)
390{
391	struct winreg_DeleteKey r;
392
393	ZERO_STRUCT(r);
394	r.in.handle = handle;
395
396	init_winreg_String(&r.in.key, key);
397	dcerpc_winreg_DeleteKey(p, tctx, &r);
398
399	return true;
400}
401
402static bool _test_GetSetSecurityDescriptor(struct dcerpc_pipe *p,
403					   struct torture_context *tctx,
404					   struct policy_handle *handle,
405					   WERROR get_werr,
406					   WERROR set_werr)
407{
408	struct security_descriptor *sd = NULL;
409
410	if (!_test_GetKeySecurity(p, tctx, handle, NULL, get_werr, &sd)) {
411		return false;
412	}
413
414	if (!_test_SetKeySecurity(p, tctx, handle, NULL, sd, set_werr)) {
415		return false;
416	}
417
418	return true;
419}
420
421static bool test_SecurityDescriptor(struct dcerpc_pipe *p,
422				    struct torture_context *tctx,
423				    struct policy_handle *handle,
424				    const char *key)
425{
426	struct policy_handle new_handle;
427	bool ret = true;
428
429	torture_comment(tctx, "SecurityDescriptor get & set\n");
430
431	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
432		return false;
433	}
434
435	if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
436					    WERR_OK, WERR_OK)) {
437		ret = false;
438	}
439
440	if (!test_CloseKey(p, tctx, &new_handle)) {
441		return false;
442	}
443
444	return ret;
445}
446
447static bool _test_SecurityDescriptor(struct dcerpc_pipe *p,
448				     struct torture_context *tctx,
449				     struct policy_handle *handle,
450				     uint32_t access_mask,
451				     const char *key,
452				     WERROR open_werr,
453				     WERROR get_werr,
454				     WERROR set_werr)
455{
456	struct policy_handle new_handle;
457	bool ret = true;
458	bool got_key = false;
459
460	if (!_test_OpenKey(p, tctx, handle, key, access_mask, &new_handle,
461			   open_werr, &got_key)) {
462		return false;
463	}
464
465	if (!got_key) {
466		return true;
467	}
468
469	if (!_test_GetSetSecurityDescriptor(p, tctx, &new_handle,
470					    get_werr, set_werr)) {
471		ret = false;
472	}
473
474	if (!test_CloseKey(p, tctx, &new_handle)) {
475		return false;
476	}
477
478	return ret;
479}
480
481static bool test_dacl_trustee_present(struct dcerpc_pipe *p,
482				      struct torture_context *tctx,
483				      struct policy_handle *handle,
484				      const struct dom_sid *sid)
485{
486	struct security_descriptor *sd = NULL;
487	int i;
488
489	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
490		return false;
491	}
492
493	if (!sd || !sd->dacl) {
494		return false;
495	}
496
497	for (i = 0; i < sd->dacl->num_aces; i++) {
498		if (dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) {
499			return true;
500		}
501	}
502
503	return false;
504}
505
506static bool _test_dacl_trustee_present(struct dcerpc_pipe *p,
507				       struct torture_context *tctx,
508				       struct policy_handle *handle,
509				       const char *key,
510				       const struct dom_sid *sid)
511{
512	struct policy_handle new_handle;
513	bool ret = true;
514
515	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
516		return false;
517	}
518
519	ret = test_dacl_trustee_present(p, tctx, &new_handle, sid);
520
521	test_CloseKey(p, tctx, &new_handle);
522
523	return ret;
524}
525
526static bool test_sacl_trustee_present(struct dcerpc_pipe *p,
527				      struct torture_context *tctx,
528				      struct policy_handle *handle,
529				      const struct dom_sid *sid)
530{
531	struct security_descriptor *sd = NULL;
532	int i;
533	uint32_t sec_info = SECINFO_SACL;
534
535	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
536		return false;
537	}
538
539	if (!sd || !sd->sacl) {
540		return false;
541	}
542
543	for (i = 0; i < sd->sacl->num_aces; i++) {
544		if (dom_sid_equal(&sd->sacl->aces[i].trustee, sid)) {
545			return true;
546		}
547	}
548
549	return false;
550}
551
552static bool _test_sacl_trustee_present(struct dcerpc_pipe *p,
553				       struct torture_context *tctx,
554				       struct policy_handle *handle,
555				       const char *key,
556				       const struct dom_sid *sid)
557{
558	struct policy_handle new_handle;
559	bool ret = true;
560
561	if (!_test_OpenKey(p, tctx, handle, key, SEC_FLAG_SYSTEM_SECURITY,
562			   &new_handle, WERR_OK, NULL)) {
563		return false;
564	}
565
566	ret = test_sacl_trustee_present(p, tctx, &new_handle, sid);
567
568	test_CloseKey(p, tctx, &new_handle);
569
570	return ret;
571}
572
573static bool test_owner_present(struct dcerpc_pipe *p,
574			       struct torture_context *tctx,
575			       struct policy_handle *handle,
576			       const struct dom_sid *sid)
577{
578	struct security_descriptor *sd = NULL;
579	uint32_t sec_info = SECINFO_OWNER;
580
581	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
582		return false;
583	}
584
585	if (!sd || !sd->owner_sid) {
586		return false;
587	}
588
589	return dom_sid_equal(sd->owner_sid, sid);
590}
591
592static bool _test_owner_present(struct dcerpc_pipe *p,
593				struct torture_context *tctx,
594				struct policy_handle *handle,
595				const char *key,
596				const struct dom_sid *sid)
597{
598	struct policy_handle new_handle;
599	bool ret = true;
600
601	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
602		return false;
603	}
604
605	ret = test_owner_present(p, tctx, &new_handle, sid);
606
607	test_CloseKey(p, tctx, &new_handle);
608
609	return ret;
610}
611
612static bool test_group_present(struct dcerpc_pipe *p,
613			       struct torture_context *tctx,
614			       struct policy_handle *handle,
615			       const struct dom_sid *sid)
616{
617	struct security_descriptor *sd = NULL;
618	uint32_t sec_info = SECINFO_GROUP;
619
620	if (!_test_GetKeySecurity(p, tctx, handle, &sec_info, WERR_OK, &sd)) {
621		return false;
622	}
623
624	if (!sd || !sd->group_sid) {
625		return false;
626	}
627
628	return dom_sid_equal(sd->group_sid, sid);
629}
630
631static bool _test_group_present(struct dcerpc_pipe *p,
632				struct torture_context *tctx,
633				struct policy_handle *handle,
634				const char *key,
635				const struct dom_sid *sid)
636{
637	struct policy_handle new_handle;
638	bool ret = true;
639
640	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
641		return false;
642	}
643
644	ret = test_group_present(p, tctx, &new_handle, sid);
645
646	test_CloseKey(p, tctx, &new_handle);
647
648	return ret;
649}
650
651static bool test_dacl_trustee_flags_present(struct dcerpc_pipe *p,
652					    struct torture_context *tctx,
653					    struct policy_handle *handle,
654					    const struct dom_sid *sid,
655					    uint8_t flags)
656{
657	struct security_descriptor *sd = NULL;
658	int i;
659
660	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
661		return false;
662	}
663
664	if (!sd || !sd->dacl) {
665		return false;
666	}
667
668	for (i = 0; i < sd->dacl->num_aces; i++) {
669		if ((dom_sid_equal(&sd->dacl->aces[i].trustee, sid)) &&
670		    (sd->dacl->aces[i].flags == flags)) {
671			return true;
672		}
673	}
674
675	return false;
676}
677
678static bool test_dacl_ace_present(struct dcerpc_pipe *p,
679				  struct torture_context *tctx,
680				  struct policy_handle *handle,
681				  const struct security_ace *ace)
682{
683	struct security_descriptor *sd = NULL;
684	int i;
685
686	if (!test_GetKeySecurity(p, tctx, handle, &sd)) {
687		return false;
688	}
689
690	if (!sd || !sd->dacl) {
691		return false;
692	}
693
694	for (i = 0; i < sd->dacl->num_aces; i++) {
695		if (security_ace_equal(&sd->dacl->aces[i], ace)) {
696			return true;
697		}
698	}
699
700	return false;
701}
702
703static bool test_RestoreSecurity(struct dcerpc_pipe *p,
704				 struct torture_context *tctx,
705				 struct policy_handle *handle,
706				 const char *key,
707				 struct security_descriptor *sd)
708{
709	struct policy_handle new_handle;
710	bool ret = true;
711
712	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
713		return false;
714	}
715
716	if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
717		ret = false;
718	}
719
720	if (!test_CloseKey(p, tctx, &new_handle)) {
721		ret = false;
722	}
723
724	return ret;
725}
726
727static bool test_BackupSecurity(struct dcerpc_pipe *p,
728				struct torture_context *tctx,
729				struct policy_handle *handle,
730				const char *key,
731				struct security_descriptor **sd)
732{
733	struct policy_handle new_handle;
734	bool ret = true;
735
736	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
737		return false;
738	}
739
740	if (!test_GetKeySecurity(p, tctx, &new_handle, sd)) {
741		ret = false;
742	}
743
744	if (!test_CloseKey(p, tctx, &new_handle)) {
745		ret = false;
746	}
747
748	return ret;
749}
750
751static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
752					       struct torture_context *tctx,
753					       struct policy_handle *handle,
754					       const char *key)
755{
756	/* get sd
757	   add ace SEC_ACE_FLAG_CONTAINER_INHERIT
758	   set sd
759	   get sd
760	   check ace
761	   add subkey
762	   get sd
763	   check ace
764	   add subsubkey
765	   get sd
766	   check ace
767	   del subsubkey
768	   del subkey
769	   reset sd
770	*/
771
772	struct security_descriptor *sd = NULL;
773	struct security_descriptor *sd_orig = NULL;
774	struct security_ace *ace = NULL;
775	struct policy_handle new_handle;
776	NTSTATUS status;
777	bool ret = true;
778
779	torture_comment(tctx, "SecurityDescriptor inheritance\n");
780
781	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
782		return false;
783	}
784
785	if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
786		return false;
787	}
788
789	sd_orig = security_descriptor_copy(tctx, sd);
790	if (sd_orig == NULL) {
791		return false;
792	}
793
794	ace = security_ace_create(tctx,
795				  TEST_SID,
796				  SEC_ACE_TYPE_ACCESS_ALLOWED,
797				  SEC_STD_REQUIRED,
798				  SEC_ACE_FLAG_CONTAINER_INHERIT);
799
800	status = security_descriptor_dacl_add(sd, ace);
801	if (!NT_STATUS_IS_OK(status)) {
802		printf("failed to add ace: %s\n", nt_errstr(status));
803		return false;
804	}
805
806	/* FIXME: add further tests for these flags */
807	sd->type |= SEC_DESC_DACL_AUTO_INHERIT_REQ |
808		    SEC_DESC_SACL_AUTO_INHERITED;
809
810	if (!test_SetKeySecurity(p, tctx, &new_handle, sd)) {
811		return false;
812	}
813
814	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
815		printf("new ACE not present!\n");
816		return false;
817	}
818
819	if (!test_CloseKey(p, tctx, &new_handle)) {
820		return false;
821	}
822
823	if (!test_CreateKey(p, tctx, handle, TEST_SUBKEY_SD, NULL)) {
824		ret = false;
825		goto out;
826	}
827
828	if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
829		ret = false;
830		goto out;
831	}
832
833	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
834		printf("inherited ACE not present!\n");
835		ret = false;
836		goto out;
837	}
838
839	test_CloseKey(p, tctx, &new_handle);
840	if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
841		ret = false;
842		goto out;
843	}
844
845	if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
846		ret = false;
847		goto out;
848	}
849
850	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
851		printf("inherited ACE not present!\n");
852		ret = false;
853		goto out;
854	}
855
856 out:
857	test_CloseKey(p, tctx, &new_handle);
858	test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
859	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
860
861	return true;
862}
863
864static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
865						    struct torture_context *tctx,
866						    struct policy_handle *handle,
867						    const char *key)
868{
869	/* get sd
870	   add ace SEC_ACE_FLAG_NO_PROPAGATE_INHERIT
871	   set sd
872	   add subkey/subkey
873	   get sd
874	   check ace
875	   get sd from subkey
876	   check ace
877	   del subkey/subkey
878	   del subkey
879	   reset sd
880	*/
881
882	struct security_descriptor *sd = NULL;
883	struct security_descriptor *sd_orig = NULL;
884	struct security_ace *ace = NULL;
885	struct policy_handle new_handle;
886	struct dom_sid *sid = NULL;
887	NTSTATUS status;
888	bool ret = true;
889	uint8_t ace_flags = 0x0;
890
891	torture_comment(tctx, "SecurityDescriptor inheritance block\n");
892
893	if (!test_OpenKey(p, tctx, handle, key, &new_handle)) {
894		return false;
895	}
896
897	if (!_test_GetKeySecurity(p, tctx, &new_handle, NULL, WERR_OK, &sd)) {
898		return false;
899	}
900
901	sd_orig = security_descriptor_copy(tctx, sd);
902	if (sd_orig == NULL) {
903		return false;
904	}
905
906	ace = security_ace_create(tctx,
907				  TEST_SID,
908				  SEC_ACE_TYPE_ACCESS_ALLOWED,
909				  SEC_STD_REQUIRED,
910				  SEC_ACE_FLAG_CONTAINER_INHERIT |
911				  SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
912
913	status = security_descriptor_dacl_add(sd, ace);
914	if (!NT_STATUS_IS_OK(status)) {
915		printf("failed to add ace: %s\n", nt_errstr(status));
916		return false;
917	}
918
919	if (!_test_SetKeySecurity(p, tctx, &new_handle, NULL, sd, WERR_OK)) {
920		return false;
921	}
922
923	if (!test_dacl_ace_present(p, tctx, &new_handle, ace)) {
924		printf("new ACE not present!\n");
925		return false;
926	}
927
928	if (!test_CloseKey(p, tctx, &new_handle)) {
929		return false;
930	}
931
932	if (!test_CreateKey(p, tctx, handle, TEST_SUBSUBKEY_SD, NULL)) {
933		return false;
934	}
935
936	if (!test_OpenKey(p, tctx, handle, TEST_SUBSUBKEY_SD, &new_handle)) {
937		ret = false;
938		goto out;
939	}
940
941	if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
942		printf("inherited ACE present but should not!\n");
943		ret = false;
944		goto out;
945	}
946
947	sid = dom_sid_parse_talloc(tctx, TEST_SID);
948	if (sid == NULL) {
949		return false;
950	}
951
952	if (test_dacl_trustee_present(p, tctx, &new_handle, sid)) {
953		printf("inherited trustee SID present but should not!\n");
954		ret = false;
955		goto out;
956	}
957
958	test_CloseKey(p, tctx, &new_handle);
959
960	if (!test_OpenKey(p, tctx, handle, TEST_SUBKEY_SD, &new_handle)) {
961		ret = false;
962		goto out;
963	}
964
965	if (test_dacl_ace_present(p, tctx, &new_handle, ace)) {
966		printf("inherited ACE present but should not!\n");
967		ret = false;
968		goto out;
969	}
970
971	if (!test_dacl_trustee_flags_present(p, tctx, &new_handle, sid, ace_flags)) {
972		printf("inherited trustee SID with flags 0x%02x not present!\n",
973			ace_flags);
974		ret = false;
975		goto out;
976	}
977
978 out:
979	test_CloseKey(p, tctx, &new_handle);
980	test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
981	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
982
983	return ret;
984}
985
986static bool test_SecurityDescriptorsMasks(struct dcerpc_pipe *p,
987					  struct torture_context *tctx,
988					  struct policy_handle *handle,
989					  const char *key)
990{
991	bool ret = true;
992	int i;
993
994	struct winreg_mask_result_table {
995		uint32_t access_mask;
996		WERROR open_werr;
997		WERROR get_werr;
998		WERROR set_werr;
999	} sd_mask_tests[] = {
1000		{ 0,
1001			WERR_ACCESS_DENIED, WERR_BADFILE, WERR_FOOBAR },
1002		{ SEC_FLAG_MAXIMUM_ALLOWED,
1003			WERR_OK, WERR_OK, WERR_OK },
1004		{ SEC_STD_WRITE_DAC,
1005			WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR },
1006		{ SEC_FLAG_SYSTEM_SECURITY,
1007			WERR_OK, WERR_ACCESS_DENIED, WERR_FOOBAR }
1008	};
1009
1010	/* FIXME: before this test can ever run successfully we need a way to
1011	 * correctly read a NULL security_descritpor in ndr, get the required
1012	 * length, requery, etc.
1013	 */
1014
1015	return true;
1016
1017	for (i=0; i < ARRAY_SIZE(sd_mask_tests); i++) {
1018
1019		torture_comment(tctx,
1020				"SecurityDescriptor get & set with access_mask: 0x%08x\n",
1021				sd_mask_tests[i].access_mask);
1022		torture_comment(tctx,
1023				"expecting: open %s, get: %s, set: %s\n",
1024				win_errstr(sd_mask_tests[i].open_werr),
1025				win_errstr(sd_mask_tests[i].get_werr),
1026				win_errstr(sd_mask_tests[i].set_werr));
1027
1028		if (_test_SecurityDescriptor(p, tctx, handle,
1029					     sd_mask_tests[i].access_mask, key,
1030					     sd_mask_tests[i].open_werr,
1031					     sd_mask_tests[i].get_werr,
1032					     sd_mask_tests[i].set_werr)) {
1033			ret = false;
1034		}
1035	}
1036
1037	return ret;
1038}
1039
1040typedef bool (*secinfo_verify_fn)(struct dcerpc_pipe *,
1041				  struct torture_context *,
1042				  struct policy_handle *,
1043				  const char *,
1044				  const struct dom_sid *);
1045
1046static bool test_SetSecurityDescriptor_SecInfo(struct dcerpc_pipe *p,
1047					       struct torture_context *tctx,
1048					       struct policy_handle *handle,
1049					       const char *key,
1050					       const char *test,
1051					       uint32_t access_mask,
1052					       uint32_t sec_info,
1053					       struct security_descriptor *sd,
1054					       WERROR set_werr,
1055					       bool expect_present,
1056					       bool (*fn) (struct dcerpc_pipe *,
1057							   struct torture_context *,
1058							   struct policy_handle *,
1059							   const char *,
1060							   const struct dom_sid *),
1061					       const struct dom_sid *sid)
1062{
1063	struct policy_handle new_handle;
1064	bool open_success = false;
1065
1066	torture_comment(tctx, "SecurityDescriptor (%s) sets for secinfo: "
1067			"0x%08x, access_mask: 0x%08x\n",
1068			test, sec_info, access_mask);
1069
1070	if (!_test_OpenKey(p, tctx, handle, key,
1071			   access_mask,
1072			   &new_handle,
1073			   WERR_OK,
1074			   &open_success)) {
1075		return false;
1076	}
1077
1078	if (!open_success) {
1079		printf("key did not open\n");
1080		test_CloseKey(p, tctx, &new_handle);
1081		return false;
1082	}
1083
1084	if (!_test_SetKeySecurity(p, tctx, &new_handle, &sec_info,
1085				  sd,
1086				  set_werr)) {
1087		torture_warning(tctx,
1088				"SetKeySecurity with secinfo: 0x%08x has failed\n",
1089				sec_info);
1090		smb_panic("");
1091		test_CloseKey(p, tctx, &new_handle);
1092		return false;
1093	}
1094
1095	test_CloseKey(p, tctx, &new_handle);
1096
1097	if (W_ERROR_IS_OK(set_werr)) {
1098		bool present;
1099		present = fn(p, tctx, handle, key, sid);
1100		if ((expect_present) && (!present)) {
1101			torture_warning(tctx,
1102					"%s sid is not present!\n",
1103					test);
1104			return false;
1105		}
1106		if ((!expect_present) && (present)) {
1107			torture_warning(tctx,
1108					"%s sid is present but not expected!\n",
1109					test);
1110			return false;
1111		}
1112	}
1113
1114	return true;
1115}
1116
1117static bool test_SecurityDescriptorsSecInfo(struct dcerpc_pipe *p,
1118					    struct torture_context *tctx,
1119					    struct policy_handle *handle,
1120					    const char *key)
1121{
1122	struct security_descriptor *sd_orig = NULL;
1123	struct dom_sid *sid = NULL;
1124	bool ret = true;
1125	int i, a;
1126
1127	struct security_descriptor *sd_owner =
1128		security_descriptor_dacl_create(tctx,
1129						0,
1130						TEST_SID, NULL, NULL);
1131
1132	struct security_descriptor *sd_group =
1133		security_descriptor_dacl_create(tctx,
1134						0,
1135						NULL, TEST_SID, NULL);
1136
1137	struct security_descriptor *sd_dacl =
1138		security_descriptor_dacl_create(tctx,
1139						0,
1140						NULL, NULL,
1141						TEST_SID,
1142						SEC_ACE_TYPE_ACCESS_ALLOWED,
1143						SEC_GENERIC_ALL,
1144						0,
1145						SID_NT_AUTHENTICATED_USERS,
1146						SEC_ACE_TYPE_ACCESS_ALLOWED,
1147						SEC_GENERIC_ALL,
1148						0,
1149						NULL);
1150
1151	struct security_descriptor *sd_sacl =
1152		security_descriptor_sacl_create(tctx,
1153						0,
1154						NULL, NULL,
1155						TEST_SID,
1156						SEC_ACE_TYPE_SYSTEM_AUDIT,
1157						SEC_GENERIC_ALL,
1158						SEC_ACE_FLAG_SUCCESSFUL_ACCESS,
1159						NULL);
1160
1161	struct winreg_secinfo_table {
1162		struct security_descriptor *sd;
1163		uint32_t sec_info;
1164		WERROR set_werr;
1165		bool sid_present;
1166		secinfo_verify_fn fn;
1167	};
1168
1169	struct winreg_secinfo_table sec_info_owner_tests[] = {
1170		{ sd_owner, 0, WERR_OK,
1171			false, (secinfo_verify_fn)_test_owner_present },
1172		{ sd_owner, SECINFO_OWNER, WERR_OK,
1173			true, (secinfo_verify_fn)_test_owner_present },
1174		{ sd_owner, SECINFO_GROUP, WERR_INVALID_PARAM },
1175		{ sd_owner, SECINFO_DACL, WERR_OK,
1176			true, (secinfo_verify_fn)_test_owner_present },
1177		{ sd_owner, SECINFO_SACL, WERR_ACCESS_DENIED },
1178	};
1179
1180	uint32_t sd_owner_good_access_masks[] = {
1181		SEC_FLAG_MAXIMUM_ALLOWED,
1182		/* SEC_STD_WRITE_OWNER, */
1183	};
1184
1185	struct winreg_secinfo_table sec_info_group_tests[] = {
1186		{ sd_group, 0, WERR_OK,
1187			false, (secinfo_verify_fn)_test_group_present },
1188		{ sd_group, SECINFO_OWNER, WERR_INVALID_PARAM },
1189		{ sd_group, SECINFO_GROUP, WERR_OK,
1190			true, (secinfo_verify_fn)_test_group_present },
1191		{ sd_group, SECINFO_DACL, WERR_OK,
1192			true, (secinfo_verify_fn)_test_group_present },
1193		{ sd_group, SECINFO_SACL, WERR_ACCESS_DENIED },
1194	};
1195
1196	uint32_t sd_group_good_access_masks[] = {
1197		SEC_FLAG_MAXIMUM_ALLOWED,
1198	};
1199
1200	struct winreg_secinfo_table sec_info_dacl_tests[] = {
1201		{ sd_dacl, 0, WERR_OK,
1202			false, (secinfo_verify_fn)_test_dacl_trustee_present },
1203		{ sd_dacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1204		{ sd_dacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1205		{ sd_dacl, SECINFO_DACL, WERR_OK,
1206			true, (secinfo_verify_fn)_test_dacl_trustee_present },
1207		{ sd_dacl, SECINFO_SACL, WERR_ACCESS_DENIED },
1208	};
1209
1210	uint32_t sd_dacl_good_access_masks[] = {
1211		SEC_FLAG_MAXIMUM_ALLOWED,
1212		SEC_STD_WRITE_DAC,
1213	};
1214
1215	struct winreg_secinfo_table sec_info_sacl_tests[] = {
1216		{ sd_sacl, 0, WERR_OK,
1217			false, (secinfo_verify_fn)_test_sacl_trustee_present },
1218		{ sd_sacl, SECINFO_OWNER, WERR_INVALID_PARAM },
1219		{ sd_sacl, SECINFO_GROUP, WERR_INVALID_PARAM },
1220		{ sd_sacl, SECINFO_DACL, WERR_OK,
1221			false, (secinfo_verify_fn)_test_sacl_trustee_present },
1222		{ sd_sacl, SECINFO_SACL, WERR_OK,
1223			true, (secinfo_verify_fn)_test_sacl_trustee_present },
1224	};
1225
1226	uint32_t sd_sacl_good_access_masks[] = {
1227		SEC_FLAG_MAXIMUM_ALLOWED | SEC_FLAG_SYSTEM_SECURITY,
1228		/* SEC_FLAG_SYSTEM_SECURITY, */
1229	};
1230
1231	sid = dom_sid_parse_talloc(tctx, TEST_SID);
1232	if (sid == NULL) {
1233		return false;
1234	}
1235
1236	if (!test_BackupSecurity(p, tctx, handle, key, &sd_orig)) {
1237		return false;
1238	}
1239
1240	/* OWNER */
1241
1242	for (i=0; i < ARRAY_SIZE(sec_info_owner_tests); i++) {
1243
1244		for (a=0; a < ARRAY_SIZE(sd_owner_good_access_masks); a++) {
1245
1246			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1247					key,
1248					"OWNER",
1249					sd_owner_good_access_masks[a],
1250					sec_info_owner_tests[i].sec_info,
1251					sec_info_owner_tests[i].sd,
1252					sec_info_owner_tests[i].set_werr,
1253					sec_info_owner_tests[i].sid_present,
1254					sec_info_owner_tests[i].fn,
1255					sid))
1256			{
1257				printf("test_SetSecurityDescriptor_SecInfo failed for OWNER\n");
1258				ret = false;
1259				goto out;
1260			}
1261		}
1262	}
1263
1264	/* GROUP */
1265
1266	for (i=0; i < ARRAY_SIZE(sec_info_group_tests); i++) {
1267
1268		for (a=0; a < ARRAY_SIZE(sd_group_good_access_masks); a++) {
1269
1270			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1271					key,
1272					"GROUP",
1273					sd_group_good_access_masks[a],
1274					sec_info_group_tests[i].sec_info,
1275					sec_info_group_tests[i].sd,
1276					sec_info_group_tests[i].set_werr,
1277					sec_info_group_tests[i].sid_present,
1278					sec_info_group_tests[i].fn,
1279					sid))
1280			{
1281				printf("test_SetSecurityDescriptor_SecInfo failed for GROUP\n");
1282				ret = false;
1283				goto out;
1284			}
1285		}
1286	}
1287
1288	/* DACL */
1289
1290	for (i=0; i < ARRAY_SIZE(sec_info_dacl_tests); i++) {
1291
1292		for (a=0; a < ARRAY_SIZE(sd_dacl_good_access_masks); a++) {
1293
1294			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1295					key,
1296					"DACL",
1297					sd_dacl_good_access_masks[a],
1298					sec_info_dacl_tests[i].sec_info,
1299					sec_info_dacl_tests[i].sd,
1300					sec_info_dacl_tests[i].set_werr,
1301					sec_info_dacl_tests[i].sid_present,
1302					sec_info_dacl_tests[i].fn,
1303					sid))
1304			{
1305				printf("test_SetSecurityDescriptor_SecInfo failed for DACL\n");
1306				ret = false;
1307				goto out;
1308			}
1309		}
1310	}
1311
1312	/* SACL */
1313
1314	for (i=0; i < ARRAY_SIZE(sec_info_sacl_tests); i++) {
1315
1316		for (a=0; a < ARRAY_SIZE(sd_sacl_good_access_masks); a++) {
1317
1318			if (!test_SetSecurityDescriptor_SecInfo(p, tctx, handle,
1319					key,
1320					"SACL",
1321					sd_sacl_good_access_masks[a],
1322					sec_info_sacl_tests[i].sec_info,
1323					sec_info_sacl_tests[i].sd,
1324					sec_info_sacl_tests[i].set_werr,
1325					sec_info_sacl_tests[i].sid_present,
1326					sec_info_sacl_tests[i].fn,
1327					sid))
1328			{
1329				printf("test_SetSecurityDescriptor_SecInfo failed for SACL\n");
1330				ret = false;
1331				goto out;
1332			}
1333		}
1334	}
1335
1336 out:
1337	test_RestoreSecurity(p, tctx, handle, key, sd_orig);
1338
1339	return ret;
1340}
1341
1342static bool test_SecurityDescriptors(struct dcerpc_pipe *p,
1343				     struct torture_context *tctx,
1344				     struct policy_handle *handle,
1345				     const char *key)
1346{
1347	bool ret = true;
1348
1349	if (!test_SecurityDescriptor(p, tctx, handle, key)) {
1350		printf("test_SecurityDescriptor failed\n");
1351		ret = false;
1352	}
1353
1354	if (!test_SecurityDescriptorInheritance(p, tctx, handle, key)) {
1355		printf("test_SecurityDescriptorInheritance failed\n");
1356		ret = false;
1357	}
1358
1359	if (!test_SecurityDescriptorBlockInheritance(p, tctx, handle, key)) {
1360		printf("test_SecurityDescriptorBlockInheritance failed\n");
1361		ret = false;
1362	}
1363
1364	if (!test_SecurityDescriptorsSecInfo(p, tctx, handle, key)) {
1365		printf("test_SecurityDescriptorsSecInfo failed\n");
1366		ret = false;
1367	}
1368
1369	if (!test_SecurityDescriptorsMasks(p, tctx, handle, key)) {
1370		printf("test_SecurityDescriptorsMasks failed\n");
1371		ret = false;
1372	}
1373
1374	return ret;
1375}
1376
1377static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1378			   struct policy_handle *handle, const char *key)
1379{
1380	NTSTATUS status;
1381	struct winreg_DeleteKey r;
1382
1383	r.in.handle = handle;
1384	init_winreg_String(&r.in.key, key);
1385
1386	status = dcerpc_winreg_DeleteKey(p, tctx, &r);
1387
1388	torture_assert_ntstatus_ok(tctx, status, "DeleteKey failed");
1389	torture_assert_werr_ok(tctx, r.out.result, "DeleteKey failed");
1390
1391	return true;
1392}
1393
1394static bool test_QueryInfoKey(struct dcerpc_pipe *p,
1395			      struct torture_context *tctx,
1396			      struct policy_handle *handle, char *kclass)
1397{
1398	struct winreg_QueryInfoKey r;
1399	uint32_t num_subkeys, max_subkeylen, max_classlen,
1400		num_values, max_valnamelen, max_valbufsize,
1401		secdescsize;
1402	NTTIME last_changed_time;
1403
1404	ZERO_STRUCT(r);
1405	r.in.handle = handle;
1406	r.out.num_subkeys = &num_subkeys;
1407	r.out.max_subkeylen = &max_subkeylen;
1408	r.out.max_classlen = &max_classlen;
1409	r.out.num_values = &num_values;
1410	r.out.max_valnamelen = &max_valnamelen;
1411	r.out.max_valbufsize = &max_valbufsize;
1412	r.out.secdescsize = &secdescsize;
1413	r.out.last_changed_time = &last_changed_time;
1414
1415	r.out.classname = talloc(tctx, struct winreg_String);
1416
1417	r.in.classname = talloc(tctx, struct winreg_String);
1418	init_winreg_String(r.in.classname, kclass);
1419
1420	torture_assert_ntstatus_ok(tctx,
1421				   dcerpc_winreg_QueryInfoKey(p, tctx, &r),
1422				   "QueryInfoKey failed");
1423
1424	torture_assert_werr_ok(tctx, r.out.result, "QueryInfoKey failed");
1425
1426	return true;
1427}
1428
1429static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1430		     struct policy_handle *handle, int depth,
1431		     bool test_security);
1432
1433static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
1434			 struct policy_handle *handle, int depth,
1435			 bool test_security)
1436{
1437	struct winreg_EnumKey r;
1438	struct winreg_StringBuf kclass, name;
1439	NTSTATUS status;
1440	NTTIME t = 0;
1441
1442	kclass.name   = "";
1443	kclass.size   = 1024;
1444
1445	ZERO_STRUCT(r);
1446	r.in.handle = handle;
1447	r.in.enum_index = 0;
1448	r.in.name = &name;
1449	r.in.keyclass = &kclass;
1450	r.out.name = &name;
1451	r.in.last_changed_time = &t;
1452
1453	do {
1454		name.name   = NULL;
1455		name.size   = 1024;
1456
1457		status = dcerpc_winreg_EnumKey(p, tctx, &r);
1458
1459		if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) {
1460			struct policy_handle key_handle;
1461
1462			torture_comment(tctx, "EnumKey: %d: %s\n",
1463					r.in.enum_index,
1464					r.out.name->name);
1465
1466			if (!test_OpenKey(p, tctx, handle, r.out.name->name,
1467					  &key_handle)) {
1468			} else {
1469				test_key(p, tctx, &key_handle,
1470					 depth + 1, test_security);
1471			}
1472		}
1473
1474		r.in.enum_index++;
1475
1476	} while (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result));
1477
1478	torture_assert_ntstatus_ok(tctx, status, "EnumKey failed");
1479
1480	if (!W_ERROR_IS_OK(r.out.result) &&
1481		!W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
1482		torture_fail(tctx, "EnumKey failed");
1483	}
1484
1485	return true;
1486}
1487
1488static bool test_QueryMultipleValues(struct dcerpc_pipe *p,
1489				     struct torture_context *tctx,
1490				     struct policy_handle *handle,
1491				     const char *valuename)
1492{
1493	struct winreg_QueryMultipleValues r;
1494	NTSTATUS status;
1495	uint32_t bufsize=0;
1496
1497	ZERO_STRUCT(r);
1498	r.in.key_handle = handle;
1499	r.in.values = r.out.values = talloc_array(tctx, struct QueryMultipleValue, 1);
1500	r.in.values[0].name = talloc(tctx, struct winreg_String);
1501	r.in.values[0].name->name = valuename;
1502	r.in.values[0].offset = 0;
1503	r.in.values[0].length = 0;
1504	r.in.values[0].type = 0;
1505
1506	r.in.num_values = 1;
1507	r.in.buffer_size = r.out.buffer_size = talloc(tctx, uint32_t);
1508	*r.in.buffer_size = bufsize;
1509	do {
1510		*r.in.buffer_size = bufsize;
1511		r.in.buffer = r.out.buffer = talloc_zero_array(tctx, uint8_t,
1512							       *r.in.buffer_size);
1513
1514		status = dcerpc_winreg_QueryMultipleValues(p, tctx, &r);
1515
1516		if(NT_STATUS_IS_ERR(status))
1517			torture_fail(tctx, "QueryMultipleValues failed");
1518
1519		talloc_free(r.in.buffer);
1520		bufsize += 0x20;
1521	} while (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA));
1522
1523	torture_assert_werr_ok(tctx, r.out.result, "QueryMultipleValues failed");
1524
1525	return true;
1526}
1527
1528static bool test_QueryValue(struct dcerpc_pipe *p,
1529			    struct torture_context *tctx,
1530			    struct policy_handle *handle,
1531			    const char *valuename)
1532{
1533	struct winreg_QueryValue r;
1534	NTSTATUS status;
1535	enum winreg_Type zero_type = 0;
1536	uint32_t offered = 0xfff;
1537	uint32_t zero = 0;
1538
1539	ZERO_STRUCT(r);
1540	r.in.handle = handle;
1541	r.in.data = NULL;
1542	r.in.value_name = talloc_zero(tctx, struct winreg_String);
1543	r.in.value_name->name = valuename;
1544	r.in.type = &zero_type;
1545	r.in.data_size = &offered;
1546	r.in.data_length = &zero;
1547
1548	status = dcerpc_winreg_QueryValue(p, tctx, &r);
1549	if (NT_STATUS_IS_ERR(status)) {
1550		torture_fail(tctx, "QueryValue failed");
1551	}
1552
1553	torture_assert_werr_ok(tctx, r.out.result, "QueryValue failed");
1554
1555	return true;
1556}
1557
1558static bool test_EnumValue(struct dcerpc_pipe *p, struct torture_context *tctx,
1559			   struct policy_handle *handle, int max_valnamelen,
1560			   int max_valbufsize)
1561{
1562	struct winreg_EnumValue r;
1563	enum winreg_Type type = 0;
1564	uint32_t size = max_valbufsize, zero = 0;
1565	bool ret = true;
1566	uint8_t buf8;
1567	struct winreg_ValNameBuf name;
1568
1569	name.name   = "";
1570	name.size   = 1024;
1571
1572	ZERO_STRUCT(r);
1573	r.in.handle = handle;
1574	r.in.enum_index = 0;
1575	r.in.name = &name;
1576	r.out.name = &name;
1577	r.in.type = &type;
1578	r.in.value = &buf8;
1579	r.in.length = &zero;
1580	r.in.size = &size;
1581
1582	do {
1583		torture_assert_ntstatus_ok(tctx,
1584					   dcerpc_winreg_EnumValue(p, tctx, &r),
1585					   "EnumValue failed");
1586
1587		if (W_ERROR_IS_OK(r.out.result)) {
1588			ret &= test_QueryValue(p, tctx, handle,
1589					       r.out.name->name);
1590			ret &= test_QueryMultipleValues(p, tctx, handle,
1591							r.out.name->name);
1592		}
1593
1594		r.in.enum_index++;
1595	} while (W_ERROR_IS_OK(r.out.result));
1596
1597	torture_assert_werr_equal(tctx, r.out.result, WERR_NO_MORE_ITEMS,
1598				  "EnumValue failed");
1599
1600	return ret;
1601}
1602
1603static bool test_AbortSystemShutdown(struct dcerpc_pipe *p,
1604				     struct torture_context *tctx)
1605{
1606	struct winreg_AbortSystemShutdown r;
1607	uint16_t server = 0x0;
1608
1609	ZERO_STRUCT(r);
1610	r.in.server = &server;
1611
1612	torture_assert_ntstatus_ok(tctx,
1613				   dcerpc_winreg_AbortSystemShutdown(p, tctx, &r),
1614				   "AbortSystemShutdown failed");
1615
1616	torture_assert_werr_ok(tctx, r.out.result,
1617			       "AbortSystemShutdown failed");
1618
1619	return true;
1620}
1621
1622static bool test_InitiateSystemShutdown(struct torture_context *tctx,
1623					struct dcerpc_pipe *p)
1624{
1625	struct winreg_InitiateSystemShutdown r;
1626	uint16_t hostname = 0x0;
1627
1628	ZERO_STRUCT(r);
1629	r.in.hostname = &hostname;
1630	r.in.message = talloc(tctx, struct lsa_StringLarge);
1631	init_lsa_StringLarge(r.in.message, "spottyfood");
1632	r.in.force_apps = 1;
1633	r.in.timeout = 30;
1634	r.in.do_reboot = 1;
1635
1636	torture_assert_ntstatus_ok(tctx,
1637				   dcerpc_winreg_InitiateSystemShutdown(p, tctx, &r),
1638				   "InitiateSystemShutdown failed");
1639
1640	torture_assert_werr_ok(tctx, r.out.result,
1641			       "InitiateSystemShutdown failed");
1642
1643	return test_AbortSystemShutdown(p, tctx);
1644}
1645
1646
1647static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
1648					  struct dcerpc_pipe *p)
1649{
1650	struct winreg_InitiateSystemShutdownEx r;
1651	uint16_t hostname = 0x0;
1652
1653	ZERO_STRUCT(r);
1654	r.in.hostname = &hostname;
1655	r.in.message = talloc(tctx, struct lsa_StringLarge);
1656	init_lsa_StringLarge(r.in.message, "spottyfood");
1657	r.in.force_apps = 1;
1658	r.in.timeout = 30;
1659	r.in.do_reboot = 1;
1660	r.in.reason = 0;
1661
1662	torture_assert_ntstatus_ok(tctx,
1663		dcerpc_winreg_InitiateSystemShutdownEx(p, tctx, &r),
1664		"InitiateSystemShutdownEx failed");
1665
1666	torture_assert_werr_ok(tctx, r.out.result,
1667			       "InitiateSystemShutdownEx failed");
1668
1669	return test_AbortSystemShutdown(p, tctx);
1670}
1671#define MAX_DEPTH 2		/* Only go this far down the tree */
1672
1673static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
1674		     struct policy_handle *handle, int depth,
1675		     bool test_security)
1676{
1677	if (depth == MAX_DEPTH)
1678		return true;
1679
1680	if (!test_QueryInfoKey(p, tctx, handle, NULL)) {
1681	}
1682
1683	if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
1684	}
1685
1686	if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
1687	}
1688
1689	if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
1690	}
1691
1692	if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
1693	}
1694
1695	test_CloseKey(p, tctx, handle);
1696
1697	return true;
1698}
1699
1700typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
1701
1702static bool test_Open_Security(struct torture_context *tctx,
1703			       struct dcerpc_pipe *p, void *userdata)
1704{
1705	struct policy_handle handle, newhandle;
1706	bool ret = true, created2 = false;
1707	bool created4 = false;
1708	struct winreg_OpenHKLM r;
1709
1710	winreg_open_fn open_fn = userdata;
1711
1712	ZERO_STRUCT(r);
1713	r.in.system_name = 0;
1714	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1715	r.out.handle = &handle;
1716
1717	torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1718				   "open");
1719
1720	test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1721
1722	if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1723		torture_comment(tctx,
1724				"CreateKey (TEST_KEY_BASE) failed\n");
1725	}
1726
1727	if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
1728			      NULL, &newhandle)) {
1729		created2 = true;
1730	}
1731
1732	if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
1733		printf("CloseKey failed\n");
1734		ret = false;
1735	}
1736
1737	if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
1738		created4 = true;
1739	}
1740
1741	if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
1742		printf("CloseKey failed\n");
1743		ret = false;
1744	}
1745
1746	if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
1747		ret = false;
1748	}
1749
1750	if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
1751		printf("DeleteKey failed\n");
1752		ret = false;
1753	}
1754
1755	if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
1756		printf("DeleteKey failed\n");
1757		ret = false;
1758	}
1759
1760	/* The HKCR hive has a very large fanout */
1761	if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1762		if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
1763			ret = false;
1764		}
1765	} else {
1766		if (!test_key(p, tctx, &handle, 0, true)) {
1767			ret = false;
1768		}
1769	}
1770
1771	test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1772
1773	return ret;
1774}
1775
1776static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
1777		      void *userdata)
1778{
1779	struct policy_handle handle, newhandle;
1780	bool ret = true, created = false, deleted = false;
1781	bool created3 = false, created_subkey = false;
1782	struct winreg_OpenHKLM r;
1783
1784	winreg_open_fn open_fn = userdata;
1785
1786	ZERO_STRUCT(r);
1787	r.in.system_name = 0;
1788	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1789	r.out.handle = &handle;
1790
1791	torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
1792				   "open");
1793
1794	test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1795
1796	if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
1797		torture_comment(tctx,
1798				"CreateKey (TEST_KEY_BASE) failed\n");
1799	}
1800
1801	if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
1802		torture_comment(tctx,
1803				"CreateKey failed - not considering a failure\n");
1804	} else {
1805		created = true;
1806	}
1807
1808	if (created && !test_FlushKey(p, tctx, &handle)) {
1809		torture_comment(tctx, "FlushKey failed\n");
1810		ret = false;
1811	}
1812
1813	if (created && !test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle))
1814		torture_fail(tctx,
1815			     "CreateKey failed (OpenKey after Create didn't work)\n");
1816
1817	if (created && !test_CloseKey(p, tctx, &newhandle))
1818		torture_fail(tctx,
1819			     "CreateKey failed (CloseKey after Open didn't work)\n");
1820
1821	if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY1)) {
1822		torture_comment(tctx, "DeleteKey failed\n");
1823		ret = false;
1824	} else {
1825		deleted = true;
1826	}
1827
1828	if (created && !test_FlushKey(p, tctx, &handle)) {
1829		torture_comment(tctx, "FlushKey failed\n");
1830		ret = false;
1831	}
1832
1833	if (created && deleted &&
1834	    !_test_OpenKey(p, tctx, &handle, TEST_KEY1,
1835			   SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
1836			   WERR_BADFILE, NULL)) {
1837		torture_comment(tctx,
1838				"DeleteKey failed (OpenKey after Delete "
1839				"did not return WERR_BADFILE)\n");
1840		ret = false;
1841	}
1842
1843	if (!test_GetVersion(p, tctx, &handle)) {
1844		torture_comment(tctx, "GetVersion failed\n");
1845		ret = false;
1846	}
1847
1848	if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
1849		created3 = true;
1850	}
1851
1852	if (created3 &&
1853	    test_CreateKey(p, tctx, &handle, TEST_SUBKEY, NULL)) {
1854		created_subkey = true;
1855	}
1856
1857	if (created_subkey &&
1858	    !test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
1859		printf("DeleteKey failed\n");
1860		ret = false;
1861	}
1862
1863	/* The HKCR hive has a very large fanout */
1864	if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
1865		if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
1866			ret = false;
1867		}
1868	} else {
1869		if (!test_key(p, tctx, &handle, 0, false)) {
1870			ret = false;
1871		}
1872	}
1873
1874	test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
1875
1876	return ret;
1877}
1878
1879struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
1880{
1881	struct torture_rpc_tcase *tcase;
1882	struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
1883	struct torture_test *test;
1884
1885	tcase = torture_suite_add_rpc_iface_tcase(suite, "winreg",
1886						  &ndr_table_winreg);
1887
1888	test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdown",
1889					  test_InitiateSystemShutdown);
1890	test->dangerous = true;
1891
1892	test = torture_rpc_tcase_add_test(tcase, "InitiateSystemShutdownEx",
1893					  test_InitiateSystemShutdownEx);
1894	test->dangerous = true;
1895
1896	/* Basic tests without security descriptors */
1897	torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
1898				      test_Open,
1899				      (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1900	torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
1901				      test_Open,
1902				      (winreg_open_fn)dcerpc_winreg_OpenHKU);
1903	torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
1904				      test_Open,
1905				      (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1906	torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
1907				      test_Open,
1908				      (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1909
1910	/* Security descriptor tests */
1911	torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
1912				      test_Open_Security,
1913				      (winreg_open_fn)dcerpc_winreg_OpenHKLM);
1914	torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
1915				      test_Open_Security,
1916				      (winreg_open_fn)dcerpc_winreg_OpenHKU);
1917	torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
1918				      test_Open_Security,
1919				      (winreg_open_fn)dcerpc_winreg_OpenHKCR);
1920	torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
1921				      test_Open_Security,
1922				      (winreg_open_fn)dcerpc_winreg_OpenHKCU);
1923
1924	return suite;
1925}
1926