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