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