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