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