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