• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/torture/rpc/
1/*
2   Unix SMB/CIFS implementation.
3
4   test suite for netlogon rpc operations
5
6   Copyright (C) Andrew Tridgell 2003
7   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8   Copyright (C) Tim Potter      2003
9   Copyright (C) Matthias Dieter Walln��fer            2009
10
11   This program is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 3 of the License, or
14   (at your option) any later version.
15
16   This program is distributed in the hope that it will be useful,
17   but WITHOUT ANY WARRANTY; without even the implied warranty of
18   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   GNU General Public License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program.  If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26#include "version.h"
27#include "torture/torture.h"
28#include "lib/events/events.h"
29#include "auth/auth.h"
30#include "auth/gensec/gensec.h"
31#include "lib/cmdline/popt_common.h"
32#include "torture/rpc/rpc.h"
33#include "torture/rpc/netlogon.h"
34#include "../lib/crypto/crypto.h"
35#include "libcli/auth/libcli_auth.h"
36#include "librpc/gen_ndr/ndr_netlogon_c.h"
37#include "librpc/gen_ndr/ndr_netlogon.h"
38#include "librpc/gen_ndr/ndr_lsa_c.h"
39#include "param/param.h"
40#include "libcli/security/security.h"
41#include "lib/ldb/include/ldb.h"
42#include "lib/util/util_ldb.h"
43#include "lib/ldb_wrap.h"
44
45#define TEST_MACHINE_NAME "torturetest"
46#define TEST_MACHINE_DNS_SUFFIX "torturedomain"
47
48static bool test_LogonUasLogon(struct torture_context *tctx,
49			       struct dcerpc_pipe *p)
50{
51	NTSTATUS status;
52	struct netr_LogonUasLogon r;
53	struct netr_UasInfo *info = NULL;
54
55	r.in.server_name = NULL;
56	r.in.account_name = cli_credentials_get_username(cmdline_credentials);
57	r.in.workstation = TEST_MACHINE_NAME;
58	r.out.info = &info;
59
60	status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
61	torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
62
63	return true;
64}
65
66static bool test_LogonUasLogoff(struct torture_context *tctx,
67				struct dcerpc_pipe *p)
68{
69	NTSTATUS status;
70	struct netr_LogonUasLogoff r;
71	struct netr_UasLogoffInfo info;
72
73	r.in.server_name = NULL;
74	r.in.account_name = cli_credentials_get_username(cmdline_credentials);
75	r.in.workstation = TEST_MACHINE_NAME;
76	r.out.info = &info;
77
78	status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
79	torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
80
81	return true;
82}
83
84bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
85				  struct cli_credentials *credentials,
86				  struct netlogon_creds_CredentialState **creds_out)
87{
88	NTSTATUS status;
89	struct netr_ServerReqChallenge r;
90	struct netr_ServerAuthenticate a;
91	struct netr_Credential credentials1, credentials2, credentials3;
92	struct netlogon_creds_CredentialState *creds;
93	const struct samr_Password *mach_password;
94   	const char *machine_name;
95
96	mach_password = cli_credentials_get_nt_hash(credentials, tctx);
97	machine_name = cli_credentials_get_workstation(credentials);
98
99	torture_comment(tctx, "Testing ServerReqChallenge\n");
100
101	r.in.server_name = NULL;
102	r.in.computer_name = machine_name;
103	r.in.credentials = &credentials1;
104	r.out.return_credentials = &credentials2;
105
106	generate_random_buffer(credentials1.data, sizeof(credentials1.data));
107
108	status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
109	torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
110
111	a.in.server_name = NULL;
112	a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
113	a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
114	a.in.computer_name = machine_name;
115	a.in.credentials = &credentials3;
116	a.out.return_credentials = &credentials3;
117
118	creds = netlogon_creds_client_init(tctx, a.in.account_name,
119					   a.in.computer_name,
120					   &credentials1, &credentials2,
121					   mach_password, &credentials3,
122					   0);
123	torture_assert(tctx, creds != NULL, "memory allocation");
124
125
126	torture_comment(tctx, "Testing ServerAuthenticate\n");
127
128	status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
129
130	/* This allows the tests to continue against the more fussy windows 2008 */
131	if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
132		return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
133					      credentials,
134					      cli_credentials_get_secure_channel_type(credentials),
135					      creds_out);
136	}
137
138	torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
139
140	torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
141		       "Credential chaining failed");
142
143	*creds_out = creds;
144	return true;
145}
146
147bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
148			    uint32_t negotiate_flags,
149			    struct cli_credentials *machine_credentials,
150			    int sec_chan_type,
151			    struct netlogon_creds_CredentialState **creds_out)
152{
153	NTSTATUS status;
154	struct netr_ServerReqChallenge r;
155	struct netr_ServerAuthenticate2 a;
156	struct netr_Credential credentials1, credentials2, credentials3;
157	struct netlogon_creds_CredentialState *creds;
158	const struct samr_Password *mach_password;
159	const char *machine_name;
160
161	mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
162	machine_name = cli_credentials_get_workstation(machine_credentials);
163
164	torture_comment(tctx, "Testing ServerReqChallenge\n");
165
166
167	r.in.server_name = NULL;
168	r.in.computer_name = machine_name;
169	r.in.credentials = &credentials1;
170	r.out.return_credentials = &credentials2;
171
172	generate_random_buffer(credentials1.data, sizeof(credentials1.data));
173
174	status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
175	torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
176
177	a.in.server_name = NULL;
178	a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
179	a.in.secure_channel_type = sec_chan_type;
180	a.in.computer_name = machine_name;
181	a.in.negotiate_flags = &negotiate_flags;
182	a.out.negotiate_flags = &negotiate_flags;
183	a.in.credentials = &credentials3;
184	a.out.return_credentials = &credentials3;
185
186	creds = netlogon_creds_client_init(tctx, a.in.account_name,
187					   a.in.computer_name,
188					   &credentials1, &credentials2,
189					   mach_password, &credentials3,
190					   negotiate_flags);
191
192	torture_assert(tctx, creds != NULL, "memory allocation");
193
194	torture_comment(tctx, "Testing ServerAuthenticate2\n");
195
196	status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
197	torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
198
199	torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3),
200		"Credential chaining failed");
201
202	torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
203
204	*creds_out = creds;
205	return true;
206}
207
208
209static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
210			    uint32_t negotiate_flags,
211			    struct cli_credentials *machine_credentials,
212			    struct netlogon_creds_CredentialState **creds_out)
213{
214	NTSTATUS status;
215	struct netr_ServerReqChallenge r;
216	struct netr_ServerAuthenticate3 a;
217	struct netr_Credential credentials1, credentials2, credentials3;
218	struct netlogon_creds_CredentialState *creds;
219	struct samr_Password mach_password;
220	uint32_t rid;
221	const char *machine_name;
222	const char *plain_pass;
223
224	machine_name = cli_credentials_get_workstation(machine_credentials);
225	plain_pass = cli_credentials_get_password(machine_credentials);
226
227	torture_comment(tctx, "Testing ServerReqChallenge\n");
228
229	r.in.server_name = NULL;
230	r.in.computer_name = machine_name;
231	r.in.credentials = &credentials1;
232	r.out.return_credentials = &credentials2;
233
234	generate_random_buffer(credentials1.data, sizeof(credentials1.data));
235
236	status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
237	torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
238
239	E_md4hash(plain_pass, mach_password.hash);
240
241	a.in.server_name = NULL;
242	a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
243	a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
244	a.in.computer_name = machine_name;
245	a.in.negotiate_flags = &negotiate_flags;
246	a.in.credentials = &credentials3;
247	a.out.return_credentials = &credentials3;
248	a.out.negotiate_flags = &negotiate_flags;
249	a.out.rid = &rid;
250
251	creds = netlogon_creds_client_init(tctx, a.in.account_name,
252					   a.in.computer_name,
253					   &credentials1, &credentials2,
254					   &mach_password, &credentials3,
255					   negotiate_flags);
256
257	torture_assert(tctx, creds != NULL, "memory allocation");
258
259	torture_comment(tctx, "Testing ServerAuthenticate3\n");
260
261	status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
262	torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
263	torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
264
265	torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
266
267	/* Prove that requesting a challenge again won't break it */
268	status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
269	torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
270
271	*creds_out = creds;
272	return true;
273}
274
275/*
276  try a change password for our machine account
277*/
278static bool test_SetPassword(struct torture_context *tctx,
279			     struct dcerpc_pipe *p,
280			     struct cli_credentials *machine_credentials)
281{
282	NTSTATUS status;
283	struct netr_ServerPasswordSet r;
284	const char *password;
285	struct netlogon_creds_CredentialState *creds;
286	struct netr_Authenticator credential, return_authenticator;
287	struct samr_Password new_password;
288
289	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
290		return false;
291	}
292
293	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
294	r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
295	r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
296	r.in.computer_name = TEST_MACHINE_NAME;
297	r.in.credential = &credential;
298	r.in.new_password = &new_password;
299	r.out.return_authenticator = &return_authenticator;
300
301	password = generate_random_str(tctx, 8);
302	E_md4hash(password, new_password.hash);
303
304	netlogon_creds_des_encrypt(creds, &new_password);
305
306	torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
307	torture_comment(tctx, "Changing machine account password to '%s'\n",
308			password);
309
310	netlogon_creds_client_authenticator(creds, &credential);
311
312	status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
313	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
314
315	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
316		torture_comment(tctx, "Credential chaining failed\n");
317	}
318
319	/* by changing the machine password twice we test the
320	   credentials chaining fully, and we verify that the server
321	   allows the password to be set to the same value twice in a
322	   row (match win2k3) */
323	torture_comment(tctx,
324		"Testing a second ServerPasswordSet on machine account\n");
325	torture_comment(tctx,
326		"Changing machine account password to '%s' (same as previous run)\n", password);
327
328	netlogon_creds_client_authenticator(creds, &credential);
329
330	status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
331	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
332
333	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
334		torture_comment(tctx, "Credential chaining failed\n");
335	}
336
337	cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
338
339	torture_assert(tctx,
340		test_SetupCredentials(p, tctx, machine_credentials, &creds),
341		"ServerPasswordSet failed to actually change the password");
342
343	return true;
344}
345
346/*
347  try a change password for our machine account
348*/
349static bool test_SetPassword_flags(struct torture_context *tctx,
350				   struct dcerpc_pipe *p,
351				   struct cli_credentials *machine_credentials,
352				   uint32_t negotiate_flags)
353{
354	NTSTATUS status;
355	struct netr_ServerPasswordSet r;
356	const char *password;
357	struct netlogon_creds_CredentialState *creds;
358	struct netr_Authenticator credential, return_authenticator;
359	struct samr_Password new_password;
360
361	if (!test_SetupCredentials2(p, tctx, negotiate_flags,
362				    machine_credentials,
363				    cli_credentials_get_secure_channel_type(machine_credentials),
364				    &creds)) {
365		return false;
366	}
367
368	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
369	r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
370	r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
371	r.in.computer_name = TEST_MACHINE_NAME;
372	r.in.credential = &credential;
373	r.in.new_password = &new_password;
374	r.out.return_authenticator = &return_authenticator;
375
376	password = generate_random_str(tctx, 8);
377	E_md4hash(password, new_password.hash);
378
379	netlogon_creds_des_encrypt(creds, &new_password);
380
381	torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
382	torture_comment(tctx, "Changing machine account password to '%s'\n",
383			password);
384
385	netlogon_creds_client_authenticator(creds, &credential);
386
387	status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
388	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
389
390	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
391		torture_comment(tctx, "Credential chaining failed\n");
392	}
393
394	/* by changing the machine password twice we test the
395	   credentials chaining fully, and we verify that the server
396	   allows the password to be set to the same value twice in a
397	   row (match win2k3) */
398	torture_comment(tctx,
399		"Testing a second ServerPasswordSet on machine account\n");
400	torture_comment(tctx,
401		"Changing machine account password to '%s' (same as previous run)\n", password);
402
403	netlogon_creds_client_authenticator(creds, &credential);
404
405	status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
406	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
407
408	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
409		torture_comment(tctx, "Credential chaining failed\n");
410	}
411
412	cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
413
414	torture_assert(tctx,
415		test_SetupCredentials(p, tctx, machine_credentials, &creds),
416		"ServerPasswordSet failed to actually change the password");
417
418	return true;
419}
420
421
422/*
423  generate a random password for password change tests
424*/
425static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
426{
427	int i;
428	DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
429	generate_random_buffer(password.data, password.length);
430
431	for (i=0; i < len; i++) {
432		if (((uint16_t *)password.data)[i] == 0) {
433			((uint16_t *)password.data)[i] = 1;
434		}
435	}
436
437	return password;
438}
439
440/*
441  try a change password for our machine account
442*/
443static bool test_SetPassword2(struct torture_context *tctx,
444			      struct dcerpc_pipe *p,
445			      struct cli_credentials *machine_credentials)
446{
447	NTSTATUS status;
448	struct netr_ServerPasswordSet2 r;
449	const char *password;
450	DATA_BLOB new_random_pass;
451	struct netlogon_creds_CredentialState *creds;
452	struct samr_CryptPassword password_buf;
453	struct samr_Password nt_hash;
454	struct netr_Authenticator credential, return_authenticator;
455	struct netr_CryptPassword new_password;
456
457	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
458		return false;
459	}
460
461	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
462	r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
463	r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
464	r.in.computer_name = TEST_MACHINE_NAME;
465	r.in.credential = &credential;
466	r.in.new_password = &new_password;
467	r.out.return_authenticator = &return_authenticator;
468
469	password = generate_random_str(tctx, 8);
470	encode_pw_buffer(password_buf.data, password, STR_UNICODE);
471	netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
472
473	memcpy(new_password.data, password_buf.data, 512);
474	new_password.length = IVAL(password_buf.data, 512);
475
476	torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
477	torture_comment(tctx, "Changing machine account password to '%s'\n", password);
478
479	netlogon_creds_client_authenticator(creds, &credential);
480
481	status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
482	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
483
484	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
485		torture_comment(tctx, "Credential chaining failed\n");
486	}
487
488	cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
489
490	if (!torture_setting_bool(tctx, "dangerous", false)) {
491		torture_comment(tctx,
492			"Not testing ability to set password to '', enable dangerous tests to perform this test\n");
493	} else {
494		/* by changing the machine password to ""
495		 * we check if the server uses password restrictions
496		 * for ServerPasswordSet2
497		 * (win2k3 accepts "")
498		 */
499		password = "";
500		encode_pw_buffer(password_buf.data, password, STR_UNICODE);
501		netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
502
503		memcpy(new_password.data, password_buf.data, 512);
504		new_password.length = IVAL(password_buf.data, 512);
505
506		torture_comment(tctx,
507			"Testing ServerPasswordSet2 on machine account\n");
508		torture_comment(tctx,
509			"Changing machine account password to '%s'\n", password);
510
511		netlogon_creds_client_authenticator(creds, &credential);
512
513		status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
514		torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
515
516		if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
517			torture_comment(tctx, "Credential chaining failed\n");
518		}
519
520		cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
521	}
522
523	torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds),
524		"ServerPasswordSet failed to actually change the password");
525
526	/* now try a random password */
527	password = generate_random_str(tctx, 8);
528	encode_pw_buffer(password_buf.data, password, STR_UNICODE);
529	netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
530
531	memcpy(new_password.data, password_buf.data, 512);
532	new_password.length = IVAL(password_buf.data, 512);
533
534	torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
535	torture_comment(tctx, "Changing machine account password to '%s'\n", password);
536
537	netlogon_creds_client_authenticator(creds, &credential);
538
539	status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
540	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
541
542	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
543		torture_comment(tctx, "Credential chaining failed\n");
544	}
545
546	/* by changing the machine password twice we test the
547	   credentials chaining fully, and we verify that the server
548	   allows the password to be set to the same value twice in a
549	   row (match win2k3) */
550	torture_comment(tctx,
551		"Testing a second ServerPasswordSet2 on machine account\n");
552	torture_comment(tctx,
553		"Changing machine account password to '%s' (same as previous run)\n", password);
554
555	netlogon_creds_client_authenticator(creds, &credential);
556
557	status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
558	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
559
560	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
561		torture_comment(tctx, "Credential chaining failed\n");
562	}
563
564	cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
565
566	torture_assert (tctx,
567		test_SetupCredentials(p, tctx, machine_credentials, &creds),
568		"ServerPasswordSet failed to actually change the password");
569
570	new_random_pass = netlogon_very_rand_pass(tctx, 128);
571
572	/* now try a random stream of bytes for a password */
573	set_pw_in_buffer(password_buf.data, &new_random_pass);
574
575	netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
576
577	memcpy(new_password.data, password_buf.data, 512);
578	new_password.length = IVAL(password_buf.data, 512);
579
580	torture_comment(tctx,
581		"Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
582
583	netlogon_creds_client_authenticator(creds, &credential);
584
585	status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
586	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
587
588	if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
589		torture_comment(tctx, "Credential chaining failed\n");
590	}
591
592	mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
593
594	cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
595	cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
596
597	torture_assert (tctx,
598		test_SetupCredentials(p, tctx, machine_credentials, &creds),
599		"ServerPasswordSet failed to actually change the password");
600
601	return true;
602}
603
604static bool test_GetPassword(struct torture_context *tctx,
605			     struct dcerpc_pipe *p,
606			     struct cli_credentials *machine_credentials)
607{
608	struct netr_ServerPasswordGet r;
609	struct netlogon_creds_CredentialState *creds;
610	struct netr_Authenticator credential;
611	NTSTATUS status;
612	struct netr_Authenticator return_authenticator;
613	struct samr_Password password;
614
615	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
616		return false;
617	}
618
619	netlogon_creds_client_authenticator(creds, &credential);
620
621	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
622	r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
623	r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
624	r.in.computer_name = TEST_MACHINE_NAME;
625	r.in.credential = &credential;
626	r.out.return_authenticator = &return_authenticator;
627	r.out.password = &password;
628
629	status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
630	torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
631
632	return true;
633}
634
635static bool test_GetTrustPasswords(struct torture_context *tctx,
636				   struct dcerpc_pipe *p,
637				   struct cli_credentials *machine_credentials)
638{
639	struct netr_ServerTrustPasswordsGet r;
640	struct netlogon_creds_CredentialState *creds;
641	struct netr_Authenticator credential;
642	NTSTATUS status;
643	struct netr_Authenticator return_authenticator;
644	struct samr_Password password, password2;
645
646	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
647		return false;
648	}
649
650	netlogon_creds_client_authenticator(creds, &credential);
651
652	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
653	r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
654	r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
655	r.in.computer_name = TEST_MACHINE_NAME;
656	r.in.credential = &credential;
657	r.out.return_authenticator = &return_authenticator;
658	r.out.password = &password;
659	r.out.password2 = &password2;
660
661	status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
662	torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
663
664	return true;
665}
666
667/*
668  try a netlogon SamLogon
669*/
670bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
671			      struct cli_credentials *credentials,
672			      struct netlogon_creds_CredentialState *creds)
673{
674	NTSTATUS status;
675	struct netr_LogonSamLogon r;
676	struct netr_Authenticator auth, auth2;
677	union netr_LogonLevel logon;
678	union netr_Validation validation;
679	uint8_t authoritative;
680	struct netr_NetworkInfo ninfo;
681	DATA_BLOB names_blob, chal, lm_resp, nt_resp;
682	int i;
683	int flags = CLI_CRED_NTLM_AUTH;
684	if (lp_client_lanman_auth(tctx->lp_ctx)) {
685		flags |= CLI_CRED_LANMAN_AUTH;
686	}
687
688	if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
689		flags |= CLI_CRED_NTLMv2_AUTH;
690	}
691
692	cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx,
693						 &ninfo.identity_info.account_name.string,
694						 &ninfo.identity_info.domain_name.string);
695
696	generate_random_buffer(ninfo.challenge,
697			       sizeof(ninfo.challenge));
698	chal = data_blob_const(ninfo.challenge,
699			       sizeof(ninfo.challenge));
700
701	names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials),
702						cli_credentials_get_domain(credentials));
703
704	status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx,
705						   &flags,
706						   chal,
707						   names_blob,
708						   &lm_resp, &nt_resp,
709						   NULL, NULL);
710	torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
711
712	ninfo.lm.data = lm_resp.data;
713	ninfo.lm.length = lm_resp.length;
714
715	ninfo.nt.data = nt_resp.data;
716	ninfo.nt.length = nt_resp.length;
717
718	ninfo.identity_info.parameter_control = 0;
719	ninfo.identity_info.logon_id_low = 0;
720	ninfo.identity_info.logon_id_high = 0;
721	ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
722
723	logon.network = &ninfo;
724
725	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
726	r.in.computer_name = cli_credentials_get_workstation(credentials);
727	r.in.credential = &auth;
728	r.in.return_authenticator = &auth2;
729	r.in.logon_level = 2;
730	r.in.logon = &logon;
731	r.out.validation = &validation;
732	r.out.authoritative = &authoritative;
733
734	d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
735
736	for (i=2;i<3;i++) {
737		ZERO_STRUCT(auth2);
738		netlogon_creds_client_authenticator(creds, &auth);
739
740		r.in.validation_level = i;
741
742		status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
743		torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
744
745		torture_assert(tctx, netlogon_creds_client_check(creds,
746								 &r.out.return_authenticator->cred),
747			"Credential chaining failed");
748	}
749
750	r.in.credential = NULL;
751
752	for (i=2;i<=3;i++) {
753
754		r.in.validation_level = i;
755
756		torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
757
758		status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
759		torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER,
760			"LogonSamLogon expected INVALID_PARAMETER");
761
762	}
763
764	return true;
765}
766
767/*
768  try a netlogon SamLogon
769*/
770static bool test_SamLogon(struct torture_context *tctx,
771			  struct dcerpc_pipe *p,
772			  struct cli_credentials *credentials)
773{
774	struct netlogon_creds_CredentialState *creds;
775
776	if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
777		return false;
778	}
779
780	return test_netlogon_ops(p, tctx, credentials, creds);
781}
782
783/* we remember the sequence numbers so we can easily do a DatabaseDelta */
784static uint64_t sequence_nums[3];
785
786/*
787  try a netlogon DatabaseSync
788*/
789static bool test_DatabaseSync(struct torture_context *tctx,
790			      struct dcerpc_pipe *p,
791			      struct cli_credentials *machine_credentials)
792{
793	NTSTATUS status;
794	struct netr_DatabaseSync r;
795	struct netlogon_creds_CredentialState *creds;
796	const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
797	int i;
798	struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
799	struct netr_Authenticator credential, return_authenticator;
800
801	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
802		return false;
803	}
804
805	ZERO_STRUCT(return_authenticator);
806
807	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
808	r.in.computername = TEST_MACHINE_NAME;
809	r.in.preferredmaximumlength = (uint32_t)-1;
810	r.in.return_authenticator = &return_authenticator;
811	r.out.delta_enum_array = &delta_enum_array;
812	r.out.return_authenticator = &return_authenticator;
813
814	for (i=0;i<ARRAY_SIZE(database_ids);i++) {
815
816		uint32_t sync_context = 0;
817
818		r.in.database_id = database_ids[i];
819		r.in.sync_context = &sync_context;
820		r.out.sync_context = &sync_context;
821
822		torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
823
824		do {
825			netlogon_creds_client_authenticator(creds, &credential);
826
827			r.in.credential = &credential;
828
829			status = dcerpc_netr_DatabaseSync(p, tctx, &r);
830			if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
831			    break;
832
833			/* Native mode servers don't do this */
834			if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
835				return true;
836			}
837			torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
838
839			if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
840				torture_comment(tctx, "Credential chaining failed\n");
841			}
842
843			if (delta_enum_array &&
844			    delta_enum_array->num_deltas > 0 &&
845			    delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
846			    delta_enum_array->delta_enum[0].delta_union.domain) {
847				sequence_nums[r.in.database_id] =
848					delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
849				torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
850				       r.in.database_id,
851				       (unsigned long long)sequence_nums[r.in.database_id]);
852			}
853		} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
854	}
855
856	return true;
857}
858
859
860/*
861  try a netlogon DatabaseDeltas
862*/
863static bool test_DatabaseDeltas(struct torture_context *tctx,
864				struct dcerpc_pipe *p,
865				struct cli_credentials *machine_credentials)
866{
867	NTSTATUS status;
868	struct netr_DatabaseDeltas r;
869	struct netlogon_creds_CredentialState *creds;
870	struct netr_Authenticator credential;
871	struct netr_Authenticator return_authenticator;
872	struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
873	const uint32_t database_ids[] = {0, 1, 2};
874	int i;
875
876	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
877		return false;
878	}
879
880	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
881	r.in.computername = TEST_MACHINE_NAME;
882	r.in.preferredmaximumlength = (uint32_t)-1;
883	ZERO_STRUCT(r.in.return_authenticator);
884	r.out.return_authenticator = &return_authenticator;
885	r.out.delta_enum_array = &delta_enum_array;
886
887	for (i=0;i<ARRAY_SIZE(database_ids);i++) {
888		r.in.database_id = database_ids[i];
889		r.in.sequence_num = &sequence_nums[r.in.database_id];
890
891		if (*r.in.sequence_num == 0) continue;
892
893		*r.in.sequence_num -= 1;
894
895		torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n",
896		       r.in.database_id, (unsigned long long)*r.in.sequence_num);
897
898		do {
899			netlogon_creds_client_authenticator(creds, &credential);
900
901			status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
902			if (NT_STATUS_EQUAL(status,
903					     NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
904				torture_comment(tctx, "not considering %s to be an error\n",
905				       nt_errstr(status));
906				return true;
907			}
908			if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
909			    break;
910
911			torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
912
913			if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
914				torture_comment(tctx, "Credential chaining failed\n");
915			}
916
917			(*r.in.sequence_num)++;
918		} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
919	}
920
921	return true;
922}
923
924static bool test_DatabaseRedo(struct torture_context *tctx,
925			      struct dcerpc_pipe *p,
926			      struct cli_credentials *machine_credentials)
927{
928	NTSTATUS status;
929	struct netr_DatabaseRedo r;
930	struct netlogon_creds_CredentialState *creds;
931	struct netr_Authenticator credential;
932	struct netr_Authenticator return_authenticator;
933	struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
934	struct netr_ChangeLogEntry e;
935	struct dom_sid null_sid, *sid;
936	int i,d;
937
938	ZERO_STRUCT(null_sid);
939
940	sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
941
942	{
943
944	struct {
945		uint32_t rid;
946		uint16_t flags;
947		uint8_t db_index;
948		uint8_t delta_type;
949		struct dom_sid sid;
950		const char *name;
951		NTSTATUS expected_error;
952		uint32_t expected_num_results;
953		uint8_t expected_delta_type_1;
954		uint8_t expected_delta_type_2;
955		const char *comment;
956	} changes[] = {
957
958		/* SAM_DATABASE_DOMAIN */
959
960		{
961			.rid			= 0,
962			.flags			= 0,
963			.db_index		= SAM_DATABASE_DOMAIN,
964			.delta_type		= NETR_DELTA_MODIFY_COUNT,
965			.sid			= null_sid,
966			.name			= NULL,
967			.expected_error		= NT_STATUS_SYNCHRONIZATION_REQUIRED,
968			.expected_num_results   = 0,
969			.comment		= "NETR_DELTA_MODIFY_COUNT"
970		},
971		{
972			.rid			= 0,
973			.flags			= 0,
974			.db_index		= SAM_DATABASE_DOMAIN,
975			.delta_type		= 0,
976			.sid			= null_sid,
977			.name			= NULL,
978			.expected_error		= NT_STATUS_OK,
979			.expected_num_results	= 1,
980			.expected_delta_type_1	= NETR_DELTA_DOMAIN,
981			.comment		= "NULL DELTA"
982		},
983		{
984			.rid			= 0,
985			.flags			= 0,
986			.db_index		= SAM_DATABASE_DOMAIN,
987			.delta_type		= NETR_DELTA_DOMAIN,
988			.sid			= null_sid,
989			.name			= NULL,
990			.expected_error		= NT_STATUS_OK,
991			.expected_num_results	= 1,
992			.expected_delta_type_1	= NETR_DELTA_DOMAIN,
993			.comment		= "NETR_DELTA_DOMAIN"
994		},
995		{
996			.rid			= DOMAIN_RID_ADMINISTRATOR,
997			.flags			= 0,
998			.db_index		= SAM_DATABASE_DOMAIN,
999			.delta_type		= NETR_DELTA_USER,
1000			.sid			= null_sid,
1001			.name			= NULL,
1002			.expected_error		= NT_STATUS_OK,
1003			.expected_num_results   = 1,
1004			.expected_delta_type_1	= NETR_DELTA_USER,
1005			.comment		= "NETR_DELTA_USER by rid 500"
1006		},
1007		{
1008			.rid			= DOMAIN_RID_GUEST,
1009			.flags			= 0,
1010			.db_index		= SAM_DATABASE_DOMAIN,
1011			.delta_type		= NETR_DELTA_USER,
1012			.sid			= null_sid,
1013			.name			= NULL,
1014			.expected_error		= NT_STATUS_OK,
1015			.expected_num_results   = 1,
1016			.expected_delta_type_1	= NETR_DELTA_USER,
1017			.comment		= "NETR_DELTA_USER by rid 501"
1018		},
1019		{
1020			.rid			= 0,
1021			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1022			.db_index		= SAM_DATABASE_DOMAIN,
1023			.delta_type		= NETR_DELTA_USER,
1024			.sid			= *sid,
1025			.name			= NULL,
1026			.expected_error		= NT_STATUS_OK,
1027			.expected_num_results   = 1,
1028			.expected_delta_type_1	= NETR_DELTA_DELETE_USER,
1029			.comment		= "NETR_DELTA_USER by sid and flags"
1030		},
1031		{
1032			.rid			= 0,
1033			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1034			.db_index		= SAM_DATABASE_DOMAIN,
1035			.delta_type		= NETR_DELTA_USER,
1036			.sid			= null_sid,
1037			.name			= NULL,
1038			.expected_error		= NT_STATUS_OK,
1039			.expected_num_results   = 1,
1040			.expected_delta_type_1	= NETR_DELTA_DELETE_USER,
1041			.comment		= "NETR_DELTA_USER by null_sid and flags"
1042		},
1043		{
1044			.rid			= 0,
1045			.flags			= NETR_CHANGELOG_NAME_INCLUDED,
1046			.db_index		= SAM_DATABASE_DOMAIN,
1047			.delta_type		= NETR_DELTA_USER,
1048			.sid			= null_sid,
1049			.name			= "administrator",
1050			.expected_error		= NT_STATUS_OK,
1051			.expected_num_results   = 1,
1052			.expected_delta_type_1	= NETR_DELTA_DELETE_USER,
1053			.comment		= "NETR_DELTA_USER by name 'administrator'"
1054		},
1055		{
1056			.rid			= DOMAIN_RID_ADMINS,
1057			.flags			= 0,
1058			.db_index		= SAM_DATABASE_DOMAIN,
1059			.delta_type		= NETR_DELTA_GROUP,
1060			.sid			= null_sid,
1061			.name			= NULL,
1062			.expected_error		= NT_STATUS_OK,
1063			.expected_num_results   = 2,
1064			.expected_delta_type_1	= NETR_DELTA_GROUP,
1065			.expected_delta_type_2	= NETR_DELTA_GROUP_MEMBER,
1066			.comment		= "NETR_DELTA_GROUP by rid 512"
1067		},
1068		{
1069			.rid			= DOMAIN_RID_ADMINS,
1070			.flags			= 0,
1071			.db_index		= SAM_DATABASE_DOMAIN,
1072			.delta_type		= NETR_DELTA_GROUP_MEMBER,
1073			.sid			= null_sid,
1074			.name			= NULL,
1075			.expected_error		= NT_STATUS_OK,
1076			.expected_num_results   = 2,
1077			.expected_delta_type_1	= NETR_DELTA_GROUP,
1078			.expected_delta_type_2	= NETR_DELTA_GROUP_MEMBER,
1079			.comment		= "NETR_DELTA_GROUP_MEMBER by rid 512"
1080		},
1081
1082
1083		/* SAM_DATABASE_BUILTIN */
1084
1085		{
1086			.rid			= 0,
1087			.flags			= 0,
1088			.db_index		= SAM_DATABASE_BUILTIN,
1089			.delta_type		= NETR_DELTA_MODIFY_COUNT,
1090			.sid			= null_sid,
1091			.name			= NULL,
1092			.expected_error		= NT_STATUS_SYNCHRONIZATION_REQUIRED,
1093			.expected_num_results   = 0,
1094			.comment		= "NETR_DELTA_MODIFY_COUNT"
1095		},
1096		{
1097			.rid			= 0,
1098			.flags			= 0,
1099			.db_index		= SAM_DATABASE_BUILTIN,
1100			.delta_type		= NETR_DELTA_DOMAIN,
1101			.sid			= null_sid,
1102			.name			= NULL,
1103			.expected_error		= NT_STATUS_OK,
1104			.expected_num_results   = 1,
1105			.expected_delta_type_1	= NETR_DELTA_DOMAIN,
1106			.comment		= "NETR_DELTA_DOMAIN"
1107		},
1108		{
1109			.rid			= DOMAIN_RID_ADMINISTRATOR,
1110			.flags			= 0,
1111			.db_index		= SAM_DATABASE_BUILTIN,
1112			.delta_type		= NETR_DELTA_USER,
1113			.sid			= null_sid,
1114			.name			= NULL,
1115			.expected_error		= NT_STATUS_OK,
1116			.expected_num_results   = 1,
1117			.expected_delta_type_1	= NETR_DELTA_DELETE_USER,
1118			.comment		= "NETR_DELTA_USER by rid 500"
1119		},
1120		{
1121			.rid			= 0,
1122			.flags			= 0,
1123			.db_index		= SAM_DATABASE_BUILTIN,
1124			.delta_type		= NETR_DELTA_USER,
1125			.sid			= null_sid,
1126			.name			= NULL,
1127			.expected_error		= NT_STATUS_OK,
1128			.expected_num_results   = 1,
1129			.expected_delta_type_1	= NETR_DELTA_DELETE_USER,
1130			.comment		= "NETR_DELTA_USER"
1131		},
1132		{
1133			.rid			= 544,
1134			.flags			= 0,
1135			.db_index		= SAM_DATABASE_BUILTIN,
1136			.delta_type		= NETR_DELTA_ALIAS,
1137			.sid			= null_sid,
1138			.name			= NULL,
1139			.expected_error		= NT_STATUS_OK,
1140			.expected_num_results   = 2,
1141			.expected_delta_type_1	= NETR_DELTA_ALIAS,
1142			.expected_delta_type_2	= NETR_DELTA_ALIAS_MEMBER,
1143			.comment		= "NETR_DELTA_ALIAS by rid 544"
1144		},
1145		{
1146			.rid			= 544,
1147			.flags			= 0,
1148			.db_index		= SAM_DATABASE_BUILTIN,
1149			.delta_type		= NETR_DELTA_ALIAS_MEMBER,
1150			.sid			= null_sid,
1151			.name			= NULL,
1152			.expected_error		= NT_STATUS_OK,
1153			.expected_num_results   = 2,
1154			.expected_delta_type_1	= NETR_DELTA_ALIAS,
1155			.expected_delta_type_2	= NETR_DELTA_ALIAS_MEMBER,
1156			.comment		= "NETR_DELTA_ALIAS_MEMBER by rid 544"
1157		},
1158		{
1159			.rid			= 544,
1160			.flags			= 0,
1161			.db_index		= SAM_DATABASE_BUILTIN,
1162			.delta_type		= 0,
1163			.sid			= null_sid,
1164			.name			= NULL,
1165			.expected_error		= NT_STATUS_OK,
1166			.expected_num_results   = 1,
1167			.expected_delta_type_1	= NETR_DELTA_DOMAIN,
1168			.comment		= "NULL DELTA by rid 544"
1169		},
1170		{
1171			.rid			= 544,
1172			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1173			.db_index		= SAM_DATABASE_BUILTIN,
1174			.delta_type		= 0,
1175			.sid			= *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1176			.name			= NULL,
1177			.expected_error		= NT_STATUS_OK,
1178			.expected_num_results   = 1,
1179			.expected_delta_type_1	= NETR_DELTA_DOMAIN,
1180			.comment		= "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1181		},
1182		{
1183			.rid			= 544,
1184			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1185			.db_index		= SAM_DATABASE_BUILTIN,
1186			.delta_type		= NETR_DELTA_ALIAS,
1187			.sid			= *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1188			.name			= NULL,
1189			.expected_error		= NT_STATUS_OK,
1190			.expected_num_results   = 2,
1191			.expected_delta_type_1	= NETR_DELTA_ALIAS,
1192			.expected_delta_type_2	= NETR_DELTA_ALIAS_MEMBER,
1193			.comment		= "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1194		},
1195		{
1196			.rid			= 0,
1197			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1198			.db_index		= SAM_DATABASE_BUILTIN,
1199			.delta_type		= NETR_DELTA_ALIAS,
1200			.sid			= *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1201			.name			= NULL,
1202			.expected_error		= NT_STATUS_OK,
1203			.expected_num_results   = 1,
1204			.expected_delta_type_1	= NETR_DELTA_DELETE_ALIAS,
1205			.comment		= "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1206		},
1207
1208		/* SAM_DATABASE_PRIVS */
1209
1210		{
1211			.rid			= 0,
1212			.flags			= 0,
1213			.db_index		= SAM_DATABASE_PRIVS,
1214			.delta_type		= 0,
1215			.sid			= null_sid,
1216			.name			= NULL,
1217			.expected_error		= NT_STATUS_ACCESS_DENIED,
1218			.expected_num_results   = 0,
1219			.comment		= "NULL DELTA"
1220		},
1221		{
1222			.rid			= 0,
1223			.flags			= 0,
1224			.db_index		= SAM_DATABASE_PRIVS,
1225			.delta_type		= NETR_DELTA_MODIFY_COUNT,
1226			.sid			= null_sid,
1227			.name			= NULL,
1228			.expected_error		= NT_STATUS_SYNCHRONIZATION_REQUIRED,
1229			.expected_num_results   = 0,
1230			.comment		= "NETR_DELTA_MODIFY_COUNT"
1231		},
1232		{
1233			.rid			= 0,
1234			.flags			= 0,
1235			.db_index		= SAM_DATABASE_PRIVS,
1236			.delta_type		= NETR_DELTA_POLICY,
1237			.sid			= null_sid,
1238			.name			= NULL,
1239			.expected_error		= NT_STATUS_OK,
1240			.expected_num_results   = 1,
1241			.expected_delta_type_1	= NETR_DELTA_POLICY,
1242			.comment		= "NETR_DELTA_POLICY"
1243		},
1244		{
1245			.rid			= 0,
1246			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1247			.db_index		= SAM_DATABASE_PRIVS,
1248			.delta_type		= NETR_DELTA_POLICY,
1249			.sid			= null_sid,
1250			.name			= NULL,
1251			.expected_error		= NT_STATUS_OK,
1252			.expected_num_results   = 1,
1253			.expected_delta_type_1	= NETR_DELTA_POLICY,
1254			.comment		= "NETR_DELTA_POLICY by null sid and flags"
1255		},
1256		{
1257			.rid			= 0,
1258			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1259			.db_index		= SAM_DATABASE_PRIVS,
1260			.delta_type		= NETR_DELTA_POLICY,
1261			.sid			= *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1262			.name			= NULL,
1263			.expected_error		= NT_STATUS_OK,
1264			.expected_num_results   = 1,
1265			.expected_delta_type_1	= NETR_DELTA_POLICY,
1266			.comment		= "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1267		},
1268		{
1269			.rid			= DOMAIN_RID_ADMINISTRATOR,
1270			.flags			= 0,
1271			.db_index		= SAM_DATABASE_PRIVS,
1272			.delta_type		= NETR_DELTA_ACCOUNT,
1273			.sid			= null_sid,
1274			.name			= NULL,
1275			.expected_error		= NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1276			.expected_num_results   = 0,
1277			.comment		= "NETR_DELTA_ACCOUNT by rid 500"
1278		},
1279		{
1280			.rid			= 0,
1281			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1282			.db_index		= SAM_DATABASE_PRIVS,
1283			.delta_type		= NETR_DELTA_ACCOUNT,
1284			.sid			= *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1285			.name			= NULL,
1286			.expected_error		= NT_STATUS_OK,
1287			.expected_num_results   = 1,
1288			.expected_delta_type_1	= NETR_DELTA_ACCOUNT,
1289			.comment		= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1290		},
1291		{
1292			.rid			= 0,
1293			.flags			= NETR_CHANGELOG_SID_INCLUDED |
1294						  NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1295			.db_index		= SAM_DATABASE_PRIVS,
1296			.delta_type		= NETR_DELTA_ACCOUNT,
1297			.sid			= *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1298			.name			= NULL,
1299			.expected_error		= NT_STATUS_OK,
1300			.expected_num_results   = 1,
1301			.expected_delta_type_1	= NETR_DELTA_ACCOUNT,
1302			.comment		= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1303		},
1304		{
1305			.rid			= 0,
1306			.flags			= NETR_CHANGELOG_SID_INCLUDED |
1307						  NETR_CHANGELOG_NAME_INCLUDED,
1308			.db_index		= SAM_DATABASE_PRIVS,
1309			.delta_type		= NETR_DELTA_ACCOUNT,
1310			.sid			= *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1311			.name			= NULL,
1312			.expected_error		= NT_STATUS_INVALID_PARAMETER,
1313			.expected_num_results   = 0,
1314			.comment		= "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1315		},
1316		{
1317			.rid			= DOMAIN_RID_ADMINISTRATOR,
1318			.flags			= NETR_CHANGELOG_SID_INCLUDED,
1319			.db_index		= SAM_DATABASE_PRIVS,
1320			.delta_type		= NETR_DELTA_ACCOUNT,
1321			.sid			= *sid,
1322			.name			= NULL,
1323			.expected_error		= NT_STATUS_OK,
1324			.expected_num_results   = 1,
1325			.expected_delta_type_1	= NETR_DELTA_DELETE_ACCOUNT,
1326			.comment		= "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1327		},
1328		{
1329			.rid			= 0,
1330			.flags			= NETR_CHANGELOG_NAME_INCLUDED,
1331			.db_index		= SAM_DATABASE_PRIVS,
1332			.delta_type		= NETR_DELTA_SECRET,
1333			.sid			= null_sid,
1334			.name			= "IsurelydontexistIhope",
1335			.expected_error		= NT_STATUS_OK,
1336			.expected_num_results   = 1,
1337			.expected_delta_type_1	= NETR_DELTA_DELETE_SECRET,
1338			.comment		= "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1339		},
1340		{
1341			.rid			= 0,
1342			.flags			= NETR_CHANGELOG_NAME_INCLUDED,
1343			.db_index		= SAM_DATABASE_PRIVS,
1344			.delta_type		= NETR_DELTA_SECRET,
1345			.sid			= null_sid,
1346			.name			= "G$BCKUPKEY_P",
1347			.expected_error		= NT_STATUS_OK,
1348			.expected_num_results   = 1,
1349			.expected_delta_type_1	= NETR_DELTA_SECRET,
1350			.comment		= "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1351		}
1352	};
1353
1354	ZERO_STRUCT(return_authenticator);
1355
1356	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1357	r.in.computername = TEST_MACHINE_NAME;
1358	r.in.return_authenticator = &return_authenticator;
1359	r.out.return_authenticator = &return_authenticator;
1360	r.out.delta_enum_array = &delta_enum_array;
1361
1362	for (d=0; d<3; d++) {
1363
1364		const char *database;
1365
1366		switch (d) {
1367		case 0:
1368			database = "SAM";
1369			break;
1370		case 1:
1371			database = "BUILTIN";
1372			break;
1373		case 2:
1374			database = "LSA";
1375			break;
1376		default:
1377			break;
1378		}
1379
1380		torture_comment(tctx, "Testing DatabaseRedo\n");
1381
1382		if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1383			return false;
1384		}
1385
1386		for (i=0;i<ARRAY_SIZE(changes);i++) {
1387
1388			if (d != changes[i].db_index) {
1389				continue;
1390			}
1391
1392			netlogon_creds_client_authenticator(creds, &credential);
1393
1394			r.in.credential = &credential;
1395
1396			e.serial_number1	= 0;
1397			e.serial_number2	= 0;
1398			e.object_rid		= changes[i].rid;
1399			e.flags			= changes[i].flags;
1400			e.db_index		= changes[i].db_index;
1401			e.delta_type		= changes[i].delta_type;
1402
1403			switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1404			case NETR_CHANGELOG_SID_INCLUDED:
1405				e.object.object_sid		= changes[i].sid;
1406				break;
1407			case NETR_CHANGELOG_NAME_INCLUDED:
1408				e.object.object_name		= changes[i].name;
1409				break;
1410			default:
1411				break;
1412			}
1413
1414			r.in.change_log_entry = e;
1415
1416			torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1417				database, changes[i].comment);
1418
1419			status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
1420			if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1421				return true;
1422			}
1423
1424			torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
1425			if (delta_enum_array) {
1426				torture_assert_int_equal(tctx,
1427					delta_enum_array->num_deltas,
1428					changes[i].expected_num_results,
1429					changes[i].comment);
1430				if (delta_enum_array->num_deltas > 0) {
1431					torture_assert_int_equal(tctx,
1432						delta_enum_array->delta_enum[0].delta_type,
1433						changes[i].expected_delta_type_1,
1434						changes[i].comment);
1435				}
1436				if (delta_enum_array->num_deltas > 1) {
1437					torture_assert_int_equal(tctx,
1438						delta_enum_array->delta_enum[1].delta_type,
1439						changes[i].expected_delta_type_2,
1440						changes[i].comment);
1441				}
1442			}
1443
1444			if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1445				torture_comment(tctx, "Credential chaining failed\n");
1446				if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1447					return false;
1448				}
1449			}
1450		}
1451	}
1452	}
1453
1454	return true;
1455}
1456
1457/*
1458  try a netlogon AccountDeltas
1459*/
1460static bool test_AccountDeltas(struct torture_context *tctx,
1461			       struct dcerpc_pipe *p,
1462			       struct cli_credentials *machine_credentials)
1463{
1464	NTSTATUS status;
1465	struct netr_AccountDeltas r;
1466	struct netlogon_creds_CredentialState *creds;
1467
1468	struct netr_AccountBuffer buffer;
1469	uint32_t count_returned = 0;
1470	uint32_t total_entries = 0;
1471	struct netr_UAS_INFO_0 recordid;
1472	struct netr_Authenticator return_authenticator;
1473
1474	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1475		return false;
1476	}
1477
1478	ZERO_STRUCT(return_authenticator);
1479
1480	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1481	r.in.computername = TEST_MACHINE_NAME;
1482	r.in.return_authenticator = &return_authenticator;
1483	netlogon_creds_client_authenticator(creds, &r.in.credential);
1484	ZERO_STRUCT(r.in.uas);
1485	r.in.count=10;
1486	r.in.level=0;
1487	r.in.buffersize=100;
1488	r.out.buffer = &buffer;
1489	r.out.count_returned = &count_returned;
1490	r.out.total_entries = &total_entries;
1491	r.out.recordid = &recordid;
1492	r.out.return_authenticator = &return_authenticator;
1493
1494	/* w2k3 returns "NOT IMPLEMENTED" for this call */
1495	status = dcerpc_netr_AccountDeltas(p, tctx, &r);
1496	torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1497
1498	return true;
1499}
1500
1501/*
1502  try a netlogon AccountSync
1503*/
1504static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p,
1505			     struct cli_credentials *machine_credentials)
1506{
1507	NTSTATUS status;
1508	struct netr_AccountSync r;
1509	struct netlogon_creds_CredentialState *creds;
1510
1511	struct netr_AccountBuffer buffer;
1512	uint32_t count_returned = 0;
1513	uint32_t total_entries = 0;
1514	uint32_t next_reference = 0;
1515	struct netr_UAS_INFO_0 recordid;
1516	struct netr_Authenticator return_authenticator;
1517
1518	ZERO_STRUCT(recordid);
1519	ZERO_STRUCT(return_authenticator);
1520
1521	if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1522		return false;
1523	}
1524
1525	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1526	r.in.computername = TEST_MACHINE_NAME;
1527	r.in.return_authenticator = &return_authenticator;
1528	netlogon_creds_client_authenticator(creds, &r.in.credential);
1529	r.in.recordid = &recordid;
1530	r.in.reference=0;
1531	r.in.level=0;
1532	r.in.buffersize=100;
1533	r.out.buffer = &buffer;
1534	r.out.count_returned = &count_returned;
1535	r.out.total_entries = &total_entries;
1536	r.out.next_reference = &next_reference;
1537	r.out.recordid = &recordid;
1538	r.out.return_authenticator = &return_authenticator;
1539
1540	/* w2k3 returns "NOT IMPLEMENTED" for this call */
1541	status = dcerpc_netr_AccountSync(p, tctx, &r);
1542	torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1543
1544	return true;
1545}
1546
1547/*
1548  try a netlogon GetDcName
1549*/
1550static bool test_GetDcName(struct torture_context *tctx,
1551			   struct dcerpc_pipe *p)
1552{
1553	NTSTATUS status;
1554	struct netr_GetDcName r;
1555	const char *dcname = NULL;
1556
1557	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1558	r.in.domainname = lp_workgroup(tctx->lp_ctx);
1559	r.out.dcname = &dcname;
1560
1561	status = dcerpc_netr_GetDcName(p, tctx, &r);
1562	torture_assert_ntstatus_ok(tctx, status, "GetDcName");
1563	torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
1564
1565	torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1566
1567	return true;
1568}
1569
1570static const char *function_code_str(TALLOC_CTX *mem_ctx,
1571				     enum netr_LogonControlCode function_code)
1572{
1573	switch (function_code) {
1574	case NETLOGON_CONTROL_QUERY:
1575		return "NETLOGON_CONTROL_QUERY";
1576	case NETLOGON_CONTROL_REPLICATE:
1577		return "NETLOGON_CONTROL_REPLICATE";
1578	case NETLOGON_CONTROL_SYNCHRONIZE:
1579		return "NETLOGON_CONTROL_SYNCHRONIZE";
1580	case NETLOGON_CONTROL_PDC_REPLICATE:
1581		return "NETLOGON_CONTROL_PDC_REPLICATE";
1582	case NETLOGON_CONTROL_REDISCOVER:
1583		return "NETLOGON_CONTROL_REDISCOVER";
1584	case NETLOGON_CONTROL_TC_QUERY:
1585		return "NETLOGON_CONTROL_TC_QUERY";
1586	case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1587		return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1588	case NETLOGON_CONTROL_FIND_USER:
1589		return "NETLOGON_CONTROL_FIND_USER";
1590	case NETLOGON_CONTROL_CHANGE_PASSWORD:
1591		return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1592	case NETLOGON_CONTROL_TC_VERIFY:
1593		return "NETLOGON_CONTROL_TC_VERIFY";
1594	case NETLOGON_CONTROL_FORCE_DNS_REG:
1595		return "NETLOGON_CONTROL_FORCE_DNS_REG";
1596	case NETLOGON_CONTROL_QUERY_DNS_REG:
1597		return "NETLOGON_CONTROL_QUERY_DNS_REG";
1598	case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1599		return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1600	case NETLOGON_CONTROL_TRUNCATE_LOG:
1601		return "NETLOGON_CONTROL_TRUNCATE_LOG";
1602	case NETLOGON_CONTROL_SET_DBFLAG:
1603		return "NETLOGON_CONTROL_SET_DBFLAG";
1604	case NETLOGON_CONTROL_BREAKPOINT:
1605		return "NETLOGON_CONTROL_BREAKPOINT";
1606	default:
1607		return talloc_asprintf(mem_ctx, "unknown function code: %d",
1608				       function_code);
1609	}
1610}
1611
1612
1613/*
1614  try a netlogon LogonControl
1615*/
1616static bool test_LogonControl(struct torture_context *tctx,
1617			      struct dcerpc_pipe *p,
1618			      struct cli_credentials *machine_credentials)
1619
1620{
1621	NTSTATUS status;
1622	struct netr_LogonControl r;
1623	union netr_CONTROL_QUERY_INFORMATION query;
1624	int i,f;
1625	enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1626
1627	uint32_t function_codes[] = {
1628		NETLOGON_CONTROL_QUERY,
1629		NETLOGON_CONTROL_REPLICATE,
1630		NETLOGON_CONTROL_SYNCHRONIZE,
1631		NETLOGON_CONTROL_PDC_REPLICATE,
1632		NETLOGON_CONTROL_REDISCOVER,
1633		NETLOGON_CONTROL_TC_QUERY,
1634		NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1635		NETLOGON_CONTROL_FIND_USER,
1636		NETLOGON_CONTROL_CHANGE_PASSWORD,
1637		NETLOGON_CONTROL_TC_VERIFY,
1638		NETLOGON_CONTROL_FORCE_DNS_REG,
1639		NETLOGON_CONTROL_QUERY_DNS_REG,
1640		NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1641		NETLOGON_CONTROL_TRUNCATE_LOG,
1642		NETLOGON_CONTROL_SET_DBFLAG,
1643		NETLOGON_CONTROL_BREAKPOINT
1644	};
1645
1646	if (machine_credentials) {
1647		secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1648	}
1649
1650	torture_comment(tctx, "testing LogonControl with secure channel type: %d\n",
1651		secure_channel_type);
1652
1653	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1654	r.in.function_code = 1;
1655	r.out.query = &query;
1656
1657	for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1658	for (i=1;i<5;i++) {
1659
1660		r.in.function_code = function_codes[f];
1661		r.in.level = i;
1662
1663		torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1664				function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1665
1666		status = dcerpc_netr_LogonControl(p, tctx, &r);
1667		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1668
1669		switch (r.in.level) {
1670		case 1:
1671			switch (r.in.function_code) {
1672			case NETLOGON_CONTROL_REPLICATE:
1673			case NETLOGON_CONTROL_SYNCHRONIZE:
1674			case NETLOGON_CONTROL_PDC_REPLICATE:
1675			case NETLOGON_CONTROL_BREAKPOINT:
1676			case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1677				if ((secure_channel_type == SEC_CHAN_BDC) ||
1678				    (secure_channel_type == SEC_CHAN_WKSTA)) {
1679					torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1680						"LogonControl returned unexpected error code");
1681				} else {
1682					torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1683						"LogonControl returned unexpected error code");
1684				}
1685				break;
1686
1687			case NETLOGON_CONTROL_REDISCOVER:
1688			case NETLOGON_CONTROL_TC_QUERY:
1689			case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1690			case NETLOGON_CONTROL_FIND_USER:
1691			case NETLOGON_CONTROL_CHANGE_PASSWORD:
1692			case NETLOGON_CONTROL_TC_VERIFY:
1693			case NETLOGON_CONTROL_FORCE_DNS_REG:
1694			case NETLOGON_CONTROL_QUERY_DNS_REG:
1695			case NETLOGON_CONTROL_SET_DBFLAG:
1696				torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1697					"LogonControl returned unexpected error code");
1698				break;
1699			case NETLOGON_CONTROL_TRUNCATE_LOG:
1700				if ((secure_channel_type == SEC_CHAN_BDC) ||
1701				    (secure_channel_type == SEC_CHAN_WKSTA)) {
1702					torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1703						"LogonControl returned unexpected error code");
1704				} else {
1705					torture_assert_werr_ok(tctx, r.out.result,
1706						"LogonControl returned unexpected result");
1707				}
1708				break;
1709			default:
1710				torture_assert_werr_ok(tctx, r.out.result,
1711					"LogonControl returned unexpected result");
1712				break;
1713			}
1714			break;
1715		case 2:
1716			torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1717				"LogonControl returned unexpected error code");
1718			break;
1719		default:
1720			torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1721				"LogonControl returned unexpected error code");
1722			break;
1723		}
1724	}
1725	}
1726
1727	return true;
1728}
1729
1730
1731/*
1732  try a netlogon GetAnyDCName
1733*/
1734static bool test_GetAnyDCName(struct torture_context *tctx,
1735			      struct dcerpc_pipe *p)
1736{
1737	NTSTATUS status;
1738	struct netr_GetAnyDCName r;
1739	const char *dcname = NULL;
1740
1741	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1742	r.in.domainname = lp_workgroup(tctx->lp_ctx);
1743	r.out.dcname = &dcname;
1744
1745	status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
1746	torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1747	torture_assert_werr_ok(tctx, r.out.result, "GetAnyDCName");
1748
1749	if (dcname) {
1750	    torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1751	}
1752
1753	return true;
1754}
1755
1756
1757/*
1758  try a netlogon LogonControl2
1759*/
1760static bool test_LogonControl2(struct torture_context *tctx,
1761			       struct dcerpc_pipe *p,
1762			       struct cli_credentials *machine_credentials)
1763
1764{
1765	NTSTATUS status;
1766	struct netr_LogonControl2 r;
1767	union netr_CONTROL_DATA_INFORMATION data;
1768	union netr_CONTROL_QUERY_INFORMATION query;
1769	int i;
1770
1771	data.domain = lp_workgroup(tctx->lp_ctx);
1772
1773	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1774
1775	r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1776	r.in.data = &data;
1777	r.out.query = &query;
1778
1779	for (i=1;i<4;i++) {
1780		r.in.level = i;
1781
1782		torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1783		       i, r.in.function_code);
1784
1785		status = dcerpc_netr_LogonControl2(p, tctx, &r);
1786		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1787	}
1788
1789	data.domain = lp_workgroup(tctx->lp_ctx);
1790
1791	r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1792	r.in.data = &data;
1793
1794	for (i=1;i<4;i++) {
1795		r.in.level = i;
1796
1797		torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1798		       i, r.in.function_code);
1799
1800		status = dcerpc_netr_LogonControl2(p, tctx, &r);
1801		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1802	}
1803
1804	data.domain = lp_workgroup(tctx->lp_ctx);
1805
1806	r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1807	r.in.data = &data;
1808
1809	for (i=1;i<4;i++) {
1810		r.in.level = i;
1811
1812		torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1813		       i, r.in.function_code);
1814
1815		status = dcerpc_netr_LogonControl2(p, tctx, &r);
1816		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1817	}
1818
1819	data.debug_level = ~0;
1820
1821	r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1822	r.in.data = &data;
1823
1824	for (i=1;i<4;i++) {
1825		r.in.level = i;
1826
1827		torture_comment(tctx, "Testing LogonControl2 level %d function %d\n",
1828		       i, r.in.function_code);
1829
1830		status = dcerpc_netr_LogonControl2(p, tctx, &r);
1831		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1832	}
1833
1834	return true;
1835}
1836
1837/*
1838  try a netlogon DatabaseSync2
1839*/
1840static bool test_DatabaseSync2(struct torture_context *tctx,
1841			       struct dcerpc_pipe *p,
1842			       struct cli_credentials *machine_credentials)
1843{
1844	NTSTATUS status;
1845	struct netr_DatabaseSync2 r;
1846	struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1847	struct netr_Authenticator return_authenticator, credential;
1848
1849	struct netlogon_creds_CredentialState *creds;
1850	const uint32_t database_ids[] = {0, 1, 2};
1851	int i;
1852
1853	if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS,
1854				    machine_credentials,
1855				    cli_credentials_get_secure_channel_type(machine_credentials),
1856				    &creds)) {
1857		return false;
1858	}
1859
1860	ZERO_STRUCT(return_authenticator);
1861
1862	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1863	r.in.computername = TEST_MACHINE_NAME;
1864	r.in.preferredmaximumlength = (uint32_t)-1;
1865	r.in.return_authenticator = &return_authenticator;
1866	r.out.return_authenticator = &return_authenticator;
1867	r.out.delta_enum_array = &delta_enum_array;
1868
1869	for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1870
1871		uint32_t sync_context = 0;
1872
1873		r.in.database_id = database_ids[i];
1874		r.in.sync_context = &sync_context;
1875		r.out.sync_context = &sync_context;
1876		r.in.restart_state = 0;
1877
1878		torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1879
1880		do {
1881			netlogon_creds_client_authenticator(creds, &credential);
1882
1883			r.in.credential = &credential;
1884
1885			status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1886			if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1887			    break;
1888
1889			/* Native mode servers don't do this */
1890			if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1891				return true;
1892			}
1893
1894			torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1895
1896			if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1897				torture_comment(tctx, "Credential chaining failed\n");
1898			}
1899
1900		} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1901	}
1902
1903	return true;
1904}
1905
1906
1907/*
1908  try a netlogon LogonControl2Ex
1909*/
1910static bool test_LogonControl2Ex(struct torture_context *tctx,
1911				 struct dcerpc_pipe *p,
1912				 struct cli_credentials *machine_credentials)
1913
1914{
1915	NTSTATUS status;
1916	struct netr_LogonControl2Ex r;
1917	union netr_CONTROL_DATA_INFORMATION data;
1918	union netr_CONTROL_QUERY_INFORMATION query;
1919	int i;
1920
1921	data.domain = lp_workgroup(tctx->lp_ctx);
1922
1923	r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1924
1925	r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1926	r.in.data = &data;
1927	r.out.query = &query;
1928
1929	for (i=1;i<4;i++) {
1930		r.in.level = i;
1931
1932		torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1933		       i, r.in.function_code);
1934
1935		status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1936		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1937	}
1938
1939	data.domain = lp_workgroup(tctx->lp_ctx);
1940
1941	r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1942	r.in.data = &data;
1943
1944	for (i=1;i<4;i++) {
1945		r.in.level = i;
1946
1947		torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1948		       i, r.in.function_code);
1949
1950		status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1951		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1952	}
1953
1954	data.domain = lp_workgroup(tctx->lp_ctx);
1955
1956	r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1957	r.in.data = &data;
1958
1959	for (i=1;i<4;i++) {
1960		r.in.level = i;
1961
1962		torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1963		       i, r.in.function_code);
1964
1965		status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1966		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1967	}
1968
1969	data.debug_level = ~0;
1970
1971	r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1972	r.in.data = &data;
1973
1974	for (i=1;i<4;i++) {
1975		r.in.level = i;
1976
1977		torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n",
1978		       i, r.in.function_code);
1979
1980		status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1981		torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1982	}
1983
1984	return true;
1985}
1986
1987static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx,
1988						   struct dcerpc_pipe *p, const char *trusted_domain_name)
1989{
1990	NTSTATUS status;
1991	struct netr_DsRGetForestTrustInformation r;
1992	struct lsa_ForestTrustInformation info, *info_ptr;
1993
1994	info_ptr = &info;
1995
1996	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1997	r.in.trusted_domain_name = trusted_domain_name;
1998	r.in.flags = 0;
1999	r.out.forest_trust_info = &info_ptr;
2000
2001	torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2002
2003	status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
2004	torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2005	torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2006
2007	return true;
2008}
2009
2010/*
2011  try a netlogon netr_DsrEnumerateDomainTrusts
2012*/
2013static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx,
2014					  struct dcerpc_pipe *p)
2015{
2016	NTSTATUS status;
2017	struct netr_DsrEnumerateDomainTrusts r;
2018	struct netr_DomainTrustList trusts;
2019	int i;
2020
2021	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2022	r.in.trust_flags = 0x3f;
2023	r.out.trusts = &trusts;
2024
2025	status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
2026	torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2027	torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2028
2029	/* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2030	 * will show non-forest trusts and all UPN suffixes of the own forest
2031	 * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2032
2033	if (r.out.trusts->count) {
2034		if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2035			return false;
2036		}
2037	}
2038
2039	for (i=0; i<r.out.trusts->count; i++) {
2040
2041		/* get info for transitive forest trusts */
2042
2043		if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2044			if (!test_netr_DsRGetForestTrustInformation(tctx, p,
2045								    r.out.trusts->array[i].dns_name)) {
2046				return false;
2047			}
2048		}
2049	}
2050
2051	return true;
2052}
2053
2054static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2055						  struct dcerpc_pipe *p)
2056{
2057	NTSTATUS status;
2058	struct netr_NetrEnumerateTrustedDomains r;
2059	struct netr_Blob trusted_domains_blob;
2060
2061	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2062	r.out.trusted_domains_blob = &trusted_domains_blob;
2063
2064	status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
2065	torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2066	torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2067
2068	return true;
2069}
2070
2071static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2072						    struct dcerpc_pipe *p)
2073{
2074	NTSTATUS status;
2075	struct netr_NetrEnumerateTrustedDomainsEx r;
2076	struct netr_DomainTrustList dom_trust_list;
2077
2078	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2079	r.out.dom_trust_list = &dom_trust_list;
2080
2081	status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
2082	torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2083	torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2084
2085	return true;
2086}
2087
2088
2089static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2090				     const char *computer_name,
2091				     const char *expected_site)
2092{
2093	NTSTATUS status;
2094	struct netr_DsRGetSiteName r;
2095	const char *site = NULL;
2096
2097	if (torture_setting_bool(tctx, "samba4", false))
2098		torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
2099
2100	r.in.computer_name		= computer_name;
2101	r.out.site			= &site;
2102	torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2103
2104	status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2105	torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2106	torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2107	torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2108
2109	r.in.computer_name		= talloc_asprintf(tctx, "\\\\%s", computer_name);
2110	torture_comment(tctx,
2111			"Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2112
2113	status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
2114	torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2115	torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2116
2117	return true;
2118}
2119
2120/*
2121  try a netlogon netr_DsRGetDCName
2122*/
2123static bool test_netr_DsRGetDCName(struct torture_context *tctx,
2124				   struct dcerpc_pipe *p)
2125{
2126	NTSTATUS status;
2127	struct netr_DsRGetDCName r;
2128	struct netr_DsRGetDCNameInfo *info = NULL;
2129
2130	r.in.server_unc		= talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2131	r.in.domain_name	= talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
2132	r.in.domain_guid	= NULL;
2133	r.in.site_guid	        = NULL;
2134	r.in.flags		= DS_RETURN_DNS_NAME;
2135	r.out.info		= &info;
2136
2137	status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
2138	torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2139	torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2140	return test_netr_DsRGetSiteName(p, tctx,
2141				       info->dc_unc,
2142				       info->dc_site_name);
2143}
2144
2145/*
2146  try a netlogon netr_DsRGetDCNameEx
2147*/
2148static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx,
2149				     struct dcerpc_pipe *p)
2150{
2151	NTSTATUS status;
2152	struct netr_DsRGetDCNameEx r;
2153	struct netr_DsRGetDCNameInfo *info = NULL;
2154
2155	r.in.server_unc		= talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2156	r.in.domain_name	= talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
2157	r.in.domain_guid	= NULL;
2158	r.in.site_name	        = NULL;
2159	r.in.flags		= DS_RETURN_DNS_NAME;
2160	r.out.info		= &info;
2161
2162	status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
2163	torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2164	torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2165
2166	return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2167				        info->dc_site_name);
2168}
2169
2170/*
2171  try a netlogon netr_DsRGetDCNameEx2
2172*/
2173static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx,
2174				      struct dcerpc_pipe *p)
2175{
2176	NTSTATUS status;
2177	struct netr_DsRGetDCNameEx2 r;
2178	struct netr_DsRGetDCNameInfo *info = NULL;
2179
2180	r.in.server_unc		= talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2181	r.in.client_account	= NULL;
2182	r.in.mask		= 0x00000000;
2183	r.in.domain_name	= talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
2184	r.in.domain_guid	= NULL;
2185	r.in.site_name		= NULL;
2186	r.in.flags		= DS_RETURN_DNS_NAME;
2187	r.out.info		= &info;
2188
2189	torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2190
2191	status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2192	torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2193	torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2194
2195	torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
2196	r.in.client_account	= TEST_MACHINE_NAME"$";
2197	r.in.mask		= ACB_SVRTRUST;
2198	r.in.flags		= DS_RETURN_FLAT_NAME;
2199	r.out.info		= &info;
2200
2201	status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
2202	torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2203	torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2204	return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2205					info->dc_site_name);
2206}
2207
2208static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx,
2209					    struct dcerpc_pipe *p)
2210{
2211	NTSTATUS status;
2212	struct netr_DsrGetDcSiteCoverageW r;
2213	struct DcSitesCtr *ctr = NULL;
2214
2215	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2216	r.out.ctr = &ctr;
2217
2218	status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
2219	torture_assert_ntstatus_ok(tctx, status, "failed");
2220	torture_assert_werr_ok(tctx, r.out.result, "failed");
2221
2222	return true;
2223}
2224
2225static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2226					     struct dcerpc_pipe *p)
2227{
2228	NTSTATUS status;
2229	struct netr_DsRAddressToSitenamesW r;
2230	struct netr_DsRAddress addr;
2231	struct netr_DsRAddressToSitenamesWCtr *ctr;
2232
2233	ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2234
2235	addr.size = 16;
2236	addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2237
2238	addr.buffer[0] = 2; /* AF_INET */
2239	addr.buffer[4] = 127;
2240	addr.buffer[5] = 0;
2241	addr.buffer[6] = 0;
2242	addr.buffer[7] = 1;
2243
2244	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2245	r.in.count = 1;
2246	r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
2247	r.in.addresses[0] = addr;
2248	r.out.ctr = &ctr;
2249
2250	status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
2251	torture_assert_ntstatus_ok(tctx, status, "failed");
2252	torture_assert_werr_ok(tctx, r.out.result, "failed");
2253
2254	return true;
2255}
2256
2257static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2258					       struct dcerpc_pipe *p)
2259{
2260	NTSTATUS status;
2261	struct netr_DsRAddressToSitenamesExW r;
2262	struct netr_DsRAddress addr;
2263	struct netr_DsRAddressToSitenamesExWCtr *ctr;
2264
2265	ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2266
2267	addr.size = 16;
2268	addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
2269
2270	addr.buffer[0] = 2; /* AF_INET */
2271	addr.buffer[4] = 127;
2272	addr.buffer[5] = 0;
2273	addr.buffer[6] = 0;
2274	addr.buffer[7] = 1;
2275
2276	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2277	r.in.count = 1;
2278	r.in.addresses = talloc_zero_array(tctx, struct	netr_DsRAddress, r.in.count);
2279	r.in.addresses[0] = addr;
2280	r.out.ctr = &ctr;
2281
2282	status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
2283	torture_assert_ntstatus_ok(tctx, status, "failed");
2284	torture_assert_werr_ok(tctx, r.out.result, "failed");
2285
2286	return true;
2287}
2288
2289static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2290					 struct dcerpc_pipe *p,
2291					 struct cli_credentials *machine_credentials)
2292{
2293	NTSTATUS status;
2294	struct netr_ServerGetTrustInfo r;
2295
2296	struct netr_Authenticator a;
2297	struct netr_Authenticator return_authenticator;
2298	struct samr_Password new_owf_password;
2299	struct samr_Password old_owf_password;
2300	struct netr_TrustInfo *trust_info;
2301
2302	struct netlogon_creds_CredentialState *creds;
2303
2304	if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2305				    machine_credentials, &creds)) {
2306		return false;
2307	}
2308
2309	netlogon_creds_client_authenticator(creds, &a);
2310
2311	r.in.server_name		= talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2312	r.in.account_name		= talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2313	r.in.secure_channel_type	= cli_credentials_get_secure_channel_type(machine_credentials);
2314	r.in.computer_name		= TEST_MACHINE_NAME;
2315	r.in.credential			= &a;
2316
2317	r.out.return_authenticator	= &return_authenticator;
2318	r.out.new_owf_password		= &new_owf_password;
2319	r.out.old_owf_password		= &old_owf_password;
2320	r.out.trust_info		= &trust_info;
2321
2322	status = dcerpc_netr_ServerGetTrustInfo(p, tctx, &r);
2323	torture_assert_ntstatus_ok(tctx, status, "failed");
2324	torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2325
2326	return true;
2327}
2328
2329
2330static bool test_GetDomainInfo(struct torture_context *tctx,
2331			       struct dcerpc_pipe *p,
2332			       struct cli_credentials *machine_credentials)
2333{
2334	NTSTATUS status;
2335	struct netr_LogonGetDomainInfo r;
2336	struct netr_WorkstationInformation q1;
2337	struct netr_Authenticator a;
2338	struct netlogon_creds_CredentialState *creds;
2339	struct netr_OsVersion os;
2340	union netr_WorkstationInfo query;
2341	union netr_DomainInfo info;
2342	const char* const attrs[] = { "dNSHostName", "operatingSystem",
2343		"operatingSystemServicePack", "operatingSystemVersion",
2344		"servicePrincipalName", NULL };
2345	char *url;
2346	struct ldb_context *sam_ctx = NULL;
2347	struct ldb_message **res;
2348	struct ldb_message_element *spn_el;
2349	int ret, i;
2350	char *version_str;
2351	const char *old_dnsname = NULL;
2352	char **spns = NULL;
2353	int num_spns = 0;
2354	char *temp_str;
2355
2356	torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
2357
2358	if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2359				    machine_credentials, &creds)) {
2360		return false;
2361	}
2362
2363	/* We won't double-check this when we are over 'local' transports */
2364	if (dcerpc_server_name(p)) {
2365		/* Set up connection to SAMDB on DC */
2366		url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2367		sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2368					   NULL,
2369					   cmdline_credentials,
2370					   0, NULL);
2371
2372		torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2373	}
2374
2375	torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
2376	netlogon_creds_client_authenticator(creds, &a);
2377
2378	ZERO_STRUCT(r);
2379	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2380	r.in.computer_name = TEST_MACHINE_NAME;
2381	r.in.credential = &a;
2382	r.in.level = 1;
2383	r.in.return_authenticator = &a;
2384	r.in.query = &query;
2385	r.out.return_authenticator = &a;
2386	r.out.info = &info;
2387
2388	ZERO_STRUCT(os);
2389	os.os.MajorVersion = 123;
2390	os.os.MinorVersion = 456;
2391	os.os.BuildNumber = 789;
2392	os.os.CSDVersion = "Service Pack 10";
2393	os.os.ServicePackMajor = 10;
2394	os.os.ServicePackMinor = 1;
2395	os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
2396	os.os.ProductType = NETR_VER_NT_SERVER;
2397	os.os.Reserved = 0;
2398
2399	version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
2400		os.os.MinorVersion, os.os.BuildNumber);
2401
2402	ZERO_STRUCT(q1);
2403	q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2404		TEST_MACHINE_DNS_SUFFIX);
2405	q1.sitename = "Default-First-Site-Name";
2406	q1.os_version.os = &os;
2407	q1.os_name.string = talloc_asprintf(tctx,
2408					    "Tortured by Samba4 RPC-NETLOGON: %s",
2409					    timestring(tctx, time(NULL)));
2410
2411	/* The workstation handles the "servicePrincipalName" and DNS hostname
2412	   updates */
2413	q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2414
2415	query.workstation_info = &q1;
2416
2417	if (sam_ctx) {
2418		/* Gets back the old DNS hostname in AD */
2419		ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2420				   "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2421		old_dnsname =
2422			ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
2423
2424		/* Gets back the "servicePrincipalName"s in AD */
2425		spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2426		if (spn_el != NULL) {
2427			for (i=0; i < spn_el->num_values; i++) {
2428				spns = talloc_realloc(tctx, spns, char *, i + 1);
2429				spns[i] = (char *) spn_el->values[i].data;
2430			}
2431			num_spns = i;
2432		}
2433	}
2434
2435	status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2436	torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2437	torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2438
2439	msleep(250);
2440
2441	if (sam_ctx) {
2442		/* AD workstation infos entry check */
2443		ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2444				   "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2445		torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2446		torture_assert_str_equal(tctx,
2447					 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2448					 q1.os_name.string, "'operatingSystem' wrong!");
2449		torture_assert_str_equal(tctx,
2450					 ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
2451					 os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
2452		torture_assert_str_equal(tctx,
2453					 ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
2454					 version_str, "'operatingSystemVersion' wrong!");
2455
2456		if (old_dnsname != NULL) {
2457			/* If before a DNS hostname was set then it should remain
2458			   the same in combination with the "servicePrincipalName"s.
2459			   The DNS hostname should also be returned by our
2460			   "LogonGetDomainInfo" call (in the domain info structure). */
2461
2462			torture_assert_str_equal(tctx,
2463						 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2464						 old_dnsname, "'DNS hostname' was not set!");
2465
2466			spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2467			torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
2468				       "'servicePrincipalName's not set!");
2469			torture_assert(tctx, spn_el->num_values == num_spns,
2470				       "'servicePrincipalName's incorrect!");
2471			for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
2472				torture_assert_str_equal(tctx,
2473							 (char *) spn_el->values[i].data,
2474				spns[i], "'servicePrincipalName's incorrect!");
2475
2476			torture_assert_str_equal(tctx,
2477						 info.domain_info->dns_hostname.string,
2478						 old_dnsname,
2479						 "Out 'DNS hostname' doesn't match the old one!");
2480		} else {
2481			/* If no DNS hostname was set then also now none should be set,
2482			   the "servicePrincipalName"s should remain empty and no DNS
2483			   hostname should be returned by our "LogonGetDomainInfo"
2484			   call (in the domain info structure). */
2485
2486			torture_assert(tctx,
2487				       ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
2488				       "'DNS hostname' was set!");
2489
2490			spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2491			torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
2492				       "'servicePrincipalName's were set!");
2493
2494			torture_assert(tctx,
2495				       info.domain_info->dns_hostname.string == NULL,
2496				       "Out 'DNS host name' was set!");
2497		}
2498	}
2499
2500	/* Checks "workstation flags" */
2501	torture_assert(tctx,
2502		info.domain_info->workstation_flags
2503		== NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2504		"Out 'workstation flags' don't match!");
2505
2506
2507	torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname)\n");
2508	netlogon_creds_client_authenticator(creds, &a);
2509
2510	/* Wipe out the osVersion, and prove which values still 'stick' */
2511	q1.os_version.os = NULL;
2512
2513	/* Change also the DNS hostname to test differences in behaviour */
2514	q1.dns_hostname = talloc_asprintf(tctx, "%s.newdomain",
2515		TEST_MACHINE_NAME);
2516
2517	/* Let the DC handle the "servicePrincipalName" and DNS hostname
2518	   updates */
2519	q1.workstation_flags = 0;
2520
2521	status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2522	torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2523	torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2524
2525	msleep(250);
2526
2527	if (sam_ctx) {
2528		/* AD workstation infos entry check */
2529		ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
2530				   "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
2531		torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
2532		torture_assert_str_equal(tctx,
2533					 ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
2534					 q1.os_name.string, "'operatingSystem' should stick!");
2535		torture_assert(tctx,
2536			       ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
2537			       "'operatingSystemServicePack' shouldn't stick!");
2538		torture_assert(tctx,
2539			       ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
2540			       "'operatingSystemVersion' shouldn't stick!");
2541
2542		/* The DNS host name should have been updated now by the server */
2543		torture_assert_str_equal(tctx,
2544					 ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
2545					 q1.dns_hostname, "'DNS host name' didn't change!");
2546
2547		/* Find the two "servicePrincipalName"s which the DC should have been
2548		   updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
2549		   3.5.4.3.9 */
2550		spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
2551		torture_assert(tctx, spn_el != NULL,
2552			       "There should exist 'servicePrincipalName's in AD!");
2553		temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
2554		for (i=0; i < spn_el->num_values; i++)
2555			if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2556				break;
2557		torture_assert(tctx, i != spn_el->num_values,
2558			       "'servicePrincipalName' HOST/<Netbios name> not found!");
2559		temp_str = talloc_asprintf(tctx, "HOST/%s", q1.dns_hostname);
2560		for (i=0; i < spn_el->num_values; i++)
2561			if (strcmp((char *) spn_el->values[i].data, temp_str) == 0)
2562				break;
2563		torture_assert(tctx, i != spn_el->num_values,
2564			       "'servicePrincipalName' HOST/<FQDN name> not found!");
2565
2566		/* Check that the out DNS hostname was set properly */
2567		torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
2568					 old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
2569	}
2570
2571	/* Checks "workstation flags" */
2572	torture_assert(tctx,
2573		info.domain_info->workstation_flags == 0,
2574		"Out 'workstation flags' don't match!");
2575
2576
2577	torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (verification of DNS hostname and check for trusted domains)\n");
2578	netlogon_creds_client_authenticator(creds, &a);
2579
2580	/* The workstation handles the "servicePrincipalName" and DNS hostname
2581	   updates */
2582	q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
2583
2584	status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2585	torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2586	torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2587
2588	msleep(250);
2589
2590	/* Now the in/out DNS hostnames should be the same */
2591	torture_assert_str_equal(tctx,
2592		info.domain_info->dns_hostname.string,
2593		query.workstation_info->dns_hostname,
2594		"In/Out 'DNS hostnames' don't match!");
2595
2596	/* Checks "workstation flags" */
2597	torture_assert(tctx,
2598		info.domain_info->workstation_flags
2599		== NETR_WS_FLAG_HANDLES_SPN_UPDATE,
2600		"Out 'workstation flags' don't match!");
2601
2602	/* Checks for trusted domains */
2603	torture_assert(tctx,
2604		(info.domain_info->trusted_domain_count != 0)
2605		&& (info.domain_info->trusted_domains != NULL),
2606		"Trusted domains have been requested!");
2607
2608
2609	torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (check for trusted domains)\n");
2610	netlogon_creds_client_authenticator(creds, &a);
2611
2612	/* The workstation handles the "servicePrincipalName" and DNS hostname
2613	   updates and requests inbound trusts */
2614	q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
2615		| NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
2616
2617	status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
2618	torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
2619	torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
2620
2621	msleep(250);
2622
2623	/* Checks "workstation flags" */
2624	torture_assert(tctx,
2625		info.domain_info->workstation_flags
2626		== (NETR_WS_FLAG_HANDLES_SPN_UPDATE
2627			| NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
2628		"Out 'workstation flags' don't match!");
2629
2630	/* Checks for trusted domains */
2631	torture_assert(tctx,
2632		(info.domain_info->trusted_domain_count != 0)
2633		&& (info.domain_info->trusted_domains != NULL),
2634		"Trusted domains have been requested!");
2635
2636	return true;
2637}
2638
2639
2640static void async_callback(struct rpc_request *req)
2641{
2642	int *counter = (int *)req->async.private_data;
2643	if (NT_STATUS_IS_OK(req->status)) {
2644		(*counter)++;
2645	}
2646}
2647
2648static bool test_GetDomainInfo_async(struct torture_context *tctx,
2649				     struct dcerpc_pipe *p,
2650				     struct cli_credentials *machine_credentials)
2651{
2652	NTSTATUS status;
2653	struct netr_LogonGetDomainInfo r;
2654	struct netr_WorkstationInformation q1;
2655	struct netr_Authenticator a;
2656#define ASYNC_COUNT 100
2657	struct netlogon_creds_CredentialState *creds;
2658	struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
2659	struct rpc_request *req[ASYNC_COUNT];
2660	int i;
2661	int *async_counter = talloc(tctx, int);
2662	union netr_WorkstationInfo query;
2663	union netr_DomainInfo info;
2664
2665	torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
2666
2667	if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2668				    machine_credentials, &creds)) {
2669		return false;
2670	}
2671
2672	ZERO_STRUCT(r);
2673	r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2674	r.in.computer_name = TEST_MACHINE_NAME;
2675	r.in.credential = &a;
2676	r.in.level = 1;
2677	r.in.return_authenticator = &a;
2678	r.in.query = &query;
2679	r.out.return_authenticator = &a;
2680	r.out.info = &info;
2681
2682	ZERO_STRUCT(q1);
2683	q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
2684		TEST_MACHINE_DNS_SUFFIX);
2685	q1.sitename = "Default-First-Site-Name";
2686	q1.os_name.string = "UNIX/Linux or similar";
2687
2688	query.workstation_info = &q1;
2689
2690	*async_counter = 0;
2691
2692	for (i=0;i<ASYNC_COUNT;i++) {
2693		netlogon_creds_client_authenticator(creds, &a);
2694
2695		creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
2696		req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
2697
2698		req[i]->async.callback = async_callback;
2699		req[i]->async.private_data = async_counter;
2700
2701		/* even with this flush per request a w2k3 server seems to
2702		   clag with multiple outstanding requests. bleergh. */
2703		torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0,
2704					 "event_loop_once failed");
2705	}
2706
2707	for (i=0;i<ASYNC_COUNT;i++) {
2708		status = dcerpc_ndr_request_recv(req[i]);
2709
2710		torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
2711		torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async");
2712
2713		torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred),
2714			"Credential chaining failed at async");
2715	}
2716
2717	torture_comment(tctx,
2718			"Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
2719
2720	torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
2721
2722	return true;
2723}
2724
2725static bool test_ManyGetDCName(struct torture_context *tctx,
2726			       struct dcerpc_pipe *p)
2727{
2728	NTSTATUS status;
2729	struct dcerpc_pipe *p2;
2730	struct lsa_ObjectAttribute attr;
2731	struct lsa_QosInfo qos;
2732	struct lsa_OpenPolicy2 o;
2733	struct policy_handle lsa_handle;
2734	struct lsa_DomainList domains;
2735
2736	struct lsa_EnumTrustDom t;
2737	uint32_t resume_handle = 0;
2738	struct netr_GetAnyDCName d;
2739	const char *dcname = NULL;
2740
2741	int i;
2742
2743	if (p->conn->transport.transport != NCACN_NP) {
2744		return true;
2745	}
2746
2747	torture_comment(tctx, "Torturing GetDCName\n");
2748
2749	status = dcerpc_secondary_connection(p, &p2, p->binding);
2750	torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
2751
2752	status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
2753	torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
2754
2755	qos.len = 0;
2756	qos.impersonation_level = 2;
2757	qos.context_mode = 1;
2758	qos.effective_only = 0;
2759
2760	attr.len = 0;
2761	attr.root_dir = NULL;
2762	attr.object_name = NULL;
2763	attr.attributes = 0;
2764	attr.sec_desc = NULL;
2765	attr.sec_qos = &qos;
2766
2767	o.in.system_name = "\\";
2768	o.in.attr = &attr;
2769	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2770	o.out.handle = &lsa_handle;
2771
2772	status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
2773	torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
2774
2775	t.in.handle = &lsa_handle;
2776	t.in.resume_handle = &resume_handle;
2777	t.in.max_size = 1000;
2778	t.out.domains = &domains;
2779	t.out.resume_handle = &resume_handle;
2780
2781	status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
2782
2783	if ((!NT_STATUS_IS_OK(status) &&
2784	     (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
2785		torture_fail(tctx, "Could not list domains");
2786
2787	talloc_free(p2);
2788
2789	d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
2790					    dcerpc_server_name(p));
2791	d.out.dcname = &dcname;
2792
2793	for (i=0; i<domains.count * 4; i++) {
2794		struct lsa_DomainInfo *info =
2795			&domains.domains[rand()%domains.count];
2796
2797		d.in.domainname = info->name.string;
2798
2799		status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
2800		torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
2801
2802		torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
2803		       dcname ? dcname : "unknown");
2804	}
2805
2806	return true;
2807}
2808
2809static bool test_SetPassword_with_flags(struct torture_context *tctx,
2810					struct dcerpc_pipe *p,
2811					struct cli_credentials *machine_credentials)
2812{
2813	uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
2814	struct netlogon_creds_CredentialState *creds;
2815	int i;
2816
2817	if (!test_SetupCredentials2(p, tctx, 0,
2818				    machine_credentials,
2819				    cli_credentials_get_secure_channel_type(machine_credentials),
2820				    &creds)) {
2821		torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
2822	}
2823
2824	for (i=0; i < ARRAY_SIZE(flags); i++) {
2825		torture_assert(tctx,
2826			test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
2827			talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
2828	}
2829
2830	return true;
2831}
2832
2833struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
2834{
2835	struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
2836	struct torture_rpc_tcase *tcase;
2837	struct torture_test *test;
2838
2839	tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2840						  &ndr_table_netlogon, TEST_MACHINE_NAME);
2841
2842	torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
2843	torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
2844	torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2845	torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2846	torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2847	torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
2848	torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
2849	torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
2850	torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
2851	torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
2852	torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
2853	torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
2854	torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
2855	torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
2856	torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
2857	torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
2858	torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
2859	torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
2860	torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2861	torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
2862	test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
2863	test->dangerous = true;
2864	torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
2865	torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
2866	torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
2867	torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
2868	torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
2869	torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
2870	torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
2871
2872	return suite;
2873}
2874
2875struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
2876{
2877	struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-S3");
2878	struct torture_rpc_tcase *tcase;
2879
2880	tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2881						  &ndr_table_netlogon, TEST_MACHINE_NAME);
2882
2883	torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
2884	torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
2885	torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
2886	torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
2887	torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
2888
2889	return suite;
2890}
2891
2892struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
2893{
2894	struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON-ADMIN");
2895	struct torture_rpc_tcase *tcase;
2896
2897	tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
2898						  &ndr_table_netlogon, TEST_MACHINE_NAME);
2899	torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2900	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2901	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2902
2903	tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
2904						  &ndr_table_netlogon, TEST_MACHINE_NAME);
2905	torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2906	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2907	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2908
2909	tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
2910						  &ndr_table_netlogon);
2911	torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
2912	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
2913	torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
2914
2915	return suite;
2916}
2917