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