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