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