s4-smbtorture: fix test_LogonUasLogon.
[ira/wip.git] / source4 / torture / rpc / netlogon.c
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    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "torture/torture.h"
26 #include "lib/events/events.h"
27 #include "auth/auth.h"
28 #include "auth/gensec/gensec.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "torture/rpc/rpc.h"
31 #include "torture/rpc/netlogon.h"
32 #include "../lib/crypto/crypto.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "librpc/gen_ndr/ndr_netlogon_c.h"
35 #include "librpc/gen_ndr/ndr_lsa_c.h"
36 #include "param/param.h"
37
38 #define TEST_MACHINE_NAME "torturetest"
39
40 static bool test_LogonUasLogon(struct torture_context *tctx, 
41                                struct dcerpc_pipe *p)
42 {
43         NTSTATUS status;
44         struct netr_LogonUasLogon r;
45         struct netr_UasInfo *info = NULL;
46
47         r.in.server_name = NULL;
48         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
49         r.in.workstation = TEST_MACHINE_NAME;
50         r.out.info = &info;
51
52         status = dcerpc_netr_LogonUasLogon(p, tctx, &r);
53         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
54
55         return true;
56 }
57
58 static bool test_LogonUasLogoff(struct torture_context *tctx,
59                                 struct dcerpc_pipe *p)
60 {
61         NTSTATUS status;
62         struct netr_LogonUasLogoff r;
63
64         r.in.server_name = NULL;
65         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
66         r.in.workstation = TEST_MACHINE_NAME;
67
68         status = dcerpc_netr_LogonUasLogoff(p, tctx, &r);
69         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
70
71         return true;
72 }
73
74 static bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
75                                   struct cli_credentials *credentials,
76                                   struct creds_CredentialState **creds_out)
77 {
78         NTSTATUS status;
79         struct netr_ServerReqChallenge r;
80         struct netr_ServerAuthenticate a;
81         struct netr_Credential credentials1, credentials2, credentials3;
82         struct creds_CredentialState *creds;
83         const struct samr_Password *mach_password;
84         const char *machine_name;
85
86         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
87         machine_name = cli_credentials_get_workstation(credentials);
88
89         torture_comment(tctx, "Testing ServerReqChallenge\n");
90
91         creds = talloc(tctx, struct creds_CredentialState);
92         torture_assert(tctx, creds != NULL, "memory allocation");
93
94         r.in.server_name = NULL;
95         r.in.computer_name = machine_name;
96         r.in.credentials = &credentials1;
97         r.out.credentials = &credentials2;
98
99         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
100
101         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
102         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
103
104         a.in.server_name = NULL;
105         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
106         a.in.secure_channel_type = SEC_CHAN_BDC;
107         a.in.computer_name = machine_name;
108         a.in.credentials = &credentials3;
109         a.out.credentials = &credentials3;
110
111         creds_client_init(creds, &credentials1, &credentials2, 
112                           mach_password, &credentials3, 
113                           0);
114
115         torture_comment(tctx, "Testing ServerAuthenticate\n");
116
117         status = dcerpc_netr_ServerAuthenticate(p, tctx, &a);
118
119         /* This allows the tests to continue against the more fussy windows 2008 */
120         if (NT_STATUS_EQUAL(status, NT_STATUS_DOWNGRADE_DETECTED)) {
121                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
122                                               credentials, SEC_CHAN_BDC, creds_out);
123         }
124
125         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate");
126
127         torture_assert(tctx, creds_client_check(creds, &credentials3), 
128                        "Credential chaining failed");
129
130         *creds_out = creds;
131         return true;
132 }
133
134 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
135                             uint32_t negotiate_flags,
136                             struct cli_credentials *machine_credentials,
137                             int sec_chan_type,
138                             struct creds_CredentialState **creds_out)
139 {
140         NTSTATUS status;
141         struct netr_ServerReqChallenge r;
142         struct netr_ServerAuthenticate2 a;
143         struct netr_Credential credentials1, credentials2, credentials3;
144         struct creds_CredentialState *creds;
145         const struct samr_Password *mach_password;
146         const char *machine_name;
147         const char *plain_pass;
148
149         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
150         machine_name = cli_credentials_get_workstation(machine_credentials);
151
152         torture_comment(tctx, "Testing ServerReqChallenge\n");
153
154         creds = talloc(tctx, struct creds_CredentialState);
155         torture_assert(tctx, creds != NULL, "memory allocation");
156
157         r.in.server_name = NULL;
158         r.in.computer_name = machine_name;
159         r.in.credentials = &credentials1;
160         r.out.credentials = &credentials2;
161
162         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
163
164         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
165         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
166
167         a.in.server_name = NULL;
168         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
169         a.in.secure_channel_type = sec_chan_type;
170         a.in.computer_name = machine_name;
171         a.in.negotiate_flags = &negotiate_flags;
172         a.out.negotiate_flags = &negotiate_flags;
173         a.in.credentials = &credentials3;
174         a.out.credentials = &credentials3;
175
176         creds_client_init(creds, &credentials1, &credentials2, 
177                           mach_password, &credentials3, 
178                           negotiate_flags);
179
180         torture_comment(tctx, "Testing ServerAuthenticate2\n");
181
182         status = dcerpc_netr_ServerAuthenticate2(p, tctx, &a);
183         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate2");
184
185         torture_assert(tctx, creds_client_check(creds, &credentials3), 
186                 "Credential chaining failed");
187
188         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
189
190         *creds_out = creds;
191         return true;
192 }
193
194
195 static bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
196                             uint32_t negotiate_flags,
197                             struct cli_credentials *machine_credentials,
198                             struct creds_CredentialState **creds_out)
199 {
200         NTSTATUS status;
201         struct netr_ServerReqChallenge r;
202         struct netr_ServerAuthenticate3 a;
203         struct netr_Credential credentials1, credentials2, credentials3;
204         struct creds_CredentialState *creds;
205         struct samr_Password mach_password;
206         uint32_t rid;
207         const char *machine_name;
208         const char *plain_pass;
209
210         machine_name = cli_credentials_get_workstation(machine_credentials);
211         plain_pass = cli_credentials_get_password(machine_credentials);
212
213         torture_comment(tctx, "Testing ServerReqChallenge\n");
214
215         creds = talloc(tctx, struct creds_CredentialState);
216         torture_assert(tctx, creds != NULL, "memory allocation");
217
218         r.in.server_name = NULL;
219         r.in.computer_name = machine_name;
220         r.in.credentials = &credentials1;
221         r.out.credentials = &credentials2;
222
223         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
224
225         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
226         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
227
228         E_md4hash(plain_pass, mach_password.hash);
229
230         a.in.server_name = NULL;
231         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
232         a.in.secure_channel_type = SEC_CHAN_BDC;
233         a.in.computer_name = machine_name;
234         a.in.negotiate_flags = &negotiate_flags;
235         a.in.credentials = &credentials3;
236         a.out.credentials = &credentials3;
237         a.out.negotiate_flags = &negotiate_flags;
238         a.out.rid = &rid;
239
240         creds_client_init(creds, &credentials1, &credentials2, 
241                           &mach_password, &credentials3,
242                           negotiate_flags);
243
244         torture_comment(tctx, "Testing ServerAuthenticate3\n");
245
246         status = dcerpc_netr_ServerAuthenticate3(p, tctx, &a);
247         torture_assert_ntstatus_ok(tctx, status, "ServerAuthenticate3");
248         torture_assert(tctx, creds_client_check(creds, &credentials3), "Credential chaining failed");
249
250         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
251         
252         /* Prove that requesting a challenge again won't break it */
253         status = dcerpc_netr_ServerReqChallenge(p, tctx, &r);
254         torture_assert_ntstatus_ok(tctx, status, "ServerReqChallenge");
255
256         *creds_out = creds;
257         return true;
258 }
259
260 /*
261   try a change password for our machine account
262 */
263 static bool test_SetPassword(struct torture_context *tctx, 
264                              struct dcerpc_pipe *p,
265                              struct cli_credentials *machine_credentials)
266 {
267         NTSTATUS status;
268         struct netr_ServerPasswordSet r;
269         const char *password;
270         struct creds_CredentialState *creds;
271
272         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
273                 return false;
274         }
275
276         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
277         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
278         r.in.secure_channel_type = SEC_CHAN_BDC;
279         r.in.computer_name = TEST_MACHINE_NAME;
280
281         password = generate_random_str(tctx, 8);
282         E_md4hash(password, r.in.new_password.hash);
283
284         creds_des_encrypt(creds, &r.in.new_password);
285
286         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
287         torture_comment(tctx, "Changing machine account password to '%s'\n", 
288                         password);
289
290         creds_client_authenticator(creds, &r.in.credential);
291
292         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
293         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet");
294
295         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
296                 torture_comment(tctx, "Credential chaining failed\n");
297         }
298
299         /* by changing the machine password twice we test the
300            credentials chaining fully, and we verify that the server
301            allows the password to be set to the same value twice in a
302            row (match win2k3) */
303         torture_comment(tctx, 
304                 "Testing a second ServerPasswordSet on machine account\n");
305         torture_comment(tctx, 
306                 "Changing machine account password to '%s' (same as previous run)\n", password);
307
308         creds_client_authenticator(creds, &r.in.credential);
309
310         status = dcerpc_netr_ServerPasswordSet(p, tctx, &r);
311         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (2)");
312
313         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
314                 torture_comment(tctx, "Credential chaining failed\n");
315         }
316
317         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
318
319         torture_assert(tctx, 
320                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
321                 "ServerPasswordSet failed to actually change the password");
322
323         return true;
324 }
325
326 /*
327   generate a random password for password change tests
328 */
329 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
330 {
331         int i;
332         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
333         generate_random_buffer(password.data, password.length);
334
335         for (i=0; i < len; i++) {
336                 if (((uint16_t *)password.data)[i] == 0) {
337                         ((uint16_t *)password.data)[i] = 1;
338                 }
339         }
340
341         return password;
342 }
343
344 /*
345   try a change password for our machine account
346 */
347 static bool test_SetPassword2(struct torture_context *tctx, 
348                               struct dcerpc_pipe *p, 
349                               struct cli_credentials *machine_credentials)
350 {
351         NTSTATUS status;
352         struct netr_ServerPasswordSet2 r;
353         const char *password;
354         DATA_BLOB new_random_pass;
355         struct creds_CredentialState *creds;
356         struct samr_CryptPassword password_buf;
357         struct samr_Password nt_hash;
358
359         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
360                 return false;
361         }
362
363         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
364         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
365         r.in.secure_channel_type = SEC_CHAN_BDC;
366         r.in.computer_name = TEST_MACHINE_NAME;
367
368         password = generate_random_str(tctx, 8);
369         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
370         creds_arcfour_crypt(creds, password_buf.data, 516);
371
372         memcpy(r.in.new_password.data, password_buf.data, 512);
373         r.in.new_password.length = IVAL(password_buf.data, 512);
374
375         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
376         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
377
378         creds_client_authenticator(creds, &r.in.credential);
379
380         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
381         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
382
383         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
384                 torture_comment(tctx, "Credential chaining failed\n");
385         }
386
387         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
388
389         if (!torture_setting_bool(tctx, "dangerous", false)) {
390                 torture_comment(tctx, 
391                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
392         } else {
393                 /* by changing the machine password to ""
394                  * we check if the server uses password restrictions
395                  * for ServerPasswordSet2
396                  * (win2k3 accepts "")
397                  */
398                 password = "";
399                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
400                 creds_arcfour_crypt(creds, password_buf.data, 516);
401                 
402                 memcpy(r.in.new_password.data, password_buf.data, 512);
403                 r.in.new_password.length = IVAL(password_buf.data, 512);
404                 
405                 torture_comment(tctx, 
406                         "Testing ServerPasswordSet2 on machine account\n");
407                 torture_comment(tctx, 
408                         "Changing machine account password to '%s'\n", password);
409                 
410                 creds_client_authenticator(creds, &r.in.credential);
411                 
412                 status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
413                 torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2");
414                 
415                 if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
416                         torture_comment(tctx, "Credential chaining failed\n");
417                 }
418                 
419                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
420         }
421
422         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds), 
423                 "ServerPasswordSet failed to actually change the password");
424
425         /* now try a random password */
426         password = generate_random_str(tctx, 8);
427         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
428         creds_arcfour_crypt(creds, password_buf.data, 516);
429
430         memcpy(r.in.new_password.data, password_buf.data, 512);
431         r.in.new_password.length = IVAL(password_buf.data, 512);
432
433         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
434         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
435
436         creds_client_authenticator(creds, &r.in.credential);
437
438         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
439         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet2 (2)");
440
441         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
442                 torture_comment(tctx, "Credential chaining failed\n");
443         }
444
445         /* by changing the machine password twice we test the
446            credentials chaining fully, and we verify that the server
447            allows the password to be set to the same value twice in a
448            row (match win2k3) */
449         torture_comment(tctx, 
450                 "Testing a second ServerPasswordSet2 on machine account\n");
451         torture_comment(tctx, 
452                 "Changing machine account password to '%s' (same as previous run)\n", password);
453
454         creds_client_authenticator(creds, &r.in.credential);
455
456         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
457         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
458
459         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
460                 torture_comment(tctx, "Credential chaining failed\n");
461         }
462
463         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
464
465         torture_assert (tctx, 
466                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
467                 "ServerPasswordSet failed to actually change the password");
468
469         new_random_pass = netlogon_very_rand_pass(tctx, 128);
470
471         /* now try a random stream of bytes for a password */
472         set_pw_in_buffer(password_buf.data, &new_random_pass);
473
474         creds_arcfour_crypt(creds, password_buf.data, 516);
475
476         memcpy(r.in.new_password.data, password_buf.data, 512);
477         r.in.new_password.length = IVAL(password_buf.data, 512);
478
479         torture_comment(tctx, 
480                 "Testing a third ServerPasswordSet2 on machine account, with a compleatly random password\n");
481
482         creds_client_authenticator(creds, &r.in.credential);
483
484         status = dcerpc_netr_ServerPasswordSet2(p, tctx, &r);
485         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordSet (3)");
486
487         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
488                 torture_comment(tctx, "Credential chaining failed\n");
489         }
490
491         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
492
493         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
494         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
495
496         torture_assert (tctx, 
497                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
498                 "ServerPasswordSet failed to actually change the password");
499
500         return true;
501 }
502
503 static bool test_GetPassword(struct torture_context *tctx,
504                              struct dcerpc_pipe *p,
505                              struct cli_credentials *machine_credentials)
506 {
507         struct netr_ServerPasswordGet r;
508         struct creds_CredentialState *creds;
509         struct netr_Authenticator credential;
510         NTSTATUS status;
511         struct netr_Authenticator return_authenticator;
512         struct samr_Password password;
513
514         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
515                 return false;
516         }
517
518         creds_client_authenticator(creds, &credential);
519
520         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
521         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
522         r.in.secure_channel_type = SEC_CHAN_BDC;
523         r.in.computer_name = TEST_MACHINE_NAME;
524         r.in.credential = &credential;
525         r.out.return_authenticator = &return_authenticator;
526         r.out.password = &password;
527
528         status = dcerpc_netr_ServerPasswordGet(p, tctx, &r);
529         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
530
531         return true;
532 }
533
534 static bool test_GetTrustPasswords(struct torture_context *tctx,
535                                    struct dcerpc_pipe *p,
536                                    struct cli_credentials *machine_credentials)
537 {
538         struct netr_ServerTrustPasswordsGet r;
539         struct creds_CredentialState *creds;
540         struct netr_Authenticator credential;
541         NTSTATUS status;
542         struct netr_Authenticator return_authenticator;
543         struct samr_Password password, password2;
544
545         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
546                 return false;
547         }
548
549         creds_client_authenticator(creds, &credential);
550
551         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
552         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
553         r.in.secure_channel_type = SEC_CHAN_BDC;
554         r.in.computer_name = TEST_MACHINE_NAME;
555         r.in.credential = &credential;
556         r.out.return_authenticator = &return_authenticator;
557         r.out.password = &password;
558         r.out.password2 = &password2;
559
560         status = dcerpc_netr_ServerTrustPasswordsGet(p, tctx, &r);
561         torture_assert_ntstatus_ok(tctx, status, "ServerTrustPasswordsGet");
562
563         return true;
564 }
565
566 /*
567   try a netlogon SamLogon
568 */
569 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
570                               struct cli_credentials *credentials, 
571                               struct creds_CredentialState *creds)
572 {
573         NTSTATUS status;
574         struct netr_LogonSamLogon r;
575         struct netr_Authenticator auth, auth2;
576         struct netr_NetworkInfo ninfo;
577         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
578         int i;
579         int flags = CLI_CRED_NTLM_AUTH;
580         if (lp_client_lanman_auth(tctx->lp_ctx)) {
581                 flags |= CLI_CRED_LANMAN_AUTH;
582         }
583
584         if (lp_client_ntlmv2_auth(tctx->lp_ctx)) {
585                 flags |= CLI_CRED_NTLMv2_AUTH;
586         }
587
588         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, 
589                                                  &ninfo.identity_info.account_name.string,
590                                                  &ninfo.identity_info.domain_name.string);
591         
592         generate_random_buffer(ninfo.challenge, 
593                                sizeof(ninfo.challenge));
594         chal = data_blob_const(ninfo.challenge, 
595                                sizeof(ninfo.challenge));
596
597         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), 
598                                                 cli_credentials_get_domain(credentials));
599
600         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, 
601                                                    &flags, 
602                                                    chal,
603                                                    names_blob,
604                                                    &lm_resp, &nt_resp,
605                                                    NULL, NULL);
606         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
607
608         ninfo.lm.data = lm_resp.data;
609         ninfo.lm.length = lm_resp.length;
610
611         ninfo.nt.data = nt_resp.data;
612         ninfo.nt.length = nt_resp.length;
613
614         ninfo.identity_info.parameter_control = 0;
615         ninfo.identity_info.logon_id_low = 0;
616         ninfo.identity_info.logon_id_high = 0;
617         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
618
619         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
620         r.in.computer_name = cli_credentials_get_workstation(credentials);
621         r.in.credential = &auth;
622         r.in.return_authenticator = &auth2;
623         r.in.logon_level = 2;
624         r.in.logon.network = &ninfo;
625
626         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
627         
628         for (i=2;i<3;i++) {
629                 ZERO_STRUCT(auth2);
630                 creds_client_authenticator(creds, &auth);
631                 
632                 r.in.validation_level = i;
633                 
634                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
635                 torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
636                 
637                 torture_assert(tctx, creds_client_check(creds, &r.out.return_authenticator->cred), 
638                         "Credential chaining failed");
639         }
640
641         r.in.credential = NULL;
642
643         for (i=2;i<=3;i++) {
644
645                 r.in.validation_level = i;
646
647                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
648
649                 status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
650                 torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_PARAMETER, 
651                         "LogonSamLogon expected INVALID_PARAMETER");
652
653         }
654
655         return true;
656 }
657
658 /*
659   try a netlogon SamLogon
660 */
661 static bool test_SamLogon(struct torture_context *tctx, 
662                           struct dcerpc_pipe *p,
663                           struct cli_credentials *credentials)
664 {
665         struct creds_CredentialState *creds;
666
667         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
668                 return false;
669         }
670
671         return test_netlogon_ops(p, tctx, credentials, creds);
672 }
673
674 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
675 static uint64_t sequence_nums[3];
676
677 /*
678   try a netlogon DatabaseSync
679 */
680 static bool test_DatabaseSync(struct torture_context *tctx, 
681                               struct dcerpc_pipe *p,
682                               struct cli_credentials *machine_credentials)
683 {
684         NTSTATUS status;
685         struct netr_DatabaseSync r;
686         struct creds_CredentialState *creds;
687         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
688         int i;
689
690         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
691                 return false;
692         }
693
694         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
695         r.in.computername = TEST_MACHINE_NAME;
696         r.in.preferredmaximumlength = (uint32_t)-1;
697         ZERO_STRUCT(r.in.return_authenticator);
698
699         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
700                 r.in.sync_context = 0;
701                 r.in.database_id = database_ids[i];
702
703                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
704
705                 do {
706                         creds_client_authenticator(creds, &r.in.credential);
707
708                         status = dcerpc_netr_DatabaseSync(p, tctx, &r);
709                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
710                             break;
711
712                         /* Native mode servers don't do this */
713                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
714                                 return true;
715                         }
716                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync");
717
718                         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
719                                 torture_comment(tctx, "Credential chaining failed\n");
720                         }
721
722                         r.in.sync_context = r.out.sync_context;
723
724                         if (r.out.delta_enum_array &&
725                             r.out.delta_enum_array->num_deltas > 0 &&
726                             r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
727                             r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
728                                 sequence_nums[r.in.database_id] = 
729                                         r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
730                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
731                                        r.in.database_id, 
732                                        (unsigned long long)sequence_nums[r.in.database_id]);
733                         }
734                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
735         }
736
737         return true;
738 }
739
740
741 /*
742   try a netlogon DatabaseDeltas
743 */
744 static bool test_DatabaseDeltas(struct torture_context *tctx, 
745                                 struct dcerpc_pipe *p,
746                                 struct cli_credentials *machine_credentials)
747 {
748         NTSTATUS status;
749         struct netr_DatabaseDeltas r;
750         struct creds_CredentialState *creds;
751         const uint32_t database_ids[] = {0, 1, 2}; 
752         int i;
753
754         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
755                 return false;
756         }
757
758         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
759         r.in.computername = TEST_MACHINE_NAME;
760         r.in.preferredmaximumlength = (uint32_t)-1;
761         ZERO_STRUCT(r.in.return_authenticator);
762
763         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
764                 r.in.database_id = database_ids[i];
765                 r.in.sequence_num = sequence_nums[r.in.database_id];
766
767                 if (r.in.sequence_num == 0) continue;
768
769                 r.in.sequence_num -= 1;
770
771                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
772                        r.in.database_id, (unsigned long long)r.in.sequence_num);
773
774                 do {
775                         creds_client_authenticator(creds, &r.in.credential);
776
777                         status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
778                         if (NT_STATUS_EQUAL(status, 
779                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
780                                 torture_comment(tctx, "not considering %s to be an error\n",
781                                        nt_errstr(status));
782                                 return true;
783                         }
784                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) 
785                             break;
786
787                         torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
788
789                         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
790                                 torture_comment(tctx, "Credential chaining failed\n");
791                         }
792
793                         r.in.sequence_num++;
794                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
795         }
796
797         return true;
798 }
799
800
801 /*
802   try a netlogon AccountDeltas
803 */
804 static bool test_AccountDeltas(struct torture_context *tctx, 
805                                struct dcerpc_pipe *p,
806                                struct cli_credentials *machine_credentials)
807 {
808         NTSTATUS status;
809         struct netr_AccountDeltas r;
810         struct creds_CredentialState *creds;
811
812         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
813                 return false;
814         }
815
816         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
817         r.in.computername = TEST_MACHINE_NAME;
818         ZERO_STRUCT(r.in.return_authenticator);
819         creds_client_authenticator(creds, &r.in.credential);
820         ZERO_STRUCT(r.in.uas);
821         r.in.count=10;
822         r.in.level=0;
823         r.in.buffersize=100;
824
825         /* w2k3 returns "NOT IMPLEMENTED" for this call */
826         status = dcerpc_netr_AccountDeltas(p, tctx, &r);
827         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
828
829         return true;
830 }
831
832 /*
833   try a netlogon AccountSync
834 */
835 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
836                              struct cli_credentials *machine_credentials)
837 {
838         NTSTATUS status;
839         struct netr_AccountSync r;
840         struct creds_CredentialState *creds;
841
842         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
843                 return false;
844         }
845
846         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
847         r.in.computername = TEST_MACHINE_NAME;
848         ZERO_STRUCT(r.in.return_authenticator);
849         creds_client_authenticator(creds, &r.in.credential);
850         ZERO_STRUCT(r.in.recordid);
851         r.in.reference=0;
852         r.in.level=0;
853         r.in.buffersize=100;
854
855         /* w2k3 returns "NOT IMPLEMENTED" for this call */
856         status = dcerpc_netr_AccountSync(p, tctx, &r);
857         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
858
859         return true;
860 }
861
862 /*
863   try a netlogon GetDcName
864 */
865 static bool test_GetDcName(struct torture_context *tctx, 
866                            struct dcerpc_pipe *p)
867 {
868         NTSTATUS status;
869         struct netr_GetDcName r;
870
871         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
872         r.in.domainname = lp_workgroup(tctx->lp_ctx);
873
874         status = dcerpc_netr_GetDcName(p, tctx, &r);
875         torture_assert_ntstatus_ok(tctx, status, "GetDcName");
876         torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
877
878         torture_comment(tctx, "\tDC is at '%s'\n", r.out.dcname);
879
880         return true;
881 }
882
883 /*
884   try a netlogon LogonControl 
885 */
886 static bool test_LogonControl(struct torture_context *tctx, 
887                               struct dcerpc_pipe *p)
888 {
889         NTSTATUS status;
890         struct netr_LogonControl r;
891         int i;
892
893         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
894         r.in.function_code = 1;
895
896         for (i=1;i<4;i++) {
897                 r.in.level = i;
898
899                 torture_comment(tctx, "Testing LogonControl level %d\n", i);
900
901                 status = dcerpc_netr_LogonControl(p, tctx, &r);
902                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
903         }
904
905         return true;
906 }
907
908
909 /*
910   try a netlogon GetAnyDCName
911 */
912 static bool test_GetAnyDCName(struct torture_context *tctx, 
913                               struct dcerpc_pipe *p)
914 {
915         NTSTATUS status;
916         struct netr_GetAnyDCName r;
917
918         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
919         r.in.domainname = lp_workgroup(tctx->lp_ctx);
920
921         status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
922         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
923
924         if (r.out.dcname) {
925             torture_comment(tctx, "\tDC is at '%s'\n", r.out.dcname);
926         }
927
928         return true;
929 }
930
931
932 /*
933   try a netlogon LogonControl2
934 */
935 static bool test_LogonControl2(struct torture_context *tctx, 
936                                struct dcerpc_pipe *p)
937 {
938         NTSTATUS status;
939         struct netr_LogonControl2 r;
940         int i;
941
942         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
943
944         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
945         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
946
947         for (i=1;i<4;i++) {
948                 r.in.level = i;
949
950                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
951                        i, r.in.function_code);
952
953                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
954                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
955         }
956
957         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
958         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
959
960         for (i=1;i<4;i++) {
961                 r.in.level = i;
962
963                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
964                        i, r.in.function_code);
965
966                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
967                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
968         }
969
970         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
971         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
972
973         for (i=1;i<4;i++) {
974                 r.in.level = i;
975
976                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
977                        i, r.in.function_code);
978
979                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
980                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
981         }
982
983         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
984         r.in.data.debug_level = ~0;
985
986         for (i=1;i<4;i++) {
987                 r.in.level = i;
988
989                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
990                        i, r.in.function_code);
991
992                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
993                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
994         }
995
996         return true;
997 }
998
999 /*
1000   try a netlogon DatabaseSync2
1001 */
1002 static bool test_DatabaseSync2(struct torture_context *tctx, 
1003                                struct dcerpc_pipe *p,
1004                                struct cli_credentials *machine_credentials)
1005 {
1006         NTSTATUS status;
1007         struct netr_DatabaseSync2 r;
1008         struct creds_CredentialState *creds;
1009         const uint32_t database_ids[] = {0, 1, 2}; 
1010         int i;
1011
1012         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
1013                                     machine_credentials,
1014                                     SEC_CHAN_BDC, &creds)) {
1015                 return false;
1016         }
1017
1018         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1019         r.in.computername = TEST_MACHINE_NAME;
1020         r.in.preferredmaximumlength = (uint32_t)-1;
1021         ZERO_STRUCT(r.in.return_authenticator);
1022
1023         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1024                 r.in.sync_context = 0;
1025                 r.in.database_id = database_ids[i];
1026                 r.in.restart_state = 0;
1027
1028                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1029
1030                 do {
1031                         creds_client_authenticator(creds, &r.in.credential);
1032
1033                         status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1034                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1035                             break;
1036
1037                         /* Native mode servers don't do this */
1038                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1039                                 return true;
1040                         }
1041
1042                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1043
1044                         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
1045                                 torture_comment(tctx, "Credential chaining failed\n");
1046                         }
1047
1048                         r.in.sync_context = r.out.sync_context;
1049                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1050         }
1051
1052         return true;
1053 }
1054
1055
1056 /*
1057   try a netlogon LogonControl2Ex
1058 */
1059 static bool test_LogonControl2Ex(struct torture_context *tctx, 
1060                                  struct dcerpc_pipe *p)
1061 {
1062         NTSTATUS status;
1063         struct netr_LogonControl2Ex r;
1064         int i;
1065
1066         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1067
1068         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1069         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1070
1071         for (i=1;i<4;i++) {
1072                 r.in.level = i;
1073
1074                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1075                        i, r.in.function_code);
1076
1077                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1078                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1079         }
1080
1081         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1082         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1083
1084         for (i=1;i<4;i++) {
1085                 r.in.level = i;
1086
1087                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1088                        i, r.in.function_code);
1089
1090                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1091                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1092         }
1093
1094         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1095         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1096
1097         for (i=1;i<4;i++) {
1098                 r.in.level = i;
1099
1100                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1101                        i, r.in.function_code);
1102
1103                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1104                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1105         }
1106
1107         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1108         r.in.data.debug_level = ~0;
1109
1110         for (i=1;i<4;i++) {
1111                 r.in.level = i;
1112
1113                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1114                        i, r.in.function_code);
1115
1116                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1117                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1118         }
1119
1120         return true;
1121 }
1122
1123 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
1124                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
1125 {
1126         NTSTATUS status;
1127         struct netr_DsRGetForestTrustInformation r;
1128         struct lsa_ForestTrustInformation info, *info_ptr;
1129
1130         info_ptr = &info;
1131
1132         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1133         r.in.trusted_domain_name = trusted_domain_name;
1134         r.in.flags = 0;
1135         r.out.forest_trust_info = &info_ptr;
1136
1137         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1138
1139         status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1140         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1141         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1142
1143         return true;
1144 }
1145
1146 /*
1147   try a netlogon netr_DsrEnumerateDomainTrusts
1148 */
1149 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
1150                                           struct dcerpc_pipe *p)
1151 {
1152         NTSTATUS status;
1153         struct netr_DsrEnumerateDomainTrusts r;
1154         int i;
1155
1156         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1157         r.in.trust_flags = 0x3f;
1158
1159         status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1160         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1161         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1162
1163         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1164          * will show non-forest trusts and all UPN suffixes of the own forest
1165          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1166
1167         if (r.out.count) {
1168                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1169                         return false;
1170                 }
1171         }
1172
1173         for (i=0; i<r.out.count; i++) {
1174
1175                 /* get info for transitive forest trusts */
1176
1177                 if (r.out.trusts[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1178                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
1179                                                                     r.out.trusts[i].dns_name)) {
1180                                 return false;
1181                         }
1182                 }
1183         }
1184
1185         return true;
1186 }
1187
1188 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1189                                                   struct dcerpc_pipe *p)
1190 {
1191         NTSTATUS status;
1192         struct netr_NetrEnumerateTrustedDomains r;
1193         struct netr_Blob trusted_domains_blob;
1194
1195         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1196         r.out.trusted_domains_blob = &trusted_domains_blob;
1197
1198         status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1199         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1200         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1201
1202         return true;
1203 }
1204
1205 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1206                                                     struct dcerpc_pipe *p)
1207 {
1208         NTSTATUS status;
1209         struct netr_NetrEnumerateTrustedDomainsEx r;
1210         struct netr_DomainTrustList dom_trust_list;
1211
1212         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1213         r.out.dom_trust_list = &dom_trust_list;
1214
1215         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1216         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1217         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1218
1219         return true;
1220 }
1221
1222
1223 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1224                                      const char *computer_name, 
1225                                      const char *expected_site) 
1226 {
1227         NTSTATUS status;
1228         struct netr_DsRGetSiteName r;
1229
1230         if (torture_setting_bool(tctx, "samba4", false))
1231                 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1232
1233         r.in.computer_name              = computer_name;
1234         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1235
1236         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1237         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1238         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1239         torture_assert_str_equal(tctx, expected_site, r.out.site, "netr_DsRGetSiteName");
1240
1241         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
1242         torture_comment(tctx, 
1243                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1244
1245         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1246         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1247         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1248
1249         return true;
1250 }
1251
1252 /*
1253   try a netlogon netr_DsRGetDCName
1254 */
1255 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
1256                                    struct dcerpc_pipe *p)
1257 {
1258         NTSTATUS status;
1259         struct netr_DsRGetDCName r;
1260
1261         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1262         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1263         r.in.domain_guid        = NULL;
1264         r.in.site_guid          = NULL;
1265         r.in.flags              = DS_RETURN_DNS_NAME;
1266
1267         status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
1268         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
1269         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
1270         return test_netr_DsRGetSiteName(p, tctx, 
1271                                        r.out.info->dc_unc, 
1272                                        r.out.info->dc_site_name);
1273 }
1274
1275 /*
1276   try a netlogon netr_DsRGetDCNameEx
1277 */
1278 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
1279                                      struct dcerpc_pipe *p)
1280 {
1281         NTSTATUS status;
1282         struct netr_DsRGetDCNameEx r;
1283
1284         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1285         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1286         r.in.domain_guid        = NULL;
1287         r.in.site_name          = NULL;
1288         r.in.flags              = DS_RETURN_DNS_NAME;
1289
1290         status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
1291         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
1292         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
1293
1294         return test_netr_DsRGetSiteName(p, tctx, r.out.info->dc_unc, 
1295                                        r.out.info->dc_site_name);
1296 }
1297
1298 /*
1299   try a netlogon netr_DsRGetDCNameEx2
1300 */
1301 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
1302                                       struct dcerpc_pipe *p)
1303 {
1304         NTSTATUS status;
1305         struct netr_DsRGetDCNameEx2 r;
1306
1307         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1308         r.in.client_account     = NULL;
1309         r.in.mask               = 0x00000000;
1310         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1311         r.in.domain_guid        = NULL;
1312         r.in.site_name          = NULL;
1313         r.in.flags              = DS_RETURN_DNS_NAME;
1314
1315         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
1316
1317         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1318         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1319         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1320
1321         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
1322         r.in.client_account     = TEST_MACHINE_NAME"$";
1323         r.in.mask               = ACB_SVRTRUST;
1324         r.in.flags              = DS_RETURN_FLAT_NAME;
1325
1326         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1327         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1328         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1329         return test_netr_DsRGetSiteName(p, tctx, r.out.info->dc_unc, 
1330                                         r.out.info->dc_site_name);
1331 }
1332
1333 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
1334                                             struct dcerpc_pipe *p)
1335 {
1336         NTSTATUS status;
1337         struct netr_DsrGetDcSiteCoverageW r;
1338
1339         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1340
1341         status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
1342         torture_assert_ntstatus_ok(tctx, status, "failed");
1343         torture_assert_werr_ok(tctx, r.out.result, "failed");
1344
1345         return true;
1346 }
1347
1348 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
1349                                              struct dcerpc_pipe *p)
1350 {
1351         NTSTATUS status;
1352         struct netr_DsRAddressToSitenamesW r;
1353         struct netr_DsRAddress addr;
1354         struct netr_DsRAddressToSitenamesWCtr *ctr;
1355
1356         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
1357
1358         addr.size = 16;
1359         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1360
1361         addr.buffer[0] = 2; /* AF_INET */
1362         addr.buffer[4] = 127;
1363         addr.buffer[5] = 0;
1364         addr.buffer[6] = 0;
1365         addr.buffer[7] = 1;
1366
1367         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1368         r.in.count = 1;
1369         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1370         r.in.addresses[0] = addr;
1371         r.out.ctr = &ctr;
1372
1373         status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
1374         torture_assert_ntstatus_ok(tctx, status, "failed");
1375         torture_assert_werr_ok(tctx, r.out.result, "failed");
1376
1377         return true;
1378 }
1379
1380 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
1381                                                struct dcerpc_pipe *p)
1382 {
1383         NTSTATUS status;
1384         struct netr_DsRAddressToSitenamesExW r;
1385         struct netr_DsRAddress addr;
1386         struct netr_DsRAddressToSitenamesExWCtr *ctr;
1387
1388         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
1389
1390         addr.size = 16;
1391         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1392
1393         addr.buffer[0] = 2; /* AF_INET */
1394         addr.buffer[4] = 127;
1395         addr.buffer[5] = 0;
1396         addr.buffer[6] = 0;
1397         addr.buffer[7] = 1;
1398
1399         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1400         r.in.count = 1;
1401         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1402         r.in.addresses[0] = addr;
1403         r.out.ctr = &ctr;
1404
1405         status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
1406         torture_assert_ntstatus_ok(tctx, status, "failed");
1407         torture_assert_werr_ok(tctx, r.out.result, "failed");
1408
1409         return true;
1410 }
1411
1412 static bool test_GetDomainInfo(struct torture_context *tctx, 
1413                                struct dcerpc_pipe *p,
1414                                struct cli_credentials *machine_credentials)
1415 {
1416         NTSTATUS status;
1417         struct netr_LogonGetDomainInfo r;
1418         struct netr_DomainQuery1 q1;
1419         struct netr_Authenticator a;
1420         struct creds_CredentialState *creds;
1421
1422         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
1423                                     machine_credentials, &creds)) {
1424                 return false;
1425         }
1426
1427         ZERO_STRUCT(r);
1428
1429         creds_client_authenticator(creds, &a);
1430
1431         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1432         r.in.computer_name = TEST_MACHINE_NAME;
1433         r.in.level = 1;
1434         r.in.credential = &a;
1435         r.in.return_authenticator = &a;
1436         r.out.return_authenticator = &a;
1437
1438         r.in.query.query1 = &q1;
1439         ZERO_STRUCT(q1);
1440         
1441         /* this should really be the fully qualified name */
1442         q1.workstation_domain = TEST_MACHINE_NAME;
1443         q1.workstation_site = "Default-First-Site-Name";
1444         q1.blob2.length = 0;
1445         q1.blob2.size = 0;
1446         q1.blob2.data = NULL;
1447         q1.product.string = "product string";
1448
1449         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
1450
1451         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1452         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1453         torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1454
1455         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call\n");
1456         creds_client_authenticator(creds, &a);
1457
1458         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1459         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1460         torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1461
1462         return true;
1463 }
1464
1465
1466 static void async_callback(struct rpc_request *req)
1467 {
1468         int *counter = (int *)req->async.private_data;
1469         if (NT_STATUS_IS_OK(req->status)) {
1470                 (*counter)++;
1471         }
1472 }
1473
1474 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
1475                                      struct dcerpc_pipe *p,
1476                                      struct cli_credentials *machine_credentials)
1477 {
1478         NTSTATUS status;
1479         struct netr_LogonGetDomainInfo r;
1480         struct netr_DomainQuery1 q1;
1481         struct netr_Authenticator a;
1482 #define ASYNC_COUNT 100
1483         struct creds_CredentialState *creds;
1484         struct creds_CredentialState *creds_async[ASYNC_COUNT];
1485         struct rpc_request *req[ASYNC_COUNT];
1486         int i;
1487         int *async_counter = talloc(tctx, int);
1488
1489         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
1490                                     machine_credentials, &creds)) {
1491                 return false;
1492         }
1493
1494         ZERO_STRUCT(r);
1495         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1496         r.in.computer_name = TEST_MACHINE_NAME;
1497         r.in.level = 1;
1498         r.in.credential = &a;
1499         r.in.return_authenticator = &a;
1500         r.out.return_authenticator = &a;
1501
1502         r.in.query.query1 = &q1;
1503         ZERO_STRUCT(q1);
1504         
1505         /* this should really be the fully qualified name */
1506         q1.workstation_domain = TEST_MACHINE_NAME;
1507         q1.workstation_site = "Default-First-Site-Name";
1508         q1.blob2.length = 0;
1509         q1.blob2.size = 0;
1510         q1.blob2.data = NULL;
1511         q1.product.string = "product string";
1512
1513         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1514
1515         *async_counter = 0;
1516
1517         for (i=0;i<ASYNC_COUNT;i++) {
1518                 creds_client_authenticator(creds, &a);
1519
1520                 creds_async[i] = (struct creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
1521                 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
1522
1523                 req[i]->async.callback = async_callback;
1524                 req[i]->async.private_data = async_counter;
1525
1526                 /* even with this flush per request a w2k3 server seems to 
1527                    clag with multiple outstanding requests. bleergh. */
1528                 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0, 
1529                                          "event_loop_once failed");
1530         }
1531
1532         for (i=0;i<ASYNC_COUNT;i++) {
1533                 status = dcerpc_ndr_request_recv(req[i]);
1534
1535                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
1536                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
1537
1538                 torture_assert(tctx, creds_client_check(creds_async[i], &a.cred), 
1539                         "Credential chaining failed at async");
1540         }
1541
1542         torture_comment(tctx, 
1543                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1544
1545         torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
1546
1547         return true;
1548 }
1549
1550 static bool test_ManyGetDCName(struct torture_context *tctx, 
1551                                struct dcerpc_pipe *p)
1552 {
1553         NTSTATUS status;
1554         struct dcerpc_pipe *p2;
1555         struct lsa_ObjectAttribute attr;
1556         struct lsa_QosInfo qos;
1557         struct lsa_OpenPolicy2 o;
1558         struct policy_handle lsa_handle;
1559         struct lsa_DomainList domains;
1560
1561         struct lsa_EnumTrustDom t;
1562         uint32_t resume_handle = 0;
1563         struct netr_GetAnyDCName d;
1564
1565         int i;
1566
1567         if (p->conn->transport.transport != NCACN_NP) {
1568                 return true;
1569         }
1570
1571         torture_comment(tctx, "Torturing GetDCName\n");
1572
1573         status = dcerpc_secondary_connection(p, &p2, p->binding);
1574         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
1575
1576         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
1577         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
1578
1579         qos.len = 0;
1580         qos.impersonation_level = 2;
1581         qos.context_mode = 1;
1582         qos.effective_only = 0;
1583
1584         attr.len = 0;
1585         attr.root_dir = NULL;
1586         attr.object_name = NULL;
1587         attr.attributes = 0;
1588         attr.sec_desc = NULL;
1589         attr.sec_qos = &qos;
1590
1591         o.in.system_name = "\\";
1592         o.in.attr = &attr;
1593         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1594         o.out.handle = &lsa_handle;
1595
1596         status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
1597         torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
1598
1599         t.in.handle = &lsa_handle;
1600         t.in.resume_handle = &resume_handle;
1601         t.in.max_size = 1000;
1602         t.out.domains = &domains;
1603         t.out.resume_handle = &resume_handle;
1604
1605         status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
1606
1607         if ((!NT_STATUS_IS_OK(status) &&
1608              (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
1609                 torture_fail(tctx, "Could not list domains");
1610
1611         talloc_free(p2);
1612
1613         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
1614                                             dcerpc_server_name(p));
1615
1616         for (i=0; i<domains.count * 4; i++) {
1617                 struct lsa_DomainInfo *info =
1618                         &domains.domains[rand()%domains.count];
1619
1620                 d.in.domainname = info->name.string;
1621
1622                 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
1623                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1624
1625                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
1626                        d.out.dcname ? d.out.dcname : "unknown");
1627         }
1628
1629         return true;
1630 }
1631
1632 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
1633 {
1634         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
1635         struct torture_rpc_tcase *tcase;
1636         struct torture_test *test;
1637
1638         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "netlogon", 
1639                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
1640
1641         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
1642         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
1643         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
1644         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
1645         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
1646         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
1647         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
1648         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
1649         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
1650         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
1651         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
1652         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
1653         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
1654         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
1655         torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
1656         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
1657         torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
1658         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
1659         torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
1660         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
1661         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
1662         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
1663         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
1664         test->dangerous = true;
1665         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
1666         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
1667         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
1668         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
1669         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
1670         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
1671
1672         return suite;
1673 }