• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/samba-3.5.8/source4/torture/rpc/
1/*
2   Unix SMB/CIFS implementation.
3   test suite for lsa rpc operations
4
5   Copyright (C) Andrew Tridgell 2003
6   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
7
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.
12
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.
17
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/>.
20*/
21
22#include "includes.h"
23#include "torture/torture.h"
24#include "librpc/gen_ndr/ndr_lsa_c.h"
25#include "librpc/gen_ndr/netlogon.h"
26#include "librpc/gen_ndr/ndr_drsblobs.h"
27#include "lib/events/events.h"
28#include "libcli/security/security.h"
29#include "libcli/auth/libcli_auth.h"
30#include "torture/rpc/rpc.h"
31#include "param/param.h"
32#include "../lib/crypto/crypto.h"
33#define TEST_MACHINENAME "lsatestmach"
34
35static void init_lsa_String(struct lsa_String *name, const char *s)
36{
37	name->string = s;
38}
39
40static bool test_OpenPolicy(struct dcerpc_pipe *p,
41			    struct torture_context *tctx)
42{
43	struct lsa_ObjectAttribute attr;
44	struct policy_handle handle;
45	struct lsa_QosInfo qos;
46	struct lsa_OpenPolicy r;
47	NTSTATUS status;
48	uint16_t system_name = '\\';
49
50	torture_comment(tctx, "\nTesting OpenPolicy\n");
51
52	qos.len = 0;
53	qos.impersonation_level = 2;
54	qos.context_mode = 1;
55	qos.effective_only = 0;
56
57	attr.len = 0;
58	attr.root_dir = NULL;
59	attr.object_name = NULL;
60	attr.attributes = 0;
61	attr.sec_desc = NULL;
62	attr.sec_qos = &qos;
63
64	r.in.system_name = &system_name;
65	r.in.attr = &attr;
66	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
67	r.out.handle = &handle;
68
69	status = dcerpc_lsa_OpenPolicy(p, tctx, &r);
70	if (!NT_STATUS_IS_OK(status)) {
71		if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
72		    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
73			torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
74			return true;
75		}
76		torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status));
77		return false;
78	}
79
80	return true;
81}
82
83
84bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p,
85			  struct torture_context *tctx,
86			  struct policy_handle **handle)
87{
88	struct lsa_ObjectAttribute attr;
89	struct lsa_QosInfo qos;
90	struct lsa_OpenPolicy2 r;
91	NTSTATUS status;
92
93	torture_comment(tctx, "\nTesting OpenPolicy2\n");
94
95	*handle = talloc(tctx, struct policy_handle);
96	if (!*handle) {
97		return false;
98	}
99
100	qos.len = 0;
101	qos.impersonation_level = 2;
102	qos.context_mode = 1;
103	qos.effective_only = 0;
104
105	attr.len = 0;
106	attr.root_dir = NULL;
107	attr.object_name = NULL;
108	attr.attributes = 0;
109	attr.sec_desc = NULL;
110	attr.sec_qos = &qos;
111
112	r.in.system_name = "\\";
113	r.in.attr = &attr;
114	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
115	r.out.handle = *handle;
116
117	status = dcerpc_lsa_OpenPolicy2(p, tctx, &r);
118	if (!NT_STATUS_IS_OK(status)) {
119		if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
120		    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
121			torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
122			talloc_free(*handle);
123			*handle = NULL;
124			return true;
125		}
126		torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
127		return false;
128	}
129
130	return true;
131}
132
133
134static const char *sid_type_lookup(enum lsa_SidType r)
135{
136	switch (r) {
137		case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break;
138		case SID_NAME_USER: return "SID_NAME_USER"; break;
139		case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break;
140		case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break;
141		case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break;
142		case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break;
143		case SID_NAME_DELETED: return "SID_NAME_DELETED"; break;
144		case SID_NAME_INVALID: return "SID_NAME_INVALID"; break;
145		case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break;
146		case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break;
147	}
148	return "Invalid sid type\n";
149}
150
151static bool test_LookupNames(struct dcerpc_pipe *p,
152			     struct torture_context *tctx,
153			     struct policy_handle *handle,
154			     struct lsa_TransNameArray *tnames)
155{
156	struct lsa_LookupNames r;
157	struct lsa_TransSidArray sids;
158	struct lsa_RefDomainList *domains = NULL;
159	struct lsa_String *names;
160	uint32_t count = 0;
161	NTSTATUS status;
162	int i;
163
164	torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
165
166	sids.count = 0;
167	sids.sids = NULL;
168
169	names = talloc_array(tctx, struct lsa_String, tnames->count);
170	for (i=0;i<tnames->count;i++) {
171		init_lsa_String(&names[i], tnames->names[i].name.string);
172	}
173
174	r.in.handle = handle;
175	r.in.num_names = tnames->count;
176	r.in.names = names;
177	r.in.sids = &sids;
178	r.in.level = 1;
179	r.in.count = &count;
180	r.out.count = &count;
181	r.out.sids = &sids;
182	r.out.domains = &domains;
183
184	status = dcerpc_lsa_LookupNames(p, tctx, &r);
185
186	if (NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED) ||
187	    NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
188		for (i=0;i< tnames->count;i++) {
189			if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
190				torture_comment(tctx, "LookupName of %s was unmapped\n",
191				       tnames->names[i].name.string);
192			} else if (i >=count) {
193				torture_comment(tctx, "LookupName of %s failed to return a result\n",
194				       tnames->names[i].name.string);
195			}
196		}
197		torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
198		return false;
199	} else if (!NT_STATUS_IS_OK(status)) {
200		torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
201		return false;
202	}
203
204	for (i=0;i< tnames->count;i++) {
205		if (i < count) {
206			if (sids.sids[i].sid_type != tnames->names[i].sid_type) {
207				torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n",
208				       tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type));
209				return false;
210			}
211			if ((sids.sids[i].sid_type == SID_NAME_DOMAIN) &&
212			    (sids.sids[i].rid != (uint32_t)-1)) {
213				torture_comment(tctx, "LookupName of %s got unexpected rid: %d\n",
214					tnames->names[i].name.string, sids.sids[i].rid);
215				return false;
216			}
217		} else if (i >=count) {
218			torture_comment(tctx, "LookupName of %s failed to return a result\n",
219			       tnames->names[i].name.string);
220			return false;
221		}
222	}
223	torture_comment(tctx, "\n");
224
225	return true;
226}
227
228static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
229				   struct torture_context *tctx,
230				   struct policy_handle *handle)
231{
232	struct lsa_LookupNames r;
233	struct lsa_TransSidArray sids;
234	struct lsa_RefDomainList *domains = NULL;
235	struct lsa_String names[1];
236	uint32_t count = 0;
237	NTSTATUS status;
238
239	torture_comment(tctx, "\nTesting LookupNames with bogus name\n");
240
241	sids.count = 0;
242	sids.sids = NULL;
243
244	init_lsa_String(&names[0], "NT AUTHORITY\\BOGUS");
245
246	r.in.handle = handle;
247	r.in.num_names = 1;
248	r.in.names = names;
249	r.in.sids = &sids;
250	r.in.level = 1;
251	r.in.count = &count;
252	r.out.count = &count;
253	r.out.sids = &sids;
254	r.out.domains = &domains;
255
256	status = dcerpc_lsa_LookupNames(p, tctx, &r);
257	if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
258		torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
259		return false;
260	}
261
262	torture_comment(tctx, "\n");
263
264	return true;
265}
266
267static bool test_LookupNames_NULL(struct dcerpc_pipe *p,
268				  struct torture_context *tctx,
269				  struct policy_handle *handle)
270{
271	struct lsa_LookupNames r;
272	struct lsa_TransSidArray sids;
273	struct lsa_RefDomainList *domains = NULL;
274	struct lsa_String names[1];
275	uint32_t count = 0;
276
277	torture_comment(tctx, "\nTesting LookupNames with NULL name\n");
278
279	sids.count = 0;
280	sids.sids = NULL;
281
282	names[0].string = NULL;
283
284	r.in.handle = handle;
285	r.in.num_names = 1;
286	r.in.names = names;
287	r.in.sids = &sids;
288	r.in.level = 1;
289	r.in.count = &count;
290	r.out.count = &count;
291	r.out.sids = &sids;
292	r.out.domains = &domains;
293
294	/* nt4 returns NT_STATUS_NONE_MAPPED with sid_type
295	 * SID_NAME_UNKNOWN, rid 0, and sid_index -1;
296	 *
297	 * w2k3/w2k8 return NT_STATUS_OK with sid_type
298	 * SID_NAME_DOMAIN, rid -1 and sid_index 0 and BUILTIN domain
299	 */
300
301	torture_assert_ntstatus_ok(tctx, dcerpc_lsa_LookupNames(p, tctx, &r),
302		"LookupNames with NULL name failed");
303
304	torture_comment(tctx, "\n");
305
306	return true;
307}
308
309static bool test_LookupNames_wellknown(struct dcerpc_pipe *p,
310				       struct torture_context *tctx,
311				       struct policy_handle *handle)
312{
313	struct lsa_TranslatedName name;
314	struct lsa_TransNameArray tnames;
315	bool ret = true;
316
317	torture_comment(tctx, "Testing LookupNames with well known names\n");
318
319	tnames.names = &name;
320	tnames.count = 1;
321	name.name.string = "NT AUTHORITY\\SYSTEM";
322	name.sid_type = SID_NAME_WKN_GRP;
323	ret &= test_LookupNames(p, tctx, handle, &tnames);
324
325	name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON";
326	name.sid_type = SID_NAME_WKN_GRP;
327	ret &= test_LookupNames(p, tctx, handle, &tnames);
328
329	name.name.string = "NT AUTHORITY\\Authenticated Users";
330	name.sid_type = SID_NAME_WKN_GRP;
331	ret &= test_LookupNames(p, tctx, handle, &tnames);
332
333#if 0
334	name.name.string = "NT AUTHORITY";
335	ret &= test_LookupNames(p, tctx, handle, &tnames);
336
337	name.name.string = "NT AUTHORITY\\";
338	ret &= test_LookupNames(p, tctx, handle, &tnames);
339#endif
340
341	name.name.string = "BUILTIN\\";
342	name.sid_type = SID_NAME_DOMAIN;
343	ret &= test_LookupNames(p, tctx, handle, &tnames);
344
345	name.name.string = "BUILTIN\\Administrators";
346	name.sid_type = SID_NAME_ALIAS;
347	ret &= test_LookupNames(p, tctx, handle, &tnames);
348
349	name.name.string = "SYSTEM";
350	name.sid_type = SID_NAME_WKN_GRP;
351	ret &= test_LookupNames(p, tctx, handle, &tnames);
352
353	name.name.string = "Everyone";
354	name.sid_type = SID_NAME_WKN_GRP;
355	ret &= test_LookupNames(p, tctx, handle, &tnames);
356	return ret;
357}
358
359static bool test_LookupNames2(struct dcerpc_pipe *p,
360			      struct torture_context *tctx,
361			      struct policy_handle *handle,
362			      struct lsa_TransNameArray2 *tnames,
363			      bool check_result)
364{
365	struct lsa_LookupNames2 r;
366	struct lsa_TransSidArray2 sids;
367	struct lsa_RefDomainList *domains = NULL;
368	struct lsa_String *names;
369	uint32_t count = 0;
370	NTSTATUS status;
371	int i;
372
373	torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
374
375	sids.count = 0;
376	sids.sids = NULL;
377
378	names = talloc_array(tctx, struct lsa_String, tnames->count);
379	for (i=0;i<tnames->count;i++) {
380		init_lsa_String(&names[i], tnames->names[i].name.string);
381	}
382
383	r.in.handle = handle;
384	r.in.num_names = tnames->count;
385	r.in.names = names;
386	r.in.sids = &sids;
387	r.in.level = 1;
388	r.in.count = &count;
389	r.in.lookup_options = 0;
390	r.in.client_revision = 0;
391	r.out.count = &count;
392	r.out.sids = &sids;
393	r.out.domains = &domains;
394
395	status = dcerpc_lsa_LookupNames2(p, tctx, &r);
396	if (!NT_STATUS_IS_OK(status)) {
397		torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status));
398		return false;
399	}
400
401	if (check_result) {
402		torture_assert_int_equal(tctx, count, sids.count,
403			"unexpected number of results returned");
404		if (sids.count > 0) {
405			torture_assert(tctx, sids.sids, "invalid sid buffer");
406		}
407	}
408
409	torture_comment(tctx, "\n");
410
411	return true;
412}
413
414
415static bool test_LookupNames3(struct dcerpc_pipe *p,
416			      struct torture_context *tctx,
417			      struct policy_handle *handle,
418			      struct lsa_TransNameArray2 *tnames,
419			      bool check_result)
420{
421	struct lsa_LookupNames3 r;
422	struct lsa_TransSidArray3 sids;
423	struct lsa_RefDomainList *domains = NULL;
424	struct lsa_String *names;
425	uint32_t count = 0;
426	NTSTATUS status;
427	int i;
428
429	torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
430
431	sids.count = 0;
432	sids.sids = NULL;
433
434	names = talloc_array(tctx, struct lsa_String, tnames->count);
435	for (i=0;i<tnames->count;i++) {
436		init_lsa_String(&names[i], tnames->names[i].name.string);
437	}
438
439	r.in.handle = handle;
440	r.in.num_names = tnames->count;
441	r.in.names = names;
442	r.in.sids = &sids;
443	r.in.level = 1;
444	r.in.count = &count;
445	r.in.lookup_options = 0;
446	r.in.client_revision = 0;
447	r.out.count = &count;
448	r.out.sids = &sids;
449	r.out.domains = &domains;
450
451	status = dcerpc_lsa_LookupNames3(p, tctx, &r);
452	if (!NT_STATUS_IS_OK(status)) {
453		torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status));
454		return false;
455	}
456
457	if (check_result) {
458		torture_assert_int_equal(tctx, count, sids.count,
459			"unexpected number of results returned");
460		if (sids.count > 0) {
461			torture_assert(tctx, sids.sids, "invalid sid buffer");
462		}
463	}
464
465	torture_comment(tctx, "\n");
466
467	return true;
468}
469
470static bool test_LookupNames4(struct dcerpc_pipe *p,
471			      struct torture_context *tctx,
472			      struct lsa_TransNameArray2 *tnames,
473			      bool check_result)
474{
475	struct lsa_LookupNames4 r;
476	struct lsa_TransSidArray3 sids;
477	struct lsa_RefDomainList *domains = NULL;
478	struct lsa_String *names;
479	uint32_t count = 0;
480	NTSTATUS status;
481	int i;
482
483	torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
484
485	sids.count = 0;
486	sids.sids = NULL;
487
488	names = talloc_array(tctx, struct lsa_String, tnames->count);
489	for (i=0;i<tnames->count;i++) {
490		init_lsa_String(&names[i], tnames->names[i].name.string);
491	}
492
493	r.in.num_names = tnames->count;
494	r.in.names = names;
495	r.in.sids = &sids;
496	r.in.level = 1;
497	r.in.count = &count;
498	r.in.lookup_options = 0;
499	r.in.client_revision = 0;
500	r.out.count = &count;
501	r.out.sids = &sids;
502	r.out.domains = &domains;
503
504	status = dcerpc_lsa_LookupNames4(p, tctx, &r);
505	if (!NT_STATUS_IS_OK(status)) {
506		torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status));
507		return false;
508	}
509
510	if (check_result) {
511		torture_assert_int_equal(tctx, count, sids.count,
512			"unexpected number of results returned");
513		if (sids.count > 0) {
514			torture_assert(tctx, sids.sids, "invalid sid buffer");
515		}
516	}
517
518	torture_comment(tctx, "\n");
519
520	return true;
521}
522
523
524static bool test_LookupSids(struct dcerpc_pipe *p,
525			    struct torture_context *tctx,
526			    struct policy_handle *handle,
527			    struct lsa_SidArray *sids)
528{
529	struct lsa_LookupSids r;
530	struct lsa_TransNameArray names;
531	struct lsa_RefDomainList *domains = NULL;
532	uint32_t count = sids->num_sids;
533	NTSTATUS status;
534
535	torture_comment(tctx, "\nTesting LookupSids\n");
536
537	names.count = 0;
538	names.names = NULL;
539
540	r.in.handle = handle;
541	r.in.sids = sids;
542	r.in.names = &names;
543	r.in.level = 1;
544	r.in.count = &count;
545	r.out.count = &count;
546	r.out.names = &names;
547	r.out.domains = &domains;
548
549	status = dcerpc_lsa_LookupSids(p, tctx, &r);
550	if (!NT_STATUS_IS_OK(status)) {
551		torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
552		return false;
553	}
554
555	torture_comment(tctx, "\n");
556
557	if (!test_LookupNames(p, tctx, handle, &names)) {
558		return false;
559	}
560
561	return true;
562}
563
564
565static bool test_LookupSids2(struct dcerpc_pipe *p,
566			    struct torture_context *tctx,
567			    struct policy_handle *handle,
568			    struct lsa_SidArray *sids)
569{
570	struct lsa_LookupSids2 r;
571	struct lsa_TransNameArray2 names;
572	struct lsa_RefDomainList *domains = NULL;
573	uint32_t count = sids->num_sids;
574	NTSTATUS status;
575
576	torture_comment(tctx, "\nTesting LookupSids2\n");
577
578	names.count = 0;
579	names.names = NULL;
580
581	r.in.handle = handle;
582	r.in.sids = sids;
583	r.in.names = &names;
584	r.in.level = 1;
585	r.in.count = &count;
586	r.in.lookup_options = 0;
587	r.in.client_revision = 0;
588	r.out.count = &count;
589	r.out.names = &names;
590	r.out.domains = &domains;
591
592	status = dcerpc_lsa_LookupSids2(p, tctx, &r);
593	if (!NT_STATUS_IS_OK(status)) {
594		torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status));
595		return false;
596	}
597
598	torture_comment(tctx, "\n");
599
600	if (!test_LookupNames2(p, tctx, handle, &names, false)) {
601		return false;
602	}
603
604	if (!test_LookupNames3(p, tctx, handle, &names, false)) {
605		return false;
606	}
607
608	return true;
609}
610
611static bool test_LookupSids3(struct dcerpc_pipe *p,
612			    struct torture_context *tctx,
613			    struct lsa_SidArray *sids)
614{
615	struct lsa_LookupSids3 r;
616	struct lsa_TransNameArray2 names;
617	struct lsa_RefDomainList *domains = NULL;
618	uint32_t count = sids->num_sids;
619	NTSTATUS status;
620
621	torture_comment(tctx, "\nTesting LookupSids3\n");
622
623	names.count = 0;
624	names.names = NULL;
625
626	r.in.sids = sids;
627	r.in.names = &names;
628	r.in.level = 1;
629	r.in.count = &count;
630	r.in.lookup_options = 0;
631	r.in.client_revision = 0;
632	r.out.domains = &domains;
633	r.out.count = &count;
634	r.out.names = &names;
635
636	status = dcerpc_lsa_LookupSids3(p, tctx, &r);
637	if (!NT_STATUS_IS_OK(status)) {
638		if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
639		    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
640			torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
641			return true;
642		}
643		torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n",
644		       nt_errstr(status));
645		return false;
646	}
647
648	torture_comment(tctx, "\n");
649
650	if (!test_LookupNames4(p, tctx, &names, false)) {
651		return false;
652	}
653
654	return true;
655}
656
657bool test_many_LookupSids(struct dcerpc_pipe *p,
658			  struct torture_context *tctx,
659			  struct policy_handle *handle)
660{
661	uint32_t count;
662	NTSTATUS status;
663	struct lsa_SidArray sids;
664	int i;
665
666	torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
667
668	sids.num_sids = 100;
669
670	sids.sids = talloc_array(tctx, struct lsa_SidPtr, sids.num_sids);
671
672	for (i=0; i<sids.num_sids; i++) {
673		const char *sidstr = "S-1-5-32-545";
674		sids.sids[i].sid = dom_sid_parse_talloc(tctx, sidstr);
675	}
676
677	count = sids.num_sids;
678
679	if (handle) {
680		struct lsa_LookupSids r;
681		struct lsa_TransNameArray names;
682		struct lsa_RefDomainList *domains = NULL;
683		names.count = 0;
684		names.names = NULL;
685
686		r.in.handle = handle;
687		r.in.sids = &sids;
688		r.in.names = &names;
689		r.in.level = 1;
690		r.in.count = &names.count;
691		r.out.count = &count;
692		r.out.names = &names;
693		r.out.domains = &domains;
694
695		status = dcerpc_lsa_LookupSids(p, tctx, &r);
696		if (!NT_STATUS_IS_OK(status)) {
697			torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
698			return false;
699		}
700
701		torture_comment(tctx, "\n");
702
703		if (!test_LookupNames(p, tctx, handle, &names)) {
704			return false;
705		}
706	} else if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
707		   p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
708		struct lsa_LookupSids3 r;
709		struct lsa_RefDomainList *domains = NULL;
710		struct lsa_TransNameArray2 names;
711
712		names.count = 0;
713		names.names = NULL;
714
715		torture_comment(tctx, "\nTesting LookupSids3\n");
716
717		r.in.sids = &sids;
718		r.in.names = &names;
719		r.in.level = 1;
720		r.in.count = &count;
721		r.in.lookup_options = 0;
722		r.in.client_revision = 0;
723		r.out.count = &count;
724		r.out.names = &names;
725		r.out.domains = &domains;
726
727		status = dcerpc_lsa_LookupSids3(p, tctx, &r);
728		if (!NT_STATUS_IS_OK(status)) {
729			if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
730			    NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
731				torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
732				return true;
733			}
734			torture_comment(tctx, "LookupSids3 failed - %s\n",
735			       nt_errstr(status));
736			return false;
737		}
738		if (!test_LookupNames4(p, tctx, &names, false)) {
739			return false;
740		}
741	}
742
743	torture_comment(tctx, "\n");
744
745
746
747	return true;
748}
749
750static void lookupsids_cb(struct rpc_request *req)
751{
752	int *replies = (int *)req->async.private_data;
753	NTSTATUS status;
754
755	status = dcerpc_ndr_request_recv(req);
756	if (!NT_STATUS_IS_OK(status)) {
757		printf("lookupsids returned %s\n", nt_errstr(status));
758		*replies = -1;
759	}
760
761	if (*replies >= 0) {
762		*replies += 1;
763	}
764}
765
766static bool test_LookupSids_async(struct dcerpc_pipe *p,
767				  struct torture_context *tctx,
768				  struct policy_handle *handle)
769{
770	struct lsa_SidArray sids;
771	struct lsa_SidPtr sidptr;
772	uint32_t *count;
773	struct lsa_TransNameArray *names;
774	struct lsa_LookupSids *r;
775	struct lsa_RefDomainList *domains = NULL;
776	struct rpc_request **req;
777	int i, replies;
778	bool ret = true;
779	const int num_async_requests = 50;
780
781	count = talloc_array(tctx, uint32_t, num_async_requests);
782	names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
783	r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
784
785	torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
786
787	req = talloc_array(tctx, struct rpc_request *, num_async_requests);
788
789	sids.num_sids = 1;
790	sids.sids = &sidptr;
791	sidptr.sid = dom_sid_parse_talloc(tctx, "S-1-5-32-545");
792
793	replies = 0;
794
795	for (i=0; i<num_async_requests; i++) {
796		count[i] = 0;
797		names[i].count = 0;
798		names[i].names = NULL;
799
800		r[i].in.handle = handle;
801		r[i].in.sids = &sids;
802		r[i].in.names = &names[i];
803		r[i].in.level = 1;
804		r[i].in.count = &names[i].count;
805		r[i].out.count = &count[i];
806		r[i].out.names = &names[i];
807		r[i].out.domains = &domains;
808
809		req[i] = dcerpc_lsa_LookupSids_send(p, req, &r[i]);
810		if (req[i] == NULL) {
811			ret = false;
812			break;
813		}
814
815		req[i]->async.callback = lookupsids_cb;
816		req[i]->async.private_data = &replies;
817	}
818
819	while (replies >= 0 && replies < num_async_requests) {
820		event_loop_once(p->conn->event_ctx);
821	}
822
823	talloc_free(req);
824
825	if (replies < 0) {
826		ret = false;
827	}
828
829	return ret;
830}
831
832static bool test_LookupPrivValue(struct dcerpc_pipe *p,
833				 struct torture_context *tctx,
834				 struct policy_handle *handle,
835				 struct lsa_String *name)
836{
837	NTSTATUS status;
838	struct lsa_LookupPrivValue r;
839	struct lsa_LUID luid;
840
841	r.in.handle = handle;
842	r.in.name = name;
843	r.out.luid = &luid;
844
845	status = dcerpc_lsa_LookupPrivValue(p, tctx, &r);
846	if (!NT_STATUS_IS_OK(status)) {
847		torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status));
848		return false;
849	}
850
851	return true;
852}
853
854static bool test_LookupPrivName(struct dcerpc_pipe *p,
855				struct torture_context *tctx,
856				struct policy_handle *handle,
857				struct lsa_LUID *luid)
858{
859	NTSTATUS status;
860	struct lsa_LookupPrivName r;
861	struct lsa_StringLarge *name = NULL;
862
863	r.in.handle = handle;
864	r.in.luid = luid;
865	r.out.name = &name;
866
867	status = dcerpc_lsa_LookupPrivName(p, tctx, &r);
868	if (!NT_STATUS_IS_OK(status)) {
869		torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
870		return false;
871	}
872
873	return true;
874}
875
876static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
877					     struct torture_context *tctx,
878					     struct policy_handle *handle,
879					     struct policy_handle *acct_handle,
880					     struct lsa_LUID *luid)
881{
882	NTSTATUS status;
883	struct lsa_RemovePrivilegesFromAccount r;
884	struct lsa_PrivilegeSet privs;
885	bool ret = true;
886
887	torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
888
889	r.in.handle = acct_handle;
890	r.in.remove_all = 0;
891	r.in.privs = &privs;
892
893	privs.count = 1;
894	privs.unknown = 0;
895	privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
896	privs.set[0].luid = *luid;
897	privs.set[0].attribute = 0;
898
899	status = dcerpc_lsa_RemovePrivilegesFromAccount(p, tctx, &r);
900	if (!NT_STATUS_IS_OK(status)) {
901
902		struct lsa_LookupPrivName r_name;
903		struct lsa_StringLarge *name = NULL;
904
905		r_name.in.handle = handle;
906		r_name.in.luid = luid;
907		r_name.out.name = &name;
908
909		status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name);
910		if (!NT_STATUS_IS_OK(status)) {
911			torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
912			return false;
913		}
914		/* Windows 2008 does not allow this to be removed */
915		if (strcmp("SeAuditPrivilege", name->string) == 0) {
916			return ret;
917		}
918
919		torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
920		       name->string,
921		       nt_errstr(status));
922		return false;
923	}
924
925	return ret;
926}
927
928static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
929					struct torture_context *tctx,
930					struct policy_handle *acct_handle,
931					struct lsa_LUID *luid)
932{
933	NTSTATUS status;
934	struct lsa_AddPrivilegesToAccount r;
935	struct lsa_PrivilegeSet privs;
936	bool ret = true;
937
938	torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
939
940	r.in.handle = acct_handle;
941	r.in.privs = &privs;
942
943	privs.count = 1;
944	privs.unknown = 0;
945	privs.set = talloc_array(tctx, struct lsa_LUIDAttribute, 1);
946	privs.set[0].luid = *luid;
947	privs.set[0].attribute = 0;
948
949	status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r);
950	if (!NT_STATUS_IS_OK(status)) {
951		torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
952		return false;
953	}
954
955	return ret;
956}
957
958static bool test_EnumPrivsAccount(struct dcerpc_pipe *p,
959				  struct torture_context *tctx,
960				  struct policy_handle *handle,
961				  struct policy_handle *acct_handle)
962{
963	NTSTATUS status;
964	struct lsa_EnumPrivsAccount r;
965	struct lsa_PrivilegeSet *privs = NULL;
966	bool ret = true;
967
968	torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
969
970	r.in.handle = acct_handle;
971	r.out.privs = &privs;
972
973	status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r);
974	if (!NT_STATUS_IS_OK(status)) {
975		torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status));
976		return false;
977	}
978
979	if (privs && privs->count > 0) {
980		int i;
981		for (i=0;i<privs->count;i++) {
982			test_LookupPrivName(p, tctx, handle,
983					    &privs->set[i].luid);
984		}
985
986		ret &= test_RemovePrivilegesFromAccount(p, tctx, handle, acct_handle,
987							&privs->set[0].luid);
988		ret &= test_AddPrivilegesToAccount(p, tctx, acct_handle,
989						   &privs->set[0].luid);
990	}
991
992	return ret;
993}
994
995static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p,
996					struct torture_context *tctx,
997					struct policy_handle *handle,
998					struct policy_handle *acct_handle)
999{
1000	NTSTATUS status;
1001	uint32_t access_mask;
1002	struct lsa_GetSystemAccessAccount r;
1003
1004	torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
1005
1006	r.in.handle = acct_handle;
1007	r.out.access_mask = &access_mask;
1008
1009	status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r);
1010	if (!NT_STATUS_IS_OK(status)) {
1011		torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status));
1012		return false;
1013	}
1014
1015	if (r.out.access_mask != NULL) {
1016		torture_comment(tctx, "Rights:");
1017		if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
1018			torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
1019		if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
1020			torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
1021		if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
1022			torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
1023		if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
1024			torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
1025		if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
1026			torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
1027		if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
1028			torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
1029		if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
1030			torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
1031		if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
1032			torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
1033		if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
1034			torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
1035		if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
1036			torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
1037		if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
1038			torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
1039		if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
1040			torture_comment(tctx, " LSA_POLICY_MODE_ALL");
1041		if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
1042			torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
1043		torture_comment(tctx, "\n");
1044	}
1045
1046	return true;
1047}
1048
1049static bool test_Delete(struct dcerpc_pipe *p,
1050			struct torture_context *tctx,
1051			struct policy_handle *handle)
1052{
1053	NTSTATUS status;
1054	struct lsa_Delete r;
1055
1056	torture_comment(tctx, "\nTesting Delete\n");
1057
1058	r.in.handle = handle;
1059	status = dcerpc_lsa_Delete(p, tctx, &r);
1060	if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1061		torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
1062		return false;
1063	}
1064
1065	return true;
1066}
1067
1068static bool test_DeleteObject(struct dcerpc_pipe *p,
1069			      struct torture_context *tctx,
1070			      struct policy_handle *handle)
1071{
1072	NTSTATUS status;
1073	struct lsa_DeleteObject r;
1074
1075	torture_comment(tctx, "\nTesting DeleteObject\n");
1076
1077	r.in.handle = handle;
1078	r.out.handle = handle;
1079	status = dcerpc_lsa_DeleteObject(p, tctx, &r);
1080	if (!NT_STATUS_IS_OK(status)) {
1081		torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status));
1082		return false;
1083	}
1084
1085	return true;
1086}
1087
1088
1089static bool test_CreateAccount(struct dcerpc_pipe *p,
1090			       struct torture_context *tctx,
1091			       struct policy_handle *handle)
1092{
1093	NTSTATUS status;
1094	struct lsa_CreateAccount r;
1095	struct dom_sid2 *newsid;
1096	struct policy_handle acct_handle;
1097
1098	newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
1099
1100	torture_comment(tctx, "\nTesting CreateAccount\n");
1101
1102	r.in.handle = handle;
1103	r.in.sid = newsid;
1104	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1105	r.out.acct_handle = &acct_handle;
1106
1107	status = dcerpc_lsa_CreateAccount(p, tctx, &r);
1108	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1109		struct lsa_OpenAccount r_o;
1110		r_o.in.handle = handle;
1111		r_o.in.sid = newsid;
1112		r_o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1113		r_o.out.acct_handle = &acct_handle;
1114
1115		status = dcerpc_lsa_OpenAccount(p, tctx, &r_o);
1116		if (!NT_STATUS_IS_OK(status)) {
1117			torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
1118			return false;
1119		}
1120	} else if (!NT_STATUS_IS_OK(status)) {
1121		torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status));
1122		return false;
1123	}
1124
1125	if (!test_Delete(p, tctx, &acct_handle)) {
1126		return false;
1127	}
1128
1129	if (!test_DeleteObject(p, tctx, &acct_handle)) {
1130		return false;
1131	}
1132
1133	return true;
1134}
1135
1136static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p,
1137				     struct torture_context *tctx,
1138				     struct policy_handle *handle,
1139				     struct lsa_StringLarge name)
1140{
1141	NTSTATUS status;
1142	struct lsa_OpenTrustedDomainByName r;
1143	struct policy_handle trustdom_handle;
1144
1145	r.in.handle = handle;
1146	r.in.name.string = name.string;
1147	r.in.access_mask = SEC_STD_DELETE;
1148	r.out.trustdom_handle = &trustdom_handle;
1149
1150	status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r);
1151	if (!NT_STATUS_IS_OK(status)) {
1152		torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1153		return false;
1154	}
1155
1156	if (!test_Delete(p, tctx, &trustdom_handle)) {
1157		return false;
1158	}
1159
1160	if (!test_DeleteObject(p, tctx, &trustdom_handle)) {
1161		return false;
1162	}
1163
1164	return true;
1165}
1166
1167static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p,
1168					  struct torture_context *tctx,
1169					  struct policy_handle *handle,
1170					  struct dom_sid *sid)
1171{
1172	NTSTATUS status;
1173	struct lsa_DeleteTrustedDomain r;
1174
1175	r.in.handle = handle;
1176	r.in.dom_sid = sid;
1177
1178	status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r);
1179	if (!NT_STATUS_IS_OK(status)) {
1180		torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status));
1181		return false;
1182	}
1183
1184	return true;
1185}
1186
1187
1188static bool test_CreateSecret(struct dcerpc_pipe *p,
1189			      struct torture_context *tctx,
1190			      struct policy_handle *handle)
1191{
1192	NTSTATUS status;
1193	struct lsa_CreateSecret r;
1194	struct lsa_OpenSecret r2;
1195	struct lsa_SetSecret r3;
1196	struct lsa_QuerySecret r4;
1197	struct lsa_SetSecret r5;
1198	struct lsa_QuerySecret r6;
1199	struct lsa_SetSecret r7;
1200	struct lsa_QuerySecret r8;
1201	struct policy_handle sec_handle, sec_handle2, sec_handle3;
1202	struct lsa_DeleteObject d_o;
1203	struct lsa_DATA_BUF buf1;
1204	struct lsa_DATA_BUF_PTR bufp1;
1205	struct lsa_DATA_BUF_PTR bufp2;
1206	DATA_BLOB enc_key;
1207	bool ret = true;
1208	DATA_BLOB session_key;
1209	NTTIME old_mtime, new_mtime;
1210	DATA_BLOB blob1, blob2;
1211	const char *secret1 = "abcdef12345699qwerty";
1212	char *secret2;
1213 	const char *secret3 = "ABCDEF12345699QWERTY";
1214	char *secret4;
1215 	const char *secret5 = "NEW-SAMBA4-SECRET";
1216	char *secret6;
1217	char *secname[2];
1218	int i;
1219	const int LOCAL = 0;
1220	const int GLOBAL = 1;
1221
1222	secname[LOCAL] = talloc_asprintf(tctx, "torturesecret-%u", (uint_t)random());
1223	secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random());
1224
1225	for (i=0; i< 2; i++) {
1226		torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
1227
1228		init_lsa_String(&r.in.name, secname[i]);
1229
1230		r.in.handle = handle;
1231		r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1232		r.out.sec_handle = &sec_handle;
1233
1234		status = dcerpc_lsa_CreateSecret(p, tctx, &r);
1235		if (!NT_STATUS_IS_OK(status)) {
1236			torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status));
1237			return false;
1238		}
1239
1240		r.in.handle = handle;
1241		r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1242		r.out.sec_handle = &sec_handle3;
1243
1244		status = dcerpc_lsa_CreateSecret(p, tctx, &r);
1245		if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
1246			torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
1247			return false;
1248		}
1249
1250		r2.in.handle = handle;
1251		r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1252		r2.in.name = r.in.name;
1253		r2.out.sec_handle = &sec_handle2;
1254
1255		torture_comment(tctx, "Testing OpenSecret\n");
1256
1257		status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
1258		if (!NT_STATUS_IS_OK(status)) {
1259			torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status));
1260			return false;
1261		}
1262
1263		status = dcerpc_fetch_session_key(p, &session_key);
1264		if (!NT_STATUS_IS_OK(status)) {
1265			torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
1266			return false;
1267		}
1268
1269		enc_key = sess_encrypt_string(secret1, &session_key);
1270
1271		r3.in.sec_handle = &sec_handle;
1272		r3.in.new_val = &buf1;
1273		r3.in.old_val = NULL;
1274		r3.in.new_val->data = enc_key.data;
1275		r3.in.new_val->length = enc_key.length;
1276		r3.in.new_val->size = enc_key.length;
1277
1278		torture_comment(tctx, "Testing SetSecret\n");
1279
1280		status = dcerpc_lsa_SetSecret(p, tctx, &r3);
1281		if (!NT_STATUS_IS_OK(status)) {
1282			torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
1283			return false;
1284		}
1285
1286		r3.in.sec_handle = &sec_handle;
1287		r3.in.new_val = &buf1;
1288		r3.in.old_val = NULL;
1289		r3.in.new_val->data = enc_key.data;
1290		r3.in.new_val->length = enc_key.length;
1291		r3.in.new_val->size = enc_key.length;
1292
1293		/* break the encrypted data */
1294		enc_key.data[0]++;
1295
1296		torture_comment(tctx, "Testing SetSecret with broken key\n");
1297
1298		status = dcerpc_lsa_SetSecret(p, tctx, &r3);
1299		if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
1300			torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
1301			ret = false;
1302		}
1303
1304		data_blob_free(&enc_key);
1305
1306		ZERO_STRUCT(new_mtime);
1307		ZERO_STRUCT(old_mtime);
1308
1309		/* fetch the secret back again */
1310		r4.in.sec_handle = &sec_handle;
1311		r4.in.new_val = &bufp1;
1312		r4.in.new_mtime = &new_mtime;
1313		r4.in.old_val = NULL;
1314		r4.in.old_mtime = NULL;
1315
1316		bufp1.buf = NULL;
1317
1318		torture_comment(tctx, "Testing QuerySecret\n");
1319		status = dcerpc_lsa_QuerySecret(p, tctx, &r4);
1320		if (!NT_STATUS_IS_OK(status)) {
1321			torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
1322			ret = false;
1323		} else {
1324			if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
1325				torture_comment(tctx, "No secret buffer returned\n");
1326				ret = false;
1327			} else {
1328				blob1.data = r4.out.new_val->buf->data;
1329				blob1.length = r4.out.new_val->buf->size;
1330
1331				blob2 = data_blob_talloc(tctx, NULL, blob1.length);
1332
1333				secret2 = sess_decrypt_string(tctx,
1334							      &blob1, &session_key);
1335
1336				if (strcmp(secret1, secret2) != 0) {
1337					torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
1338					       secret2, secret1);
1339					ret = false;
1340				}
1341			}
1342		}
1343
1344		enc_key = sess_encrypt_string(secret3, &session_key);
1345
1346		r5.in.sec_handle = &sec_handle;
1347		r5.in.new_val = &buf1;
1348		r5.in.old_val = NULL;
1349		r5.in.new_val->data = enc_key.data;
1350		r5.in.new_val->length = enc_key.length;
1351		r5.in.new_val->size = enc_key.length;
1352
1353
1354		msleep(200);
1355		torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
1356
1357		status = dcerpc_lsa_SetSecret(p, tctx, &r5);
1358		if (!NT_STATUS_IS_OK(status)) {
1359			torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
1360			ret = false;
1361		}
1362
1363		data_blob_free(&enc_key);
1364
1365		ZERO_STRUCT(new_mtime);
1366		ZERO_STRUCT(old_mtime);
1367
1368		/* fetch the secret back again */
1369		r6.in.sec_handle = &sec_handle;
1370		r6.in.new_val = &bufp1;
1371		r6.in.new_mtime = &new_mtime;
1372		r6.in.old_val = &bufp2;
1373		r6.in.old_mtime = &old_mtime;
1374
1375		bufp1.buf = NULL;
1376		bufp2.buf = NULL;
1377
1378		status = dcerpc_lsa_QuerySecret(p, tctx, &r6);
1379		if (!NT_STATUS_IS_OK(status)) {
1380			torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
1381			ret = false;
1382			secret4 = NULL;
1383		} else {
1384
1385			if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
1386				|| r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
1387				torture_comment(tctx, "Both secret buffers and both times not returned\n");
1388				ret = false;
1389				secret4 = NULL;
1390			} else {
1391				blob1.data = r6.out.new_val->buf->data;
1392				blob1.length = r6.out.new_val->buf->size;
1393
1394				blob2 = data_blob_talloc(tctx, NULL, blob1.length);
1395
1396				secret4 = sess_decrypt_string(tctx,
1397							      &blob1, &session_key);
1398
1399				if (strcmp(secret3, secret4) != 0) {
1400					torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
1401					ret = false;
1402				}
1403
1404				blob1.data = r6.out.old_val->buf->data;
1405				blob1.length = r6.out.old_val->buf->length;
1406
1407				blob2 = data_blob_talloc(tctx, NULL, blob1.length);
1408
1409				secret2 = sess_decrypt_string(tctx,
1410							      &blob1, &session_key);
1411
1412				if (strcmp(secret1, secret2) != 0) {
1413					torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
1414					ret = false;
1415				}
1416
1417				if (*r6.out.new_mtime == *r6.out.old_mtime) {
1418					torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
1419					       i,
1420					       secname[i],
1421					       nt_time_string(tctx, *r6.out.old_mtime),
1422					       nt_time_string(tctx, *r6.out.new_mtime));
1423					ret = false;
1424				}
1425			}
1426		}
1427
1428		enc_key = sess_encrypt_string(secret5, &session_key);
1429
1430		r7.in.sec_handle = &sec_handle;
1431		r7.in.old_val = &buf1;
1432		r7.in.old_val->data = enc_key.data;
1433		r7.in.old_val->length = enc_key.length;
1434		r7.in.old_val->size = enc_key.length;
1435		r7.in.new_val = NULL;
1436
1437		torture_comment(tctx, "Testing SetSecret of old Secret only\n");
1438
1439		status = dcerpc_lsa_SetSecret(p, tctx, &r7);
1440		if (!NT_STATUS_IS_OK(status)) {
1441			torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
1442			ret = false;
1443		}
1444
1445		data_blob_free(&enc_key);
1446
1447		/* fetch the secret back again */
1448		r8.in.sec_handle = &sec_handle;
1449		r8.in.new_val = &bufp1;
1450		r8.in.new_mtime = &new_mtime;
1451		r8.in.old_val = &bufp2;
1452		r8.in.old_mtime = &old_mtime;
1453
1454		bufp1.buf = NULL;
1455		bufp2.buf = NULL;
1456
1457		status = dcerpc_lsa_QuerySecret(p, tctx, &r8);
1458		if (!NT_STATUS_IS_OK(status)) {
1459			torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
1460			ret = false;
1461		} else {
1462			if (!r8.out.new_val || !r8.out.old_val) {
1463				torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
1464				ret = false;
1465			} else if (r8.out.new_val->buf != NULL) {
1466				torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
1467				ret = false;
1468			} else if (r8.out.old_val->buf == NULL) {
1469				torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
1470				ret = false;
1471			} else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
1472				torture_comment(tctx, "Both times not returned after OLD set\n");
1473				ret = false;
1474			} else {
1475				blob1.data = r8.out.old_val->buf->data;
1476				blob1.length = r8.out.old_val->buf->size;
1477
1478				blob2 = data_blob_talloc(tctx, NULL, blob1.length);
1479
1480				secret6 = sess_decrypt_string(tctx,
1481							      &blob1, &session_key);
1482
1483				if (strcmp(secret5, secret6) != 0) {
1484					torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
1485					ret = false;
1486				}
1487
1488				if (*r8.out.new_mtime != *r8.out.old_mtime) {
1489					torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
1490					       secname[i],
1491					       nt_time_string(tctx, *r8.out.old_mtime),
1492					       nt_time_string(tctx, *r8.out.new_mtime));
1493					ret = false;
1494				}
1495			}
1496		}
1497
1498		if (!test_Delete(p, tctx, &sec_handle)) {
1499			ret = false;
1500		}
1501
1502		if (!test_DeleteObject(p, tctx, &sec_handle)) {
1503			return false;
1504		}
1505
1506		d_o.in.handle = &sec_handle2;
1507		d_o.out.handle = &sec_handle2;
1508		status = dcerpc_lsa_DeleteObject(p, tctx, &d_o);
1509		if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
1510			torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
1511			ret = false;
1512		} else {
1513
1514			torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
1515
1516			status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
1517			if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1518				torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
1519				ret = false;
1520			}
1521		}
1522
1523	}
1524
1525	return ret;
1526}
1527
1528
1529static bool test_EnumAccountRights(struct dcerpc_pipe *p,
1530				   struct torture_context *tctx,
1531				   struct policy_handle *acct_handle,
1532				   struct dom_sid *sid)
1533{
1534	NTSTATUS status;
1535	struct lsa_EnumAccountRights r;
1536	struct lsa_RightSet rights;
1537
1538	torture_comment(tctx, "\nTesting EnumAccountRights\n");
1539
1540	r.in.handle = acct_handle;
1541	r.in.sid = sid;
1542	r.out.rights = &rights;
1543
1544	status = dcerpc_lsa_EnumAccountRights(p, tctx, &r);
1545	if (!NT_STATUS_IS_OK(status)) {
1546		torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
1547		       dom_sid_string(tctx, sid), nt_errstr(status));
1548		return false;
1549	}
1550
1551	return true;
1552}
1553
1554
1555static bool test_QuerySecurity(struct dcerpc_pipe *p,
1556			     struct torture_context *tctx,
1557			     struct policy_handle *handle,
1558			     struct policy_handle *acct_handle)
1559{
1560	NTSTATUS status;
1561	struct lsa_QuerySecurity r;
1562	struct sec_desc_buf *sdbuf = NULL;
1563
1564	if (torture_setting_bool(tctx, "samba4", false)) {
1565		torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
1566		return true;
1567	}
1568
1569	torture_comment(tctx, "\nTesting QuerySecurity\n");
1570
1571	r.in.handle = acct_handle;
1572	r.in.sec_info = SECINFO_OWNER |
1573			SECINFO_GROUP |
1574			SECINFO_DACL;
1575	r.out.sdbuf = &sdbuf;
1576
1577	status = dcerpc_lsa_QuerySecurity(p, tctx, &r);
1578	if (!NT_STATUS_IS_OK(status)) {
1579		torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status));
1580		return false;
1581	}
1582
1583	return true;
1584}
1585
1586static bool test_OpenAccount(struct dcerpc_pipe *p,
1587			     struct torture_context *tctx,
1588			     struct policy_handle *handle,
1589			     struct dom_sid *sid)
1590{
1591	NTSTATUS status;
1592	struct lsa_OpenAccount r;
1593	struct policy_handle acct_handle;
1594
1595	torture_comment(tctx, "\nTesting OpenAccount\n");
1596
1597	r.in.handle = handle;
1598	r.in.sid = sid;
1599	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1600	r.out.acct_handle = &acct_handle;
1601
1602	status = dcerpc_lsa_OpenAccount(p, tctx, &r);
1603	if (!NT_STATUS_IS_OK(status)) {
1604		torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
1605		return false;
1606	}
1607
1608	if (!test_EnumPrivsAccount(p, tctx, handle, &acct_handle)) {
1609		return false;
1610	}
1611
1612	if (!test_GetSystemAccessAccount(p, tctx, handle, &acct_handle)) {
1613		return false;
1614	}
1615
1616	if (!test_QuerySecurity(p, tctx, handle, &acct_handle)) {
1617		return false;
1618	}
1619
1620	return true;
1621}
1622
1623static bool test_EnumAccounts(struct dcerpc_pipe *p,
1624			      struct torture_context *tctx,
1625			      struct policy_handle *handle)
1626{
1627	NTSTATUS status;
1628	struct lsa_EnumAccounts r;
1629	struct lsa_SidArray sids1, sids2;
1630	uint32_t resume_handle = 0;
1631	int i;
1632	bool ret = true;
1633
1634	torture_comment(tctx, "\nTesting EnumAccounts\n");
1635
1636	r.in.handle = handle;
1637	r.in.resume_handle = &resume_handle;
1638	r.in.num_entries = 100;
1639	r.out.resume_handle = &resume_handle;
1640	r.out.sids = &sids1;
1641
1642	resume_handle = 0;
1643	while (true) {
1644		status = dcerpc_lsa_EnumAccounts(p, tctx, &r);
1645		if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1646			break;
1647		}
1648		if (!NT_STATUS_IS_OK(status)) {
1649			torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
1650			return false;
1651		}
1652
1653		if (!test_LookupSids(p, tctx, handle, &sids1)) {
1654			return false;
1655		}
1656
1657		if (!test_LookupSids2(p, tctx, handle, &sids1)) {
1658			return false;
1659		}
1660
1661		/* Can't test lookupSids3 here, as clearly we must not
1662		 * be on schannel, or we would not be able to do the
1663		 * rest */
1664
1665		torture_comment(tctx, "Testing all accounts\n");
1666		for (i=0;i<sids1.num_sids;i++) {
1667			ret &= test_OpenAccount(p, tctx, handle, sids1.sids[i].sid);
1668			ret &= test_EnumAccountRights(p, tctx, handle, sids1.sids[i].sid);
1669		}
1670		torture_comment(tctx, "\n");
1671	}
1672
1673	if (sids1.num_sids < 3) {
1674		return ret;
1675	}
1676
1677	torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
1678	resume_handle = 2;
1679	r.in.num_entries = 1;
1680	r.out.sids = &sids2;
1681
1682	status = dcerpc_lsa_EnumAccounts(p, tctx, &r);
1683	if (!NT_STATUS_IS_OK(status)) {
1684		torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
1685		return false;
1686	}
1687
1688	if (sids2.num_sids != 1) {
1689		torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
1690		return false;
1691	}
1692
1693	return true;
1694}
1695
1696static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
1697				       struct torture_context *tctx,
1698				       struct policy_handle *handle,
1699				       struct lsa_String *priv_name)
1700{
1701	struct lsa_LookupPrivDisplayName r;
1702	NTSTATUS status;
1703	/* produce a reasonable range of language output without screwing up
1704	   terminals */
1705	uint16_t language_id = (random() % 4) + 0x409;
1706	uint16_t returned_language_id = 0;
1707	struct lsa_StringLarge *disp_name = NULL;
1708
1709	torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
1710
1711	r.in.handle = handle;
1712	r.in.name = priv_name;
1713	r.in.language_id = language_id;
1714	r.in.language_id_sys = 0;
1715	r.out.returned_language_id = &returned_language_id;
1716	r.out.disp_name = &disp_name;
1717
1718	status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r);
1719	if (!NT_STATUS_IS_OK(status)) {
1720		torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status));
1721		return false;
1722	}
1723	torture_comment(tctx, "%s -> \"%s\"  (language 0x%x/0x%x)\n",
1724	       priv_name->string, disp_name->string,
1725	       r.in.language_id, *r.out.returned_language_id);
1726
1727	return true;
1728}
1729
1730static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
1731					   struct torture_context *tctx,
1732					   struct policy_handle *handle,
1733					   struct lsa_String *priv_name)
1734{
1735	struct lsa_EnumAccountsWithUserRight r;
1736	struct lsa_SidArray sids;
1737	NTSTATUS status;
1738
1739	ZERO_STRUCT(sids);
1740
1741	torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
1742
1743	r.in.handle = handle;
1744	r.in.name = priv_name;
1745	r.out.sids = &sids;
1746
1747	status = dcerpc_lsa_EnumAccountsWithUserRight(p, tctx, &r);
1748
1749	/* NT_STATUS_NO_MORE_ENTRIES means noone has this privilege */
1750	if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES)) {
1751		return true;
1752	}
1753
1754	if (!NT_STATUS_IS_OK(status)) {
1755		torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
1756		return false;
1757	}
1758
1759	return true;
1760}
1761
1762
1763static bool test_EnumPrivs(struct dcerpc_pipe *p,
1764			   struct torture_context *tctx,
1765			   struct policy_handle *handle)
1766{
1767	NTSTATUS status;
1768	struct lsa_EnumPrivs r;
1769	struct lsa_PrivArray privs1;
1770	uint32_t resume_handle = 0;
1771	int i;
1772	bool ret = true;
1773
1774	torture_comment(tctx, "\nTesting EnumPrivs\n");
1775
1776	r.in.handle = handle;
1777	r.in.resume_handle = &resume_handle;
1778	r.in.max_count = 100;
1779	r.out.resume_handle = &resume_handle;
1780	r.out.privs = &privs1;
1781
1782	resume_handle = 0;
1783	status = dcerpc_lsa_EnumPrivs(p, tctx, &r);
1784	if (!NT_STATUS_IS_OK(status)) {
1785		torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status));
1786		return false;
1787	}
1788
1789	for (i = 0; i< privs1.count; i++) {
1790		test_LookupPrivDisplayName(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1791		test_LookupPrivValue(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name);
1792		if (!test_EnumAccountsWithUserRight(p, tctx, handle, (struct lsa_String *)&privs1.privs[i].name)) {
1793			ret = false;
1794		}
1795	}
1796
1797	return ret;
1798}
1799
1800static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p,
1801					     struct torture_context *tctx,
1802					     struct policy_handle *handle,
1803					     const char *trusted_domain_name)
1804{
1805	bool ret = true;
1806	struct lsa_lsaRQueryForestTrustInformation r;
1807	NTSTATUS status;
1808	struct lsa_String string;
1809	struct lsa_ForestTrustInformation info, *info_ptr;
1810
1811	torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
1812
1813	if (torture_setting_bool(tctx, "samba4", false)) {
1814		torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
1815		return true;
1816	}
1817
1818	ZERO_STRUCT(string);
1819
1820	if (trusted_domain_name) {
1821		init_lsa_String(&string, trusted_domain_name);
1822	}
1823
1824	info_ptr = &info;
1825
1826	r.in.handle = handle;
1827	r.in.trusted_domain_name = &string;
1828	r.in.unknown = 0;
1829	r.out.forest_trust_info = &info_ptr;
1830
1831	status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r);
1832
1833	if (!NT_STATUS_IS_OK(status)) {
1834		torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
1835		ret = false;
1836	}
1837
1838	return ret;
1839}
1840
1841static bool test_query_each_TrustDomEx(struct dcerpc_pipe *p,
1842				       struct torture_context *tctx,
1843				       struct policy_handle *handle,
1844				       struct lsa_DomainListEx *domains)
1845{
1846	int i;
1847	bool ret = true;
1848
1849	for (i=0; i< domains->count; i++) {
1850
1851		if (domains->domains[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1852			ret &= test_QueryForestTrustInformation(p, tctx, handle,
1853								domains->domains[i].domain_name.string);
1854		}
1855	}
1856
1857	return ret;
1858}
1859
1860static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
1861				     struct torture_context *tctx,
1862				     struct policy_handle *handle,
1863				     struct lsa_DomainList *domains)
1864{
1865	NTSTATUS status;
1866	int i,j;
1867	bool ret = true;
1868
1869	torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
1870	for (i=0; i< domains->count; i++) {
1871		struct lsa_OpenTrustedDomain trust;
1872		struct lsa_OpenTrustedDomainByName trust_by_name;
1873		struct policy_handle trustdom_handle;
1874		struct policy_handle handle2;
1875		struct lsa_Close c;
1876		struct lsa_CloseTrustedDomainEx c_trust;
1877		int levels [] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
1878		int ok[]      = {1, 0, 1, 0, 0, 1, 0, 1, 0,  0,  0,  1, 1};
1879
1880		if (domains->domains[i].sid) {
1881			trust.in.handle = handle;
1882			trust.in.sid = domains->domains[i].sid;
1883			trust.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1884			trust.out.trustdom_handle = &trustdom_handle;
1885
1886			status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust);
1887
1888			if (!NT_STATUS_IS_OK(status)) {
1889				torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status));
1890				return false;
1891			}
1892
1893			c.in.handle = &trustdom_handle;
1894			c.out.handle = &handle2;
1895
1896			c_trust.in.handle = &trustdom_handle;
1897			c_trust.out.handle = &handle2;
1898
1899			for (j=0; j < ARRAY_SIZE(levels); j++) {
1900				struct lsa_QueryTrustedDomainInfo q;
1901				union lsa_TrustedDomainInfo *info = NULL;
1902				q.in.trustdom_handle = &trustdom_handle;
1903				q.in.level = levels[j];
1904				q.out.info = &info;
1905				status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
1906				if (!NT_STATUS_IS_OK(status) && ok[j]) {
1907					torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
1908					       levels[j], nt_errstr(status));
1909					ret = false;
1910				} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
1911					torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
1912					       levels[j], nt_errstr(status));
1913					ret = false;
1914				}
1915			}
1916
1917			status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust);
1918			if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
1919				torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
1920				return false;
1921			}
1922
1923			c.in.handle = &trustdom_handle;
1924			c.out.handle = &handle2;
1925
1926			status = dcerpc_lsa_Close(p, tctx, &c);
1927			if (!NT_STATUS_IS_OK(status)) {
1928				torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
1929				return false;
1930			}
1931
1932			for (j=0; j < ARRAY_SIZE(levels); j++) {
1933				struct lsa_QueryTrustedDomainInfoBySid q;
1934				union lsa_TrustedDomainInfo *info = NULL;
1935
1936				if (!domains->domains[i].sid) {
1937					continue;
1938				}
1939
1940				q.in.handle  = handle;
1941				q.in.dom_sid = domains->domains[i].sid;
1942				q.in.level   = levels[j];
1943				q.out.info   = &info;
1944
1945				status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
1946				if (!NT_STATUS_IS_OK(status) && ok[j]) {
1947					torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
1948					       levels[j], nt_errstr(status));
1949					ret = false;
1950				} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
1951					torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
1952					       levels[j], nt_errstr(status));
1953					ret = false;
1954				}
1955			}
1956		}
1957
1958		trust_by_name.in.handle = handle;
1959		trust_by_name.in.name.string = domains->domains[i].name.string;
1960		trust_by_name.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1961		trust_by_name.out.trustdom_handle = &trustdom_handle;
1962
1963		status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name);
1964
1965		if (!NT_STATUS_IS_OK(status)) {
1966			torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
1967			return false;
1968		}
1969
1970		for (j=0; j < ARRAY_SIZE(levels); j++) {
1971			struct lsa_QueryTrustedDomainInfo q;
1972			union lsa_TrustedDomainInfo *info = NULL;
1973			q.in.trustdom_handle = &trustdom_handle;
1974			q.in.level = levels[j];
1975			q.out.info = &info;
1976			status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
1977			if (!NT_STATUS_IS_OK(status) && ok[j]) {
1978				torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
1979				       levels[j], nt_errstr(status));
1980				ret = false;
1981			} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
1982				torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
1983				       levels[j], nt_errstr(status));
1984				ret = false;
1985			}
1986		}
1987
1988		c.in.handle = &trustdom_handle;
1989		c.out.handle = &handle2;
1990
1991		status = dcerpc_lsa_Close(p, tctx, &c);
1992		if (!NT_STATUS_IS_OK(status)) {
1993			torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
1994			return false;
1995		}
1996
1997		for (j=0; j < ARRAY_SIZE(levels); j++) {
1998			struct lsa_QueryTrustedDomainInfoByName q;
1999			union lsa_TrustedDomainInfo *info = NULL;
2000			struct lsa_String name;
2001
2002			name.string = domains->domains[i].name.string;
2003
2004			q.in.handle         = handle;
2005			q.in.trusted_domain = &name;
2006			q.in.level          = levels[j];
2007			q.out.info          = &info;
2008			status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q);
2009			if (!NT_STATUS_IS_OK(status) && ok[j]) {
2010				torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
2011				       levels[j], nt_errstr(status));
2012				ret = false;
2013			} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
2014				torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
2015				       levels[j], nt_errstr(status));
2016				ret = false;
2017			}
2018		}
2019	}
2020	return ret;
2021}
2022
2023static bool test_EnumTrustDom(struct dcerpc_pipe *p,
2024			      struct torture_context *tctx,
2025			      struct policy_handle *handle)
2026{
2027	struct lsa_EnumTrustDom r;
2028	NTSTATUS enum_status;
2029	uint32_t in_resume_handle = 0;
2030	uint32_t out_resume_handle;
2031	struct lsa_DomainList domains;
2032	bool ret = true;
2033
2034	torture_comment(tctx, "\nTesting EnumTrustDom\n");
2035
2036	r.in.handle = handle;
2037	r.in.resume_handle = &in_resume_handle;
2038	r.in.max_size = 0;
2039	r.out.domains = &domains;
2040	r.out.resume_handle = &out_resume_handle;
2041
2042	enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
2043
2044	/* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2045	 * always be larger than the previous input resume handle, in
2046	 * particular when hitting the last query it is vital to set the
2047	 * resume handle correctly to avoid infinite client loops, as
2048	 * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2049	 * status is NT_STATUS_OK - gd */
2050
2051	if (NT_STATUS_IS_OK(enum_status) ||
2052	    NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) ||
2053	    NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))
2054	{
2055		if (out_resume_handle <= in_resume_handle) {
2056			torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2057				out_resume_handle, in_resume_handle);
2058			return false;
2059		}
2060	}
2061
2062	if (NT_STATUS_IS_OK(enum_status)) {
2063		if (domains.count == 0) {
2064			torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2065			return false;
2066		}
2067	} else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
2068		torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
2069		return false;
2070	}
2071
2072	/* Start from the bottom again */
2073	in_resume_handle = 0;
2074
2075	do {
2076		r.in.handle = handle;
2077		r.in.resume_handle = &in_resume_handle;
2078		r.in.max_size = LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3;
2079		r.out.domains = &domains;
2080		r.out.resume_handle = &out_resume_handle;
2081
2082		enum_status = dcerpc_lsa_EnumTrustDom(p, tctx, &r);
2083
2084		/* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2085		 * always be larger than the previous input resume handle, in
2086		 * particular when hitting the last query it is vital to set the
2087		 * resume handle correctly to avoid infinite client loops, as
2088		 * seen e.g.  with Windows XP SP3 when resume handle is 0 and
2089		 * status is NT_STATUS_OK - gd */
2090
2091		if (NT_STATUS_IS_OK(enum_status) ||
2092		    NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES) ||
2093		    NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES))
2094		{
2095			if (out_resume_handle <= in_resume_handle) {
2096				torture_comment(tctx, "EnumTrustDom failed - should have returned output resume_handle (0x%08x) larger than input resume handle (0x%08x)\n",
2097					out_resume_handle, in_resume_handle);
2098				return false;
2099			}
2100		}
2101
2102		/* NO_MORE_ENTRIES is allowed */
2103		if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
2104			if (domains.count == 0) {
2105				return true;
2106			}
2107			torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2108			return false;
2109		} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
2110			/* Windows 2003 gets this off by one on the first run */
2111			if (r.out.domains->count < 3 || r.out.domains->count > 4) {
2112				torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2113				       "asked it to (got %d, expected %d / %d == %d entries)\n",
2114				       r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
2115				       LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
2116				ret = false;
2117			}
2118		} else if (!NT_STATUS_IS_OK(enum_status)) {
2119			torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status));
2120			return false;
2121		}
2122
2123		if (domains.count == 0) {
2124			torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2125			return false;
2126		}
2127
2128		ret &= test_query_each_TrustDom(p, tctx, handle, &domains);
2129
2130		in_resume_handle = out_resume_handle;
2131
2132	} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
2133
2134	return ret;
2135}
2136
2137static bool test_EnumTrustDomEx(struct dcerpc_pipe *p,
2138				struct torture_context *tctx,
2139				struct policy_handle *handle)
2140{
2141	struct lsa_EnumTrustedDomainsEx r_ex;
2142	NTSTATUS enum_status;
2143	uint32_t resume_handle = 0;
2144	struct lsa_DomainListEx domains_ex;
2145	bool ret = true;
2146
2147	torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
2148
2149	r_ex.in.handle = handle;
2150	r_ex.in.resume_handle = &resume_handle;
2151	r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2152	r_ex.out.domains = &domains_ex;
2153	r_ex.out.resume_handle = &resume_handle;
2154
2155	enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex);
2156
2157	if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
2158		torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
2159		return false;
2160	}
2161
2162	resume_handle = 0;
2163	do {
2164		r_ex.in.handle = handle;
2165		r_ex.in.resume_handle = &resume_handle;
2166		r_ex.in.max_size = LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER * 3;
2167		r_ex.out.domains = &domains_ex;
2168		r_ex.out.resume_handle = &resume_handle;
2169
2170		enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex);
2171
2172		/* NO_MORE_ENTRIES is allowed */
2173		if (NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES)) {
2174			if (domains_ex.count == 0) {
2175				return true;
2176			}
2177			torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
2178			return false;
2179		} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
2180			/* Windows 2003 gets this off by one on the first run */
2181			if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
2182				torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
2183				       "asked it to (got %d, expected %d / %d == %d entries)\n",
2184				       r_ex.out.domains->count,
2185				       r_ex.in.max_size,
2186				       LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER,
2187				       r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
2188			}
2189		} else if (!NT_STATUS_IS_OK(enum_status)) {
2190			torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
2191			return false;
2192		}
2193
2194		if (domains_ex.count == 0) {
2195			torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
2196			return false;
2197		}
2198
2199		ret &= test_query_each_TrustDomEx(p, tctx, handle, &domains_ex);
2200
2201	} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
2202
2203	return ret;
2204}
2205
2206
2207static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
2208				     struct torture_context *tctx,
2209				     struct policy_handle *handle,
2210				     uint32_t num_trusts)
2211{
2212	NTSTATUS status;
2213	bool ret = true;
2214	struct lsa_CreateTrustedDomain r;
2215	struct lsa_DomainInfo trustinfo;
2216	struct dom_sid **domsid;
2217	struct policy_handle *trustdom_handle;
2218	struct lsa_QueryTrustedDomainInfo q;
2219	union lsa_TrustedDomainInfo *info = NULL;
2220	int i;
2221
2222	torture_comment(tctx, "\nTesting CreateTrustedDomain for %d domains\n", num_trusts);
2223
2224	if (!test_EnumTrustDom(p, tctx, handle)) {
2225		ret = false;
2226	}
2227
2228	if (!test_EnumTrustDomEx(p, tctx, handle)) {
2229		ret = false;
2230	}
2231
2232	domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2233	trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2234
2235	for (i=0; i< num_trusts; i++) {
2236		char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2237		char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2238
2239		domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2240
2241		trustinfo.sid = domsid[i];
2242		init_lsa_String((struct lsa_String *)&trustinfo.name, trust_name);
2243
2244		r.in.policy_handle = handle;
2245		r.in.info = &trustinfo;
2246		r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2247		r.out.trustdom_handle = &trustdom_handle[i];
2248
2249		status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r);
2250		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
2251			test_DeleteTrustedDomain(p, tctx, handle, trustinfo.name);
2252			status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r);
2253		}
2254		if (!NT_STATUS_IS_OK(status)) {
2255			torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status));
2256			ret = false;
2257		} else {
2258
2259			q.in.trustdom_handle = &trustdom_handle[i];
2260			q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2261			q.out.info = &info;
2262			status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
2263			if (!NT_STATUS_IS_OK(status)) {
2264				torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n", q.in.level, nt_errstr(status));
2265				ret = false;
2266			} else if (!q.out.info) {
2267				ret = false;
2268			} else {
2269				if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
2270					torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
2271					       info->info_ex.netbios_name.string, trustinfo.name.string);
2272					ret = false;
2273				}
2274				if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2275					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2276					       trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
2277					ret = false;
2278				}
2279				if (info->info_ex.trust_attributes != 0) {
2280					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2281					       trust_name, info->info_ex.trust_attributes, 0);
2282					ret = false;
2283				}
2284				if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
2285					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2286					       trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
2287					ret = false;
2288				}
2289			}
2290		}
2291	}
2292
2293	/* now that we have some domains to look over, we can test the enum calls */
2294	if (!test_EnumTrustDom(p, tctx, handle)) {
2295		ret = false;
2296	}
2297
2298	if (!test_EnumTrustDomEx(p, tctx, handle)) {
2299		ret = false;
2300	}
2301
2302	for (i=0; i<num_trusts; i++) {
2303		if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) {
2304			ret = false;
2305		}
2306	}
2307
2308	return ret;
2309}
2310
2311static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
2312					struct torture_context *tctx,
2313					struct policy_handle *handle,
2314					uint32_t num_trusts)
2315{
2316	NTSTATUS status;
2317	bool ret = true;
2318	struct lsa_CreateTrustedDomainEx2 r;
2319	struct lsa_TrustDomainInfoInfoEx trustinfo;
2320	struct lsa_TrustDomainInfoAuthInfoInternal authinfo;
2321	struct trustDomainPasswords auth_struct;
2322	DATA_BLOB auth_blob;
2323	struct dom_sid **domsid;
2324	struct policy_handle *trustdom_handle;
2325	struct lsa_QueryTrustedDomainInfo q;
2326	union lsa_TrustedDomainInfo *info = NULL;
2327	DATA_BLOB session_key;
2328	enum ndr_err_code ndr_err;
2329	int i;
2330
2331	torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for %d domains\n", num_trusts);
2332
2333	domsid = talloc_array(tctx, struct dom_sid *, num_trusts);
2334	trustdom_handle = talloc_array(tctx, struct policy_handle, num_trusts);
2335
2336	status = dcerpc_fetch_session_key(p, &session_key);
2337	if (!NT_STATUS_IS_OK(status)) {
2338		torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
2339		return false;
2340	}
2341
2342	for (i=0; i< num_trusts; i++) {
2343		char *trust_name = talloc_asprintf(tctx, "torturedom%02d", i);
2344		char *trust_name_dns = talloc_asprintf(tctx, "torturedom%02d.samba.example.com", i);
2345		char *trust_sid = talloc_asprintf(tctx, "S-1-5-21-97398-379795-100%02d", i);
2346
2347		domsid[i] = dom_sid_parse_talloc(tctx, trust_sid);
2348
2349		trustinfo.sid = domsid[i];
2350		trustinfo.netbios_name.string = trust_name;
2351		trustinfo.domain_name.string = trust_name_dns;
2352
2353		/* Create inbound, some outbound, and some
2354		 * bi-directional trusts in a repeating pattern based
2355		 * on i */
2356
2357		/* 1 == inbound, 2 == outbound, 3 == both */
2358		trustinfo.trust_direction = (i % 3) + 1;
2359
2360		/* Try different trust types too */
2361
2362		/* 1 == downlevel (NT4), 2 == uplevel (ADS), 3 == MIT (kerberos but not AD) */
2363		trustinfo.trust_type = (((i / 3) + 1) % 3) + 1;
2364
2365		trustinfo.trust_attributes = LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION;
2366
2367		generate_random_buffer(auth_struct.confounder, sizeof(auth_struct.confounder));
2368
2369		auth_struct.outgoing.count = 0;
2370		auth_struct.incoming.count = 0;
2371
2372		ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct,
2373					       (ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
2374		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2375			torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed");
2376			ret = false;
2377		}
2378
2379		arcfour_crypt_blob(auth_blob.data, auth_blob.length, &session_key);
2380
2381		authinfo.auth_blob.size = auth_blob.length;
2382		authinfo.auth_blob.data = auth_blob.data;
2383
2384		r.in.policy_handle = handle;
2385		r.in.info = &trustinfo;
2386		r.in.auth_info = &authinfo;
2387		r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2388		r.out.trustdom_handle = &trustdom_handle[i];
2389
2390		status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r);
2391		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
2392			test_DeleteTrustedDomain(p, tctx, handle, trustinfo.netbios_name);
2393			status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r);
2394		}
2395		if (!NT_STATUS_IS_OK(status)) {
2396			torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
2397			ret = false;
2398		} else {
2399
2400			q.in.trustdom_handle = &trustdom_handle[i];
2401			q.in.level = LSA_TRUSTED_DOMAIN_INFO_INFO_EX;
2402			q.out.info = &info;
2403			status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
2404			if (!NT_STATUS_IS_OK(status)) {
2405				torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
2406				ret = false;
2407			} else if (!q.out.info) {
2408				torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
2409				ret = false;
2410			} else {
2411				if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
2412					torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
2413					       info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
2414					ret = false;
2415				}
2416				if (info->info_ex.trust_type != trustinfo.trust_type) {
2417					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
2418					       trust_name, info->info_ex.trust_type, trustinfo.trust_type);
2419					ret = false;
2420				}
2421				if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
2422					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
2423					       trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
2424					ret = false;
2425				}
2426				if (info->info_ex.trust_direction != trustinfo.trust_direction) {
2427					torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
2428					       trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
2429					ret = false;
2430				}
2431			}
2432		}
2433	}
2434
2435	/* now that we have some domains to look over, we can test the enum calls */
2436	if (!test_EnumTrustDom(p, tctx, handle)) {
2437		torture_comment(tctx, "test_EnumTrustDom failed\n");
2438		ret = false;
2439	}
2440
2441	if (!test_EnumTrustDomEx(p, tctx, handle)) {
2442		torture_comment(tctx, "test_EnumTrustDomEx failed\n");
2443		ret = false;
2444	}
2445
2446	for (i=0; i<num_trusts; i++) {
2447		if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) {
2448			torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
2449			ret = false;
2450		}
2451	}
2452
2453	return ret;
2454}
2455
2456static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
2457				 struct torture_context *tctx,
2458				 struct policy_handle *handle)
2459{
2460	struct lsa_QueryDomainInformationPolicy r;
2461	union lsa_DomainInformationPolicy *info = NULL;
2462	NTSTATUS status;
2463	int i;
2464	bool ret = true;
2465
2466	if (torture_setting_bool(tctx, "samba3", false)) {
2467		torture_skip(tctx, "skipping QueryDomainInformationPolicy test\n");
2468	}
2469
2470	torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
2471
2472	for (i=2;i<4;i++) {
2473		r.in.handle = handle;
2474		r.in.level = i;
2475		r.out.info = &info;
2476
2477		torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
2478
2479		status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r);
2480
2481		/* If the server does not support EFS, then this is the correct return */
2482		if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2483			continue;
2484		} else if (!NT_STATUS_IS_OK(status)) {
2485			torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
2486			ret = false;
2487			continue;
2488		}
2489	}
2490
2491	return ret;
2492}
2493
2494
2495static bool test_QueryInfoPolicyCalls(	bool version2,
2496					struct dcerpc_pipe *p,
2497					struct torture_context *tctx,
2498					struct policy_handle *handle)
2499{
2500	struct lsa_QueryInfoPolicy r;
2501	union lsa_PolicyInformation *info = NULL;
2502	NTSTATUS status;
2503	int i;
2504	bool ret = true;
2505	const char *call = talloc_asprintf(tctx, "QueryInfoPolicy%s", version2 ? "2":"");
2506
2507	torture_comment(tctx, "\nTesting %s\n", call);
2508
2509	if (version2 && torture_setting_bool(tctx, "samba3", false)) {
2510		torture_skip(tctx, "skipping QueryInfoPolicy2 tests\n");
2511	}
2512
2513	for (i=1;i<=14;i++) {
2514		r.in.handle = handle;
2515		r.in.level = i;
2516		r.out.info = &info;
2517
2518		torture_comment(tctx, "\nTrying %s level %d\n", call, i);
2519
2520		if (version2)
2521			/* We can perform the cast, because both types are
2522			   structurally equal */
2523			status = dcerpc_lsa_QueryInfoPolicy2(p, tctx,
2524				 (struct lsa_QueryInfoPolicy2*) &r);
2525		else
2526			status = dcerpc_lsa_QueryInfoPolicy(p, tctx, &r);
2527
2528		switch (i) {
2529		case LSA_POLICY_INFO_MOD:
2530		case LSA_POLICY_INFO_AUDIT_FULL_SET:
2531		case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
2532			if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
2533				torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status));
2534				ret = false;
2535			}
2536			break;
2537		case LSA_POLICY_INFO_DOMAIN:
2538		case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
2539		case LSA_POLICY_INFO_REPLICA:
2540		case LSA_POLICY_INFO_QUOTA:
2541		case LSA_POLICY_INFO_ROLE:
2542		case LSA_POLICY_INFO_AUDIT_LOG:
2543		case LSA_POLICY_INFO_AUDIT_EVENTS:
2544		case LSA_POLICY_INFO_PD:
2545			if (!NT_STATUS_IS_OK(status)) {
2546				torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status));
2547				ret = false;
2548			}
2549			break;
2550		case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
2551		case LSA_POLICY_INFO_DNS_INT:
2552		case LSA_POLICY_INFO_DNS:
2553			if (torture_setting_bool(tctx, "samba3", false)) {
2554				/* Other levels not implemented yet */
2555				if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2556					torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status));
2557					ret = false;
2558				}
2559			} else if (!NT_STATUS_IS_OK(status)) {
2560				torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status));
2561				ret = false;
2562			}
2563			break;
2564		default:
2565			if (torture_setting_bool(tctx, "samba4", false)) {
2566				/* Other levels not implemented yet */
2567				if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
2568					torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status));
2569					ret = false;
2570				}
2571			} else if (!NT_STATUS_IS_OK(status)) {
2572				torture_comment(tctx, "%s failed - %s\n", call, nt_errstr(status));
2573				ret = false;
2574			}
2575			break;
2576		}
2577
2578		if (NT_STATUS_IS_OK(status) && (i == LSA_POLICY_INFO_DNS
2579			|| i == LSA_POLICY_INFO_DNS_INT)) {
2580			/* Let's look up some of these names */
2581
2582			struct lsa_TransNameArray tnames;
2583			tnames.count = 14;
2584			tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count);
2585			tnames.names[0].name.string = info->dns.name.string;
2586			tnames.names[0].sid_type = SID_NAME_DOMAIN;
2587			tnames.names[1].name.string = info->dns.dns_domain.string;
2588			tnames.names[1].sid_type = SID_NAME_DOMAIN;
2589			tnames.names[2].name.string = talloc_asprintf(tctx, "%s\\", info->dns.name.string);
2590			tnames.names[2].sid_type = SID_NAME_DOMAIN;
2591			tnames.names[3].name.string = talloc_asprintf(tctx, "%s\\", info->dns.dns_domain.string);
2592			tnames.names[3].sid_type = SID_NAME_DOMAIN;
2593			tnames.names[4].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.name.string);
2594			tnames.names[4].sid_type = SID_NAME_USER;
2595			tnames.names[5].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.name.string);
2596			tnames.names[5].sid_type = SID_NAME_USER;
2597			tnames.names[6].name.string = talloc_asprintf(tctx, "%s\\guest", info->dns.dns_domain.string);
2598			tnames.names[6].sid_type = SID_NAME_USER;
2599			tnames.names[7].name.string = talloc_asprintf(tctx, "%s\\krbtgt", info->dns.dns_domain.string);
2600			tnames.names[7].sid_type = SID_NAME_USER;
2601			tnames.names[8].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.name.string);
2602			tnames.names[8].sid_type = SID_NAME_USER;
2603			tnames.names[9].name.string = talloc_asprintf(tctx, "krbtgt@%s", info->dns.dns_domain.string);
2604			tnames.names[9].sid_type = SID_NAME_USER;
2605			tnames.names[10].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string);
2606			tnames.names[10].sid_type = SID_NAME_USER;
2607			tnames.names[11].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.dns_domain.string);
2608			tnames.names[11].sid_type = SID_NAME_USER;
2609			tnames.names[12].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.name.string);
2610			tnames.names[12].sid_type = SID_NAME_USER;
2611			tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string);
2612			tnames.names[13].sid_type = SID_NAME_USER;
2613			ret &= test_LookupNames(p, tctx, handle, &tnames);
2614
2615		}
2616	}
2617
2618	return ret;
2619}
2620
2621static bool test_QueryInfoPolicy(struct dcerpc_pipe *p,
2622				 struct torture_context *tctx,
2623				 struct policy_handle *handle)
2624{
2625	return test_QueryInfoPolicyCalls(false, p, tctx, handle);
2626}
2627
2628static bool test_QueryInfoPolicy2(struct dcerpc_pipe *p,
2629				  struct torture_context *tctx,
2630				  struct policy_handle *handle)
2631{
2632	return test_QueryInfoPolicyCalls(true, p, tctx, handle);
2633}
2634
2635static bool test_GetUserName(struct dcerpc_pipe *p,
2636			     struct torture_context *tctx)
2637{
2638	struct lsa_GetUserName r;
2639	NTSTATUS status;
2640	bool ret = true;
2641	struct lsa_String *authority_name_p = NULL;
2642	struct lsa_String *account_name_p = NULL;
2643
2644	torture_comment(tctx, "\nTesting GetUserName\n");
2645
2646	r.in.system_name	= "\\";
2647	r.in.account_name	= &account_name_p;
2648	r.in.authority_name	= NULL;
2649	r.out.account_name	= &account_name_p;
2650
2651	status = dcerpc_lsa_GetUserName(p, tctx, &r);
2652
2653	if (!NT_STATUS_IS_OK(status)) {
2654		torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
2655		ret = false;
2656	}
2657
2658	account_name_p = NULL;
2659	r.in.account_name	= &account_name_p;
2660	r.in.authority_name	= &authority_name_p;
2661	r.out.account_name	= &account_name_p;
2662
2663	status = dcerpc_lsa_GetUserName(p, tctx, &r);
2664
2665	if (!NT_STATUS_IS_OK(status)) {
2666		torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
2667		ret = false;
2668	}
2669
2670	return ret;
2671}
2672
2673bool test_lsa_Close(struct dcerpc_pipe *p,
2674		    struct torture_context *tctx,
2675		    struct policy_handle *handle)
2676{
2677	NTSTATUS status;
2678	struct lsa_Close r;
2679	struct policy_handle handle2;
2680
2681	torture_comment(tctx, "\nTesting Close\n");
2682
2683	r.in.handle = handle;
2684	r.out.handle = &handle2;
2685
2686	status = dcerpc_lsa_Close(p, tctx, &r);
2687	if (!NT_STATUS_IS_OK(status)) {
2688		torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
2689		return false;
2690	}
2691
2692	status = dcerpc_lsa_Close(p, tctx, &r);
2693	/* its really a fault - we need a status code for rpc fault */
2694	if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
2695		torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
2696		return false;
2697	}
2698
2699	torture_comment(tctx, "\n");
2700
2701	return true;
2702}
2703
2704bool torture_rpc_lsa(struct torture_context *tctx)
2705{
2706        NTSTATUS status;
2707        struct dcerpc_pipe *p;
2708	bool ret = true;
2709	struct policy_handle *handle;
2710	struct test_join *join = NULL;
2711	struct cli_credentials *machine_creds;
2712
2713	status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
2714	if (!NT_STATUS_IS_OK(status)) {
2715		return false;
2716	}
2717
2718	if (!test_OpenPolicy(p, tctx)) {
2719		ret = false;
2720	}
2721
2722	if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
2723		ret = false;
2724	}
2725
2726	if (handle) {
2727		join = torture_join_domain(tctx, TEST_MACHINENAME, ACB_WSTRUST, &machine_creds);
2728		if (!join) {
2729			ret = false;
2730		}
2731
2732		if (!test_LookupSids_async(p, tctx, handle)) {
2733			ret = false;
2734		}
2735
2736		if (!test_QueryDomainInfoPolicy(p, tctx, handle)) {
2737			ret = false;
2738		}
2739
2740		if (!test_CreateSecret(p, tctx, handle)) {
2741			ret = false;
2742		}
2743
2744		if (!test_QueryInfoPolicy(p, tctx, handle)) {
2745			ret = false;
2746		}
2747
2748		if (!test_QueryInfoPolicy2(p, tctx, handle)) {
2749			ret = false;
2750		}
2751
2752		if (!test_Delete(p, tctx, handle)) {
2753			ret = false;
2754		}
2755
2756		if (!test_many_LookupSids(p, tctx, handle)) {
2757			ret = false;
2758		}
2759
2760		if (!test_lsa_Close(p, tctx, handle)) {
2761			ret = false;
2762		}
2763
2764		torture_leave_domain(tctx, join);
2765
2766	} else {
2767		if (!test_many_LookupSids(p, tctx, handle)) {
2768			ret = false;
2769		}
2770	}
2771
2772	if (!test_GetUserName(p, tctx)) {
2773		ret = false;
2774	}
2775
2776	return ret;
2777}
2778
2779bool torture_rpc_lsa_get_user(struct torture_context *tctx)
2780{
2781        NTSTATUS status;
2782        struct dcerpc_pipe *p;
2783	bool ret = true;
2784
2785	status = torture_rpc_connection(tctx, &p, &ndr_table_lsarpc);
2786	if (!NT_STATUS_IS_OK(status)) {
2787		return false;
2788	}
2789
2790	if (!test_GetUserName(p, tctx)) {
2791		ret = false;
2792	}
2793
2794	return ret;
2795}
2796
2797static bool testcase_LookupNames(struct torture_context *tctx,
2798				 struct dcerpc_pipe *p)
2799{
2800	bool ret = true;
2801	struct policy_handle *handle;
2802	struct lsa_TransNameArray tnames;
2803	struct lsa_TransNameArray2 tnames2;
2804
2805	if (!test_OpenPolicy(p, tctx)) {
2806		ret = false;
2807	}
2808
2809	if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
2810		ret = false;
2811	}
2812
2813	if (!handle) {
2814		ret = false;
2815	}
2816
2817	tnames.count = 1;
2818	tnames.names = talloc_array(tctx, struct lsa_TranslatedName, tnames.count);
2819	ZERO_STRUCT(tnames.names[0]);
2820	tnames.names[0].name.string = "BUILTIN";
2821	tnames.names[0].sid_type = SID_NAME_DOMAIN;
2822
2823	if (!test_LookupNames(p, tctx, handle, &tnames)) {
2824		ret = false;
2825	}
2826
2827	tnames2.count = 1;
2828	tnames2.names = talloc_array(tctx, struct lsa_TranslatedName2, tnames2.count);
2829	ZERO_STRUCT(tnames2.names[0]);
2830	tnames2.names[0].name.string = "BUILTIN";
2831	tnames2.names[0].sid_type = SID_NAME_DOMAIN;
2832
2833	if (!test_LookupNames2(p, tctx, handle, &tnames2, true)) {
2834		ret = false;
2835	}
2836
2837	if (!test_LookupNames3(p, tctx, handle, &tnames2, true)) {
2838		ret = false;
2839	}
2840
2841	if (!test_LookupNames_wellknown(p, tctx, handle)) {
2842		ret = false;
2843	}
2844
2845	if (!test_LookupNames_NULL(p, tctx, handle)) {
2846		ret = false;
2847	}
2848
2849	if (!test_LookupNames_bogus(p, tctx, handle)) {
2850		ret = false;
2851	}
2852
2853	if (!test_lsa_Close(p, tctx, handle)) {
2854		ret = false;
2855	}
2856
2857	return ret;
2858}
2859
2860struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
2861{
2862	struct torture_suite *suite;
2863	struct torture_rpc_tcase *tcase;
2864
2865	suite = torture_suite_create(mem_ctx, "LSA-LOOKUPNAMES");
2866
2867	tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
2868						  &ndr_table_lsarpc);
2869	torture_rpc_tcase_add_test(tcase, "LookupNames",
2870				   testcase_LookupNames);
2871
2872	return suite;
2873}
2874
2875struct lsa_trustdom_state {
2876	uint32_t num_trusts;
2877};
2878
2879static bool testcase_TrustedDomains(struct torture_context *tctx,
2880				    struct dcerpc_pipe *p,
2881				    void *data)
2882{
2883	bool ret = true;
2884	struct policy_handle *handle;
2885	struct lsa_trustdom_state *state =
2886		talloc_get_type_abort(data, struct lsa_trustdom_state);
2887
2888	torture_comment(tctx, "testing %d domains\n", state->num_trusts);
2889
2890	if (!test_OpenPolicy(p, tctx)) {
2891		ret = false;
2892	}
2893
2894	if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
2895		ret = false;
2896	}
2897
2898	if (!handle) {
2899		ret = false;
2900	}
2901
2902	if (!test_CreateTrustedDomain(p, tctx, handle, state->num_trusts)) {
2903		ret = false;
2904	}
2905
2906	if (!test_CreateTrustedDomainEx2(p, tctx, handle, state->num_trusts)) {
2907		ret = false;
2908	}
2909
2910	if (!test_lsa_Close(p, tctx, handle)) {
2911		ret = false;
2912	}
2913
2914	return ret;
2915}
2916
2917struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
2918{
2919	struct torture_suite *suite;
2920	struct torture_rpc_tcase *tcase;
2921	struct lsa_trustdom_state *state;
2922
2923	state = talloc(mem_ctx, struct lsa_trustdom_state);
2924
2925	state->num_trusts = 12;
2926
2927	suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS");
2928
2929	tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
2930						  &ndr_table_lsarpc);
2931	torture_rpc_tcase_add_test_ex(tcase, "TrustedDomains",
2932				      testcase_TrustedDomains,
2933				      state);
2934
2935	return suite;
2936}
2937
2938static bool testcase_Privileges(struct torture_context *tctx,
2939				struct dcerpc_pipe *p)
2940{
2941	bool ret = true;
2942	struct policy_handle *handle;
2943
2944	if (!test_OpenPolicy(p, tctx)) {
2945		ret = false;
2946	}
2947
2948	if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
2949		ret = false;
2950	}
2951
2952	if (!handle) {
2953		ret = false;
2954	}
2955
2956	if (!test_CreateAccount(p, tctx, handle)) {
2957		ret = false;
2958	}
2959
2960	if (!test_EnumAccounts(p, tctx, handle)) {
2961		ret = false;
2962	}
2963
2964	if (!test_EnumPrivs(p, tctx, handle)) {
2965		ret = false;
2966	}
2967
2968	if (!test_lsa_Close(p, tctx, handle)) {
2969		ret = false;
2970	}
2971
2972	return ret;
2973}
2974
2975
2976struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
2977{
2978	struct torture_suite *suite;
2979	struct torture_rpc_tcase *tcase;
2980
2981	suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES");
2982
2983	tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
2984						  &ndr_table_lsarpc);
2985	torture_rpc_tcase_add_test(tcase, "Privileges",
2986				   testcase_Privileges);
2987
2988	return suite;
2989}
2990