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