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