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