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