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