232d10323c201fbfc8bb543bcef518a75690bb69
[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         const uint32_t database_ids[] = {0, 1, 2}; 
754         int i;
755
756         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
757                 return false;
758         }
759
760         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
761         r.in.computername = TEST_MACHINE_NAME;
762         r.in.preferredmaximumlength = (uint32_t)-1;
763         ZERO_STRUCT(r.in.return_authenticator);
764
765         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
766                 r.in.database_id = database_ids[i];
767                 r.in.sequence_num = sequence_nums[r.in.database_id];
768
769                 if (r.in.sequence_num == 0) continue;
770
771                 r.in.sequence_num -= 1;
772
773                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
774                        r.in.database_id, (unsigned long long)r.in.sequence_num);
775
776                 do {
777                         creds_client_authenticator(creds, &r.in.credential);
778
779                         status = dcerpc_netr_DatabaseDeltas(p, tctx, &r);
780                         if (NT_STATUS_EQUAL(status, 
781                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
782                                 torture_comment(tctx, "not considering %s to be an error\n",
783                                        nt_errstr(status));
784                                 return true;
785                         }
786                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) 
787                             break;
788
789                         torture_assert_ntstatus_ok(tctx, status, "DatabaseDeltas");
790
791                         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
792                                 torture_comment(tctx, "Credential chaining failed\n");
793                         }
794
795                         r.in.sequence_num++;
796                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
797         }
798
799         return true;
800 }
801
802
803 /*
804   try a netlogon AccountDeltas
805 */
806 static bool test_AccountDeltas(struct torture_context *tctx, 
807                                struct dcerpc_pipe *p,
808                                struct cli_credentials *machine_credentials)
809 {
810         NTSTATUS status;
811         struct netr_AccountDeltas r;
812         struct creds_CredentialState *creds;
813
814         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
815                 return false;
816         }
817
818         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
819         r.in.computername = TEST_MACHINE_NAME;
820         ZERO_STRUCT(r.in.return_authenticator);
821         creds_client_authenticator(creds, &r.in.credential);
822         ZERO_STRUCT(r.in.uas);
823         r.in.count=10;
824         r.in.level=0;
825         r.in.buffersize=100;
826
827         /* w2k3 returns "NOT IMPLEMENTED" for this call */
828         status = dcerpc_netr_AccountDeltas(p, tctx, &r);
829         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
830
831         return true;
832 }
833
834 /*
835   try a netlogon AccountSync
836 */
837 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
838                              struct cli_credentials *machine_credentials)
839 {
840         NTSTATUS status;
841         struct netr_AccountSync r;
842         struct creds_CredentialState *creds;
843
844         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
845                 return false;
846         }
847
848         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
849         r.in.computername = TEST_MACHINE_NAME;
850         ZERO_STRUCT(r.in.return_authenticator);
851         creds_client_authenticator(creds, &r.in.credential);
852         ZERO_STRUCT(r.in.recordid);
853         r.in.reference=0;
854         r.in.level=0;
855         r.in.buffersize=100;
856
857         /* w2k3 returns "NOT IMPLEMENTED" for this call */
858         status = dcerpc_netr_AccountSync(p, tctx, &r);
859         torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
860
861         return true;
862 }
863
864 /*
865   try a netlogon GetDcName
866 */
867 static bool test_GetDcName(struct torture_context *tctx, 
868                            struct dcerpc_pipe *p)
869 {
870         NTSTATUS status;
871         struct netr_GetDcName r;
872         const char *dcname = NULL;
873
874         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
875         r.in.domainname = lp_workgroup(tctx->lp_ctx);
876         r.out.dcname = &dcname;
877
878         status = dcerpc_netr_GetDcName(p, tctx, &r);
879         torture_assert_ntstatus_ok(tctx, status, "GetDcName");
880         torture_assert_werr_ok(tctx, r.out.result, "GetDcName");
881
882         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
883
884         return true;
885 }
886
887 /*
888   try a netlogon LogonControl 
889 */
890 static bool test_LogonControl(struct torture_context *tctx, 
891                               struct dcerpc_pipe *p)
892 {
893         NTSTATUS status;
894         struct netr_LogonControl r;
895         union netr_CONTROL_QUERY_INFORMATION info;
896         int i;
897
898         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
899         r.in.function_code = 1;
900         r.out.info = &info;
901
902         for (i=1;i<4;i++) {
903                 r.in.level = i;
904
905                 torture_comment(tctx, "Testing LogonControl level %d\n", i);
906
907                 status = dcerpc_netr_LogonControl(p, tctx, &r);
908                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
909         }
910
911         return true;
912 }
913
914
915 /*
916   try a netlogon GetAnyDCName
917 */
918 static bool test_GetAnyDCName(struct torture_context *tctx, 
919                               struct dcerpc_pipe *p)
920 {
921         NTSTATUS status;
922         struct netr_GetAnyDCName r;
923         const char *dcname = NULL;
924
925         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
926         r.in.domainname = lp_workgroup(tctx->lp_ctx);
927         r.out.dcname = &dcname;
928
929         status = dcerpc_netr_GetAnyDCName(p, tctx, &r);
930         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
931
932         if (dcname) {
933             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
934         }
935
936         return true;
937 }
938
939
940 /*
941   try a netlogon LogonControl2
942 */
943 static bool test_LogonControl2(struct torture_context *tctx, 
944                                struct dcerpc_pipe *p)
945 {
946         NTSTATUS status;
947         struct netr_LogonControl2 r;
948         union netr_CONTROL_DATA_INFORMATION data;
949         union netr_CONTROL_QUERY_INFORMATION query;
950         int i;
951
952         data.domain = lp_workgroup(tctx->lp_ctx);
953
954         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
955
956         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
957         r.in.data = &data;
958         r.out.query = &query;
959
960         for (i=1;i<4;i++) {
961                 r.in.level = i;
962
963                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
964                        i, r.in.function_code);
965
966                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
967                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
968         }
969
970         data.domain = lp_workgroup(tctx->lp_ctx);
971
972         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
973         r.in.data = &data;
974
975         for (i=1;i<4;i++) {
976                 r.in.level = i;
977
978                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
979                        i, r.in.function_code);
980
981                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
982                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
983         }
984
985         data.domain = lp_workgroup(tctx->lp_ctx);
986
987         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
988         r.in.data = &data;
989
990         for (i=1;i<4;i++) {
991                 r.in.level = i;
992
993                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
994                        i, r.in.function_code);
995
996                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
997                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
998         }
999
1000         data.debug_level = ~0;
1001
1002         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1003         r.in.data = &data;
1004
1005         for (i=1;i<4;i++) {
1006                 r.in.level = i;
1007
1008                 torture_comment(tctx, "Testing LogonControl2 level %d function %d\n", 
1009                        i, r.in.function_code);
1010
1011                 status = dcerpc_netr_LogonControl2(p, tctx, &r);
1012                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1013         }
1014
1015         return true;
1016 }
1017
1018 /*
1019   try a netlogon DatabaseSync2
1020 */
1021 static bool test_DatabaseSync2(struct torture_context *tctx, 
1022                                struct dcerpc_pipe *p,
1023                                struct cli_credentials *machine_credentials)
1024 {
1025         NTSTATUS status;
1026         struct netr_DatabaseSync2 r;
1027         struct creds_CredentialState *creds;
1028         const uint32_t database_ids[] = {0, 1, 2}; 
1029         int i;
1030
1031         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
1032                                     machine_credentials,
1033                                     SEC_CHAN_BDC, &creds)) {
1034                 return false;
1035         }
1036
1037         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1038         r.in.computername = TEST_MACHINE_NAME;
1039         r.in.preferredmaximumlength = (uint32_t)-1;
1040         ZERO_STRUCT(r.in.return_authenticator);
1041
1042         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1043                 r.in.sync_context = 0;
1044                 r.in.database_id = database_ids[i];
1045                 r.in.restart_state = 0;
1046
1047                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
1048
1049                 do {
1050                         creds_client_authenticator(creds, &r.in.credential);
1051
1052                         status = dcerpc_netr_DatabaseSync2(p, tctx, &r);
1053                         if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
1054                             break;
1055
1056                         /* Native mode servers don't do this */
1057                         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
1058                                 return true;
1059                         }
1060
1061                         torture_assert_ntstatus_ok(tctx, status, "DatabaseSync2");
1062
1063                         if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
1064                                 torture_comment(tctx, "Credential chaining failed\n");
1065                         }
1066
1067                         r.in.sync_context = r.out.sync_context;
1068                 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
1069         }
1070
1071         return true;
1072 }
1073
1074
1075 /*
1076   try a netlogon LogonControl2Ex
1077 */
1078 static bool test_LogonControl2Ex(struct torture_context *tctx, 
1079                                  struct dcerpc_pipe *p)
1080 {
1081         NTSTATUS status;
1082         struct netr_LogonControl2Ex r;
1083         union netr_CONTROL_QUERY_INFORMATION query;
1084         int i;
1085
1086         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1087
1088         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1089         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1090         r.out.query = &query;
1091
1092         for (i=1;i<4;i++) {
1093                 r.in.level = i;
1094
1095                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1096                        i, r.in.function_code);
1097
1098                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1099                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1100         }
1101
1102         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1103         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1104
1105         for (i=1;i<4;i++) {
1106                 r.in.level = i;
1107
1108                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1109                        i, r.in.function_code);
1110
1111                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1112                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1113         }
1114
1115         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1116         r.in.data.domain = lp_workgroup(tctx->lp_ctx);
1117
1118         for (i=1;i<4;i++) {
1119                 r.in.level = i;
1120
1121                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1122                        i, r.in.function_code);
1123
1124                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1125                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1126         }
1127
1128         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1129         r.in.data.debug_level = ~0;
1130
1131         for (i=1;i<4;i++) {
1132                 r.in.level = i;
1133
1134                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
1135                        i, r.in.function_code);
1136
1137                 status = dcerpc_netr_LogonControl2Ex(p, tctx, &r);
1138                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1139         }
1140
1141         return true;
1142 }
1143
1144 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
1145                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
1146 {
1147         NTSTATUS status;
1148         struct netr_DsRGetForestTrustInformation r;
1149         struct lsa_ForestTrustInformation info, *info_ptr;
1150
1151         info_ptr = &info;
1152
1153         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1154         r.in.trusted_domain_name = trusted_domain_name;
1155         r.in.flags = 0;
1156         r.out.forest_trust_info = &info_ptr;
1157
1158         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
1159
1160         status = dcerpc_netr_DsRGetForestTrustInformation(p, tctx, &r);
1161         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
1162         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
1163
1164         return true;
1165 }
1166
1167 /*
1168   try a netlogon netr_DsrEnumerateDomainTrusts
1169 */
1170 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
1171                                           struct dcerpc_pipe *p)
1172 {
1173         NTSTATUS status;
1174         struct netr_DsrEnumerateDomainTrusts r;
1175         struct netr_DomainTrustList trusts;
1176         int i;
1177
1178         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1179         r.in.trust_flags = 0x3f;
1180         r.out.trusts = &trusts;
1181
1182         status = dcerpc_netr_DsrEnumerateDomainTrusts(p, tctx, &r);
1183         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
1184         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
1185
1186         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
1187          * will show non-forest trusts and all UPN suffixes of the own forest
1188          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
1189
1190         if (r.out.trusts->count) {
1191                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
1192                         return false;
1193                 }
1194         }
1195
1196         for (i=0; i<r.out.trusts->count; i++) {
1197
1198                 /* get info for transitive forest trusts */
1199
1200                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1201                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
1202                                                                     r.out.trusts->array[i].dns_name)) {
1203                                 return false;
1204                         }
1205                 }
1206         }
1207
1208         return true;
1209 }
1210
1211 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
1212                                                   struct dcerpc_pipe *p)
1213 {
1214         NTSTATUS status;
1215         struct netr_NetrEnumerateTrustedDomains r;
1216         struct netr_Blob trusted_domains_blob;
1217
1218         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1219         r.out.trusted_domains_blob = &trusted_domains_blob;
1220
1221         status = dcerpc_netr_NetrEnumerateTrustedDomains(p, tctx, &r);
1222         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
1223         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
1224
1225         return true;
1226 }
1227
1228 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
1229                                                     struct dcerpc_pipe *p)
1230 {
1231         NTSTATUS status;
1232         struct netr_NetrEnumerateTrustedDomainsEx r;
1233         struct netr_DomainTrustList dom_trust_list;
1234
1235         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1236         r.out.dom_trust_list = &dom_trust_list;
1237
1238         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx(p, tctx, &r);
1239         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
1240         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
1241
1242         return true;
1243 }
1244
1245
1246 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
1247                                      const char *computer_name, 
1248                                      const char *expected_site) 
1249 {
1250         NTSTATUS status;
1251         struct netr_DsRGetSiteName r;
1252         const char *site = NULL;
1253
1254         if (torture_setting_bool(tctx, "samba4", false))
1255                 torture_skip(tctx, "skipping DsRGetSiteName test against Samba4");
1256
1257         r.in.computer_name              = computer_name;
1258         r.out.site                      = &site;
1259         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
1260
1261         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1262         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1263         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
1264         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
1265
1266         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
1267         torture_comment(tctx, 
1268                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
1269
1270         status = dcerpc_netr_DsRGetSiteName(p, tctx, &r);
1271         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
1272         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
1273
1274         return true;
1275 }
1276
1277 /*
1278   try a netlogon netr_DsRGetDCName
1279 */
1280 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
1281                                    struct dcerpc_pipe *p)
1282 {
1283         NTSTATUS status;
1284         struct netr_DsRGetDCName r;
1285         struct netr_DsRGetDCNameInfo *info = NULL;
1286
1287         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1288         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1289         r.in.domain_guid        = NULL;
1290         r.in.site_guid          = NULL;
1291         r.in.flags              = DS_RETURN_DNS_NAME;
1292         r.out.info              = &info;
1293
1294         status = dcerpc_netr_DsRGetDCName(p, tctx, &r);
1295         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
1296         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
1297         return test_netr_DsRGetSiteName(p, tctx, 
1298                                        info->dc_unc,
1299                                        info->dc_site_name);
1300 }
1301
1302 /*
1303   try a netlogon netr_DsRGetDCNameEx
1304 */
1305 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
1306                                      struct dcerpc_pipe *p)
1307 {
1308         NTSTATUS status;
1309         struct netr_DsRGetDCNameEx r;
1310         struct netr_DsRGetDCNameInfo *info = NULL;
1311
1312         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1313         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1314         r.in.domain_guid        = NULL;
1315         r.in.site_name          = NULL;
1316         r.in.flags              = DS_RETURN_DNS_NAME;
1317         r.out.info              = &info;
1318
1319         status = dcerpc_netr_DsRGetDCNameEx(p, tctx, &r);
1320         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
1321         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
1322
1323         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1324                                         info->dc_site_name);
1325 }
1326
1327 /*
1328   try a netlogon netr_DsRGetDCNameEx2
1329 */
1330 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
1331                                       struct dcerpc_pipe *p)
1332 {
1333         NTSTATUS status;
1334         struct netr_DsRGetDCNameEx2 r;
1335         struct netr_DsRGetDCNameInfo *info = NULL;
1336
1337         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1338         r.in.client_account     = NULL;
1339         r.in.mask               = 0x00000000;
1340         r.in.domain_name        = talloc_asprintf(tctx, "%s", lp_realm(tctx->lp_ctx));
1341         r.in.domain_guid        = NULL;
1342         r.in.site_name          = NULL;
1343         r.in.flags              = DS_RETURN_DNS_NAME;
1344         r.out.info              = &info;
1345
1346         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
1347
1348         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1349         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1350         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1351
1352         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client acount\n");
1353         r.in.client_account     = TEST_MACHINE_NAME"$";
1354         r.in.mask               = ACB_SVRTRUST;
1355         r.in.flags              = DS_RETURN_FLAT_NAME;
1356         r.out.info              = &info;
1357
1358         status = dcerpc_netr_DsRGetDCNameEx2(p, tctx, &r);
1359         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
1360         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
1361         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
1362                                         info->dc_site_name);
1363 }
1364
1365 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
1366                                             struct dcerpc_pipe *p)
1367 {
1368         NTSTATUS status;
1369         struct netr_DsrGetDcSiteCoverageW r;
1370         struct DcSitesCtr *ctr = NULL;
1371
1372         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1373         r.out.ctr = &ctr;
1374
1375         status = dcerpc_netr_DsrGetDcSiteCoverageW(p, tctx, &r);
1376         torture_assert_ntstatus_ok(tctx, status, "failed");
1377         torture_assert_werr_ok(tctx, r.out.result, "failed");
1378
1379         return true;
1380 }
1381
1382 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
1383                                              struct dcerpc_pipe *p)
1384 {
1385         NTSTATUS status;
1386         struct netr_DsRAddressToSitenamesW r;
1387         struct netr_DsRAddress addr;
1388         struct netr_DsRAddressToSitenamesWCtr *ctr;
1389
1390         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
1391
1392         addr.size = 16;
1393         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1394
1395         addr.buffer[0] = 2; /* AF_INET */
1396         addr.buffer[4] = 127;
1397         addr.buffer[5] = 0;
1398         addr.buffer[6] = 0;
1399         addr.buffer[7] = 1;
1400
1401         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1402         r.in.count = 1;
1403         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1404         r.in.addresses[0] = addr;
1405         r.out.ctr = &ctr;
1406
1407         status = dcerpc_netr_DsRAddressToSitenamesW(p, tctx, &r);
1408         torture_assert_ntstatus_ok(tctx, status, "failed");
1409         torture_assert_werr_ok(tctx, r.out.result, "failed");
1410
1411         return true;
1412 }
1413
1414 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
1415                                                struct dcerpc_pipe *p)
1416 {
1417         NTSTATUS status;
1418         struct netr_DsRAddressToSitenamesExW r;
1419         struct netr_DsRAddress addr;
1420         struct netr_DsRAddressToSitenamesExWCtr *ctr;
1421
1422         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
1423
1424         addr.size = 16;
1425         addr.buffer = talloc_zero_array(tctx, uint8_t, addr.size);
1426
1427         addr.buffer[0] = 2; /* AF_INET */
1428         addr.buffer[4] = 127;
1429         addr.buffer[5] = 0;
1430         addr.buffer[6] = 0;
1431         addr.buffer[7] = 1;
1432
1433         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1434         r.in.count = 1;
1435         r.in.addresses = talloc_zero_array(tctx, struct netr_DsRAddress, r.in.count);
1436         r.in.addresses[0] = addr;
1437         r.out.ctr = &ctr;
1438
1439         status = dcerpc_netr_DsRAddressToSitenamesExW(p, tctx, &r);
1440         torture_assert_ntstatus_ok(tctx, status, "failed");
1441         torture_assert_werr_ok(tctx, r.out.result, "failed");
1442
1443         return true;
1444 }
1445
1446 static bool test_GetDomainInfo(struct torture_context *tctx, 
1447                                struct dcerpc_pipe *p,
1448                                struct cli_credentials *machine_credentials)
1449 {
1450         NTSTATUS status;
1451         struct netr_LogonGetDomainInfo r;
1452         struct netr_DomainQuery1 q1;
1453         struct netr_Authenticator a;
1454         struct creds_CredentialState *creds;
1455         union netr_DomainInfo info;
1456
1457         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
1458                                     machine_credentials, &creds)) {
1459                 return false;
1460         }
1461
1462         ZERO_STRUCT(r);
1463
1464         creds_client_authenticator(creds, &a);
1465
1466         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1467         r.in.computer_name = TEST_MACHINE_NAME;
1468         r.in.level = 1;
1469         r.in.credential = &a;
1470         r.in.return_authenticator = &a;
1471         r.out.return_authenticator = &a;
1472         r.out.info = &info;
1473
1474         r.in.query.query1 = &q1;
1475         ZERO_STRUCT(q1);
1476         
1477         /* this should really be the fully qualified name */
1478         q1.workstation_domain = TEST_MACHINE_NAME;
1479         q1.workstation_site = "Default-First-Site-Name";
1480         q1.blob2.length = 0;
1481         q1.blob2.size = 0;
1482         q1.blob2.data = NULL;
1483         q1.product.string = "product string";
1484
1485         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
1486
1487         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1488         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1489         torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1490
1491         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call\n");
1492         creds_client_authenticator(creds, &a);
1493
1494         status = dcerpc_netr_LogonGetDomainInfo(p, tctx, &r);
1495         torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo");
1496         torture_assert(tctx, creds_client_check(creds, &a.cred), "Credential chaining failed");
1497
1498         return true;
1499 }
1500
1501
1502 static void async_callback(struct rpc_request *req)
1503 {
1504         int *counter = (int *)req->async.private_data;
1505         if (NT_STATUS_IS_OK(req->status)) {
1506                 (*counter)++;
1507         }
1508 }
1509
1510 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
1511                                      struct dcerpc_pipe *p,
1512                                      struct cli_credentials *machine_credentials)
1513 {
1514         NTSTATUS status;
1515         struct netr_LogonGetDomainInfo r;
1516         struct netr_DomainQuery1 q1;
1517         struct netr_Authenticator a;
1518 #define ASYNC_COUNT 100
1519         struct creds_CredentialState *creds;
1520         struct creds_CredentialState *creds_async[ASYNC_COUNT];
1521         struct rpc_request *req[ASYNC_COUNT];
1522         int i;
1523         int *async_counter = talloc(tctx, int);
1524         union netr_DomainInfo info;
1525
1526         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
1527                                     machine_credentials, &creds)) {
1528                 return false;
1529         }
1530
1531         ZERO_STRUCT(r);
1532         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1533         r.in.computer_name = TEST_MACHINE_NAME;
1534         r.in.level = 1;
1535         r.in.credential = &a;
1536         r.in.return_authenticator = &a;
1537         r.out.return_authenticator = &a;
1538         r.out.info = &info;
1539
1540         r.in.query.query1 = &q1;
1541         ZERO_STRUCT(q1);
1542         
1543         /* this should really be the fully qualified name */
1544         q1.workstation_domain = TEST_MACHINE_NAME;
1545         q1.workstation_site = "Default-First-Site-Name";
1546         q1.blob2.length = 0;
1547         q1.blob2.size = 0;
1548         q1.blob2.data = NULL;
1549         q1.product.string = "product string";
1550
1551         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
1552
1553         *async_counter = 0;
1554
1555         for (i=0;i<ASYNC_COUNT;i++) {
1556                 creds_client_authenticator(creds, &a);
1557
1558                 creds_async[i] = (struct creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
1559                 req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, tctx, &r);
1560
1561                 req[i]->async.callback = async_callback;
1562                 req[i]->async.private_data = async_counter;
1563
1564                 /* even with this flush per request a w2k3 server seems to 
1565                    clag with multiple outstanding requests. bleergh. */
1566                 torture_assert_int_equal(tctx, event_loop_once(dcerpc_event_context(p)), 0, 
1567                                          "event_loop_once failed");
1568         }
1569
1570         for (i=0;i<ASYNC_COUNT;i++) {
1571                 status = dcerpc_ndr_request_recv(req[i]);
1572
1573                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
1574                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
1575
1576                 torture_assert(tctx, creds_client_check(creds_async[i], &a.cred), 
1577                         "Credential chaining failed at async");
1578         }
1579
1580         torture_comment(tctx, 
1581                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", *async_counter);
1582
1583         torture_assert_int_equal(tctx, (*async_counter), ASYNC_COUNT, "int");
1584
1585         return true;
1586 }
1587
1588 static bool test_ManyGetDCName(struct torture_context *tctx, 
1589                                struct dcerpc_pipe *p)
1590 {
1591         NTSTATUS status;
1592         struct dcerpc_pipe *p2;
1593         struct lsa_ObjectAttribute attr;
1594         struct lsa_QosInfo qos;
1595         struct lsa_OpenPolicy2 o;
1596         struct policy_handle lsa_handle;
1597         struct lsa_DomainList domains;
1598
1599         struct lsa_EnumTrustDom t;
1600         uint32_t resume_handle = 0;
1601         struct netr_GetAnyDCName d;
1602         const char *dcname = NULL;
1603
1604         int i;
1605
1606         if (p->conn->transport.transport != NCACN_NP) {
1607                 return true;
1608         }
1609
1610         torture_comment(tctx, "Torturing GetDCName\n");
1611
1612         status = dcerpc_secondary_connection(p, &p2, p->binding);
1613         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
1614
1615         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
1616         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
1617
1618         qos.len = 0;
1619         qos.impersonation_level = 2;
1620         qos.context_mode = 1;
1621         qos.effective_only = 0;
1622
1623         attr.len = 0;
1624         attr.root_dir = NULL;
1625         attr.object_name = NULL;
1626         attr.attributes = 0;
1627         attr.sec_desc = NULL;
1628         attr.sec_qos = &qos;
1629
1630         o.in.system_name = "\\";
1631         o.in.attr = &attr;
1632         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1633         o.out.handle = &lsa_handle;
1634
1635         status = dcerpc_lsa_OpenPolicy2(p2, tctx, &o);
1636         torture_assert_ntstatus_ok(tctx, status, "OpenPolicy2 failed");
1637
1638         t.in.handle = &lsa_handle;
1639         t.in.resume_handle = &resume_handle;
1640         t.in.max_size = 1000;
1641         t.out.domains = &domains;
1642         t.out.resume_handle = &resume_handle;
1643
1644         status = dcerpc_lsa_EnumTrustDom(p2, tctx, &t);
1645
1646         if ((!NT_STATUS_IS_OK(status) &&
1647              (!NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))))
1648                 torture_fail(tctx, "Could not list domains");
1649
1650         talloc_free(p2);
1651
1652         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
1653                                             dcerpc_server_name(p));
1654         d.out.dcname = &dcname;
1655
1656         for (i=0; i<domains.count * 4; i++) {
1657                 struct lsa_DomainInfo *info =
1658                         &domains.domains[rand()%domains.count];
1659
1660                 d.in.domainname = info->name.string;
1661
1662                 status = dcerpc_netr_GetAnyDCName(p, tctx, &d);
1663                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1664
1665                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
1666                        dcname ? dcname : "unknown");
1667         }
1668
1669         return true;
1670 }
1671
1672 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
1673 {
1674         struct torture_suite *suite = torture_suite_create(mem_ctx, "NETLOGON");
1675         struct torture_rpc_tcase *tcase;
1676         struct torture_test *test;
1677
1678         tcase = torture_suite_add_machine_rpc_iface_tcase(suite, "netlogon", 
1679                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
1680
1681         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
1682         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
1683         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
1684         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
1685         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
1686         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
1687         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
1688         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
1689         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
1690         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
1691         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
1692         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
1693         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
1694         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
1695         torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
1696         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
1697         torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
1698         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
1699         torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
1700         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
1701         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
1702         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
1703         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
1704         test->dangerous = true;
1705         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
1706         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
1707         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
1708         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
1709         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
1710         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
1711
1712         return suite;
1713 }