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