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