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