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