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