s3-rpc_server: Pass in our flags to netlogon_creds_server_init().
[mat/samba.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    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "lib/events/events.h"
27 #include "lib/cmdline/popt_common.h"
28 #include "torture/rpc/torture_rpc.h"
29 #include "../lib/crypto/crypto.h"
30 #include "libcli/auth/libcli_auth.h"
31 #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 #include "librpc/gen_ndr/ndr_lsa_c.h"
33 #include "param/param.h"
34 #include "libcli/security/security.h"
35 #include <ldb.h>
36 #include "lib/util/util_ldb.h"
37 #include "ldb_wrap.h"
38 #include "lib/replace/system/network.h"
39 #include "dsdb/samdb/samdb.h"
40
41 #define TEST_MACHINE_NAME "torturetest"
42
43 static bool test_LogonUasLogon(struct torture_context *tctx, 
44                                struct dcerpc_pipe *p)
45 {
46         NTSTATUS status;
47         struct netr_LogonUasLogon r;
48         struct netr_UasInfo *info = NULL;
49         struct dcerpc_binding_handle *b = p->binding_handle;
50
51         r.in.server_name = NULL;
52         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
53         r.in.workstation = TEST_MACHINE_NAME;
54         r.out.info = &info;
55
56         status = dcerpc_netr_LogonUasLogon_r(b, tctx, &r);
57         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogon");
58
59         return true;
60 }
61
62 static bool test_LogonUasLogoff(struct torture_context *tctx,
63                                 struct dcerpc_pipe *p)
64 {
65         NTSTATUS status;
66         struct netr_LogonUasLogoff r;
67         struct netr_UasLogoffInfo info;
68         struct dcerpc_binding_handle *b = p->binding_handle;
69
70         r.in.server_name = NULL;
71         r.in.account_name = cli_credentials_get_username(cmdline_credentials);
72         r.in.workstation = TEST_MACHINE_NAME;
73         r.out.info = &info;
74
75         status = dcerpc_netr_LogonUasLogoff_r(b, tctx, &r);
76         torture_assert_ntstatus_ok(tctx, status, "LogonUasLogoff");
77
78         return true;
79 }
80
81 bool test_SetupCredentials(struct dcerpc_pipe *p, struct torture_context *tctx,
82                                   struct cli_credentials *credentials,
83                                   struct netlogon_creds_CredentialState **creds_out)
84 {
85         struct netr_ServerReqChallenge r;
86         struct netr_ServerAuthenticate a;
87         struct netr_Credential credentials1, credentials2, credentials3;
88         struct netlogon_creds_CredentialState *creds;
89         const struct samr_Password *mach_password;
90         const char *machine_name;
91         struct dcerpc_binding_handle *b = p->binding_handle;
92
93         mach_password = cli_credentials_get_nt_hash(credentials, tctx);
94         machine_name = cli_credentials_get_workstation(credentials);
95
96         torture_comment(tctx, "Testing ServerReqChallenge\n");
97
98         r.in.server_name = NULL;
99         r.in.computer_name = machine_name;
100         r.in.credentials = &credentials1;
101         r.out.return_credentials = &credentials2;
102
103         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
104
105         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
106                 "ServerReqChallenge failed");
107         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
108
109         a.in.server_name = NULL;
110         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
111         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(credentials);
112         a.in.computer_name = machine_name;
113         a.in.credentials = &credentials3;
114         a.out.return_credentials = &credentials3;
115
116         creds = netlogon_creds_client_init(tctx, a.in.account_name,
117                                            a.in.computer_name,
118                                            &credentials1, &credentials2, 
119                                            mach_password, &credentials3, 
120                                            0);
121         torture_assert(tctx, creds != NULL, "memory allocation");
122
123
124         torture_comment(tctx, "Testing ServerAuthenticate\n");
125
126         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate_r(b, tctx, &a),
127                 "ServerAuthenticate failed");
128
129         /* This allows the tests to continue against the more fussy windows 2008 */
130         if (NT_STATUS_EQUAL(a.out.result, NT_STATUS_DOWNGRADE_DETECTED)) {
131                 return test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
132                                               credentials,
133                                               cli_credentials_get_secure_channel_type(credentials),
134                                               creds_out);
135         }
136
137         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate");
138
139         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
140                        "Credential chaining failed");
141
142         *creds_out = creds;
143         return true;
144 }
145
146 bool test_SetupCredentials2(struct dcerpc_pipe *p, struct torture_context *tctx,
147                             uint32_t negotiate_flags,
148                             struct cli_credentials *machine_credentials,
149                             enum netr_SchannelType sec_chan_type,
150                             struct netlogon_creds_CredentialState **creds_out)
151 {
152         struct netr_ServerReqChallenge r;
153         struct netr_ServerAuthenticate2 a;
154         struct netr_Credential credentials1, credentials2, credentials3;
155         struct netlogon_creds_CredentialState *creds;
156         const struct samr_Password *mach_password;
157         const char *machine_name;
158         struct dcerpc_binding_handle *b = p->binding_handle;
159
160         mach_password = cli_credentials_get_nt_hash(machine_credentials, tctx);
161         machine_name = cli_credentials_get_workstation(machine_credentials);
162
163         torture_comment(tctx, "Testing ServerReqChallenge\n");
164
165
166         r.in.server_name = NULL;
167         r.in.computer_name = machine_name;
168         r.in.credentials = &credentials1;
169         r.out.return_credentials = &credentials2;
170
171         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
172
173         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
174                 "ServerReqChallenge failed");
175         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
176
177         a.in.server_name = NULL;
178         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
179         a.in.secure_channel_type = sec_chan_type;
180         a.in.computer_name = machine_name;
181         a.in.negotiate_flags = &negotiate_flags;
182         a.out.negotiate_flags = &negotiate_flags;
183         a.in.credentials = &credentials3;
184         a.out.return_credentials = &credentials3;
185
186         creds = netlogon_creds_client_init(tctx, a.in.account_name,
187                                            a.in.computer_name, 
188                                            &credentials1, &credentials2, 
189                                            mach_password, &credentials3, 
190                                            negotiate_flags);
191
192         torture_assert(tctx, creds != NULL, "memory allocation");
193
194         torture_comment(tctx, "Testing ServerAuthenticate2\n");
195
196         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate2_r(b, tctx, &a),
197                 "ServerAuthenticate2 failed");
198         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate2 failed");
199
200         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), 
201                 "Credential chaining failed");
202
203         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
204
205         *creds_out = creds;
206         return true;
207 }
208
209
210 bool test_SetupCredentials3(struct dcerpc_pipe *p, struct torture_context *tctx,
211                             uint32_t negotiate_flags,
212                             struct cli_credentials *machine_credentials,
213                             struct netlogon_creds_CredentialState **creds_out)
214 {
215         struct netr_ServerReqChallenge r;
216         struct netr_ServerAuthenticate3 a;
217         struct netr_Credential credentials1, credentials2, credentials3;
218         struct netlogon_creds_CredentialState *creds;
219         struct samr_Password mach_password;
220         uint32_t rid;
221         const char *machine_name;
222         const char *plain_pass;
223         struct dcerpc_binding_handle *b = p->binding_handle;
224
225         machine_name = cli_credentials_get_workstation(machine_credentials);
226         plain_pass = cli_credentials_get_password(machine_credentials);
227
228         torture_comment(tctx, "Testing ServerReqChallenge\n");
229
230         r.in.server_name = NULL;
231         r.in.computer_name = machine_name;
232         r.in.credentials = &credentials1;
233         r.out.return_credentials = &credentials2;
234
235         generate_random_buffer(credentials1.data, sizeof(credentials1.data));
236
237         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
238                 "ServerReqChallenge failed");
239         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
240
241         E_md4hash(plain_pass, mach_password.hash);
242
243         a.in.server_name = NULL;
244         a.in.account_name = talloc_asprintf(tctx, "%s$", machine_name);
245         a.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
246         a.in.computer_name = machine_name;
247         a.in.negotiate_flags = &negotiate_flags;
248         a.in.credentials = &credentials3;
249         a.out.return_credentials = &credentials3;
250         a.out.negotiate_flags = &negotiate_flags;
251         a.out.rid = &rid;
252
253         creds = netlogon_creds_client_init(tctx, a.in.account_name,
254                                            a.in.computer_name,
255                                            &credentials1, &credentials2, 
256                                            &mach_password, &credentials3,
257                                            negotiate_flags);
258         
259         torture_assert(tctx, creds != NULL, "memory allocation");
260
261         torture_comment(tctx, "Testing ServerAuthenticate3\n");
262
263         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerAuthenticate3_r(b, tctx, &a),
264                 "ServerAuthenticate3 failed");
265         torture_assert_ntstatus_ok(tctx, a.out.result, "ServerAuthenticate3 failed");
266         torture_assert(tctx, netlogon_creds_client_check(creds, &credentials3), "Credential chaining failed");
267
268         torture_comment(tctx, "negotiate_flags=0x%08x\n", negotiate_flags);
269         
270         /* Prove that requesting a challenge again won't break it */
271         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerReqChallenge_r(b, tctx, &r),
272                 "ServerReqChallenge failed");
273         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerReqChallenge failed");
274
275         *creds_out = creds;
276         return true;
277 }
278
279 /*
280   try a change password for our machine account
281 */
282 static bool test_SetPassword(struct torture_context *tctx, 
283                              struct dcerpc_pipe *p,
284                              struct cli_credentials *machine_credentials)
285 {
286         struct netr_ServerPasswordSet r;
287         const char *password;
288         struct netlogon_creds_CredentialState *creds;
289         struct netr_Authenticator credential, return_authenticator;
290         struct samr_Password new_password;
291         struct dcerpc_binding_handle *b = p->binding_handle;
292
293         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
294                 return false;
295         }
296
297         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
298         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
299         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
300         r.in.computer_name = TEST_MACHINE_NAME;
301         r.in.credential = &credential;
302         r.in.new_password = &new_password;
303         r.out.return_authenticator = &return_authenticator;
304
305         password = generate_random_password(tctx, 8, 255);
306         E_md4hash(password, new_password.hash);
307
308         netlogon_creds_des_encrypt(creds, &new_password);
309
310         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
311         torture_comment(tctx, "Changing machine account password to '%s'\n", 
312                         password);
313
314         netlogon_creds_client_authenticator(creds, &credential);
315
316         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
317                 "ServerPasswordSet failed");
318         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
319
320         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
321                 torture_comment(tctx, "Credential chaining failed\n");
322         }
323
324         /* by changing the machine password twice we test the
325            credentials chaining fully, and we verify that the server
326            allows the password to be set to the same value twice in a
327            row (match win2k3) */
328         torture_comment(tctx, 
329                 "Testing a second ServerPasswordSet on machine account\n");
330         torture_comment(tctx, 
331                 "Changing machine account password to '%s' (same as previous run)\n", password);
332
333         netlogon_creds_client_authenticator(creds, &credential);
334
335         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
336                 "ServerPasswordSet (2) failed");
337         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
338
339         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
340                 torture_comment(tctx, "Credential chaining failed\n");
341         }
342
343         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
344
345         torture_assert(tctx, 
346                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
347                 "ServerPasswordSet failed to actually change the password");
348
349         return true;
350 }
351
352 /*
353   try a change password for our machine account
354 */
355 static bool test_SetPassword_flags(struct torture_context *tctx,
356                                    struct dcerpc_pipe *p,
357                                    struct cli_credentials *machine_credentials,
358                                    uint32_t negotiate_flags)
359 {
360         struct netr_ServerPasswordSet r;
361         const char *password;
362         struct netlogon_creds_CredentialState *creds;
363         struct netr_Authenticator credential, return_authenticator;
364         struct samr_Password new_password;
365         struct dcerpc_binding_handle *b = p->binding_handle;
366
367         if (!test_SetupCredentials2(p, tctx, negotiate_flags,
368                                     machine_credentials,
369                                     cli_credentials_get_secure_channel_type(machine_credentials),
370                                     &creds)) {
371                 return false;
372         }
373
374         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
375         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
376         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
377         r.in.computer_name = TEST_MACHINE_NAME;
378         r.in.credential = &credential;
379         r.in.new_password = &new_password;
380         r.out.return_authenticator = &return_authenticator;
381
382         password = generate_random_password(tctx, 8, 255);
383         E_md4hash(password, new_password.hash);
384
385         netlogon_creds_des_encrypt(creds, &new_password);
386
387         torture_comment(tctx, "Testing ServerPasswordSet on machine account\n");
388         torture_comment(tctx, "Changing machine account password to '%s'\n",
389                         password);
390
391         netlogon_creds_client_authenticator(creds, &credential);
392
393         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
394                 "ServerPasswordSet failed");
395         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet failed");
396
397         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
398                 torture_comment(tctx, "Credential chaining failed\n");
399         }
400
401         /* by changing the machine password twice we test the
402            credentials chaining fully, and we verify that the server
403            allows the password to be set to the same value twice in a
404            row (match win2k3) */
405         torture_comment(tctx,
406                 "Testing a second ServerPasswordSet on machine account\n");
407         torture_comment(tctx,
408                 "Changing machine account password to '%s' (same as previous run)\n", password);
409
410         netlogon_creds_client_authenticator(creds, &credential);
411
412         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet_r(b, tctx, &r),
413                 "ServerPasswordSet (2) failed");
414         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (2) failed");
415
416         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
417                 torture_comment(tctx, "Credential chaining failed\n");
418         }
419
420         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
421
422         torture_assert(tctx,
423                 test_SetupCredentials(p, tctx, machine_credentials, &creds),
424                 "ServerPasswordSet failed to actually change the password");
425
426         return true;
427 }
428
429
430 /*
431   generate a random password for password change tests
432 */
433 static DATA_BLOB netlogon_very_rand_pass(TALLOC_CTX *mem_ctx, int len)
434 {
435         int i;
436         DATA_BLOB password = data_blob_talloc(mem_ctx, NULL, len * 2 /* number of unicode chars */);
437         generate_random_buffer(password.data, password.length);
438
439         for (i=0; i < len; i++) {
440                 if (((uint16_t *)password.data)[i] == 0) {
441                         ((uint16_t *)password.data)[i] = 1;
442                 }
443         }
444
445         return password;
446 }
447
448 /*
449   try a change password for our machine account
450 */
451 static bool test_SetPassword2(struct torture_context *tctx, 
452                               struct dcerpc_pipe *p, 
453                               struct cli_credentials *machine_credentials)
454 {
455         struct netr_ServerPasswordSet2 r;
456         const char *password;
457         DATA_BLOB new_random_pass;
458         struct netlogon_creds_CredentialState *creds;
459         struct samr_CryptPassword password_buf;
460         struct samr_Password nt_hash;
461         struct netr_Authenticator credential, return_authenticator;
462         struct netr_CryptPassword new_password;
463         struct dcerpc_binding_handle *b = p->binding_handle;
464
465         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
466                 return false;
467         }
468
469         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
470         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
471         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
472         r.in.computer_name = TEST_MACHINE_NAME;
473         r.in.credential = &credential;
474         r.in.new_password = &new_password;
475         r.out.return_authenticator = &return_authenticator;
476
477         password = generate_random_password(tctx, 8, 255);
478         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
479         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
480
481         memcpy(new_password.data, password_buf.data, 512);
482         new_password.length = IVAL(password_buf.data, 512);
483
484         torture_comment(tctx, "Testing ServerPasswordSet2 on machine account\n");
485         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
486
487         netlogon_creds_client_authenticator(creds, &credential);
488
489         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
490                 "ServerPasswordSet2 failed");
491         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
492
493         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
494                 torture_comment(tctx, "Credential chaining failed\n");
495         }
496
497         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
498
499         if (!torture_setting_bool(tctx, "dangerous", false)) {
500                 torture_comment(tctx, 
501                         "Not testing ability to set password to '', enable dangerous tests to perform this test\n");
502         } else {
503                 /* by changing the machine password to ""
504                  * we check if the server uses password restrictions
505                  * for ServerPasswordSet2
506                  * (win2k3 accepts "")
507                  */
508                 password = "";
509                 encode_pw_buffer(password_buf.data, password, STR_UNICODE);
510                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
511                 
512                 memcpy(new_password.data, password_buf.data, 512);
513                 new_password.length = IVAL(password_buf.data, 512);
514                 
515                 torture_comment(tctx, 
516                         "Testing ServerPasswordSet2 on machine account\n");
517                 torture_comment(tctx, 
518                         "Changing machine account password to '%s'\n", password);
519                 
520                 netlogon_creds_client_authenticator(creds, &credential);
521                 
522                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
523                         "ServerPasswordSet2 failed");
524                 torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 failed");
525                 
526                 if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
527                         torture_comment(tctx, "Credential chaining failed\n");
528                 }
529                 
530                 cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
531         }
532
533         torture_assert(tctx, test_SetupCredentials(p, tctx, machine_credentials, &creds), 
534                 "ServerPasswordSet failed to actually change the password");
535
536         /* now try a random password */
537         password = generate_random_password(tctx, 8, 255);
538         encode_pw_buffer(password_buf.data, password, STR_UNICODE);
539         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
540
541         memcpy(new_password.data, password_buf.data, 512);
542         new_password.length = IVAL(password_buf.data, 512);
543
544         torture_comment(tctx, "Testing second ServerPasswordSet2 on machine account\n");
545         torture_comment(tctx, "Changing machine account password to '%s'\n", password);
546
547         netlogon_creds_client_authenticator(creds, &credential);
548
549         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
550                 "ServerPasswordSet2 (2) failed");
551         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet2 (2) failed");
552
553         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
554                 torture_comment(tctx, "Credential chaining failed\n");
555         }
556
557         /* by changing the machine password twice we test the
558            credentials chaining fully, and we verify that the server
559            allows the password to be set to the same value twice in a
560            row (match win2k3) */
561         torture_comment(tctx, 
562                 "Testing a second ServerPasswordSet2 on machine account\n");
563         torture_comment(tctx, 
564                 "Changing machine account password to '%s' (same as previous run)\n", password);
565
566         netlogon_creds_client_authenticator(creds, &credential);
567
568         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
569                 "ServerPasswordSet (3) failed");
570         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
571
572         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
573                 torture_comment(tctx, "Credential chaining failed\n");
574         }
575
576         cli_credentials_set_password(machine_credentials, password, CRED_SPECIFIED);
577
578         torture_assert (tctx, 
579                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
580                 "ServerPasswordSet failed to actually change the password");
581
582         new_random_pass = netlogon_very_rand_pass(tctx, 128);
583
584         /* now try a random stream of bytes for a password */
585         set_pw_in_buffer(password_buf.data, &new_random_pass);
586
587         netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
588
589         memcpy(new_password.data, password_buf.data, 512);
590         new_password.length = IVAL(password_buf.data, 512);
591
592         torture_comment(tctx, 
593                 "Testing a third ServerPasswordSet2 on machine account, with a completely random password\n");
594
595         netlogon_creds_client_authenticator(creds, &credential);
596
597         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerPasswordSet2_r(b, tctx, &r),
598                 "ServerPasswordSet (3) failed");
599         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerPasswordSet (3) failed");
600
601         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
602                 torture_comment(tctx, "Credential chaining failed\n");
603         }
604
605         mdfour(nt_hash.hash, new_random_pass.data, new_random_pass.length);
606
607         cli_credentials_set_password(machine_credentials, NULL, CRED_UNINITIALISED);
608         cli_credentials_set_nt_hash(machine_credentials, &nt_hash, CRED_SPECIFIED);
609
610         torture_assert (tctx, 
611                 test_SetupCredentials(p, tctx, machine_credentials, &creds), 
612                 "ServerPasswordSet failed to actually change the password");
613
614         return true;
615 }
616
617 static bool test_GetPassword(struct torture_context *tctx,
618                              struct dcerpc_pipe *p,
619                              struct cli_credentials *machine_credentials)
620 {
621         struct netr_ServerPasswordGet r;
622         struct netlogon_creds_CredentialState *creds;
623         struct netr_Authenticator credential;
624         NTSTATUS status;
625         struct netr_Authenticator return_authenticator;
626         struct samr_Password password;
627         struct dcerpc_binding_handle *b = p->binding_handle;
628
629         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
630                 return false;
631         }
632
633         netlogon_creds_client_authenticator(creds, &credential);
634
635         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
636         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
637         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
638         r.in.computer_name = TEST_MACHINE_NAME;
639         r.in.credential = &credential;
640         r.out.return_authenticator = &return_authenticator;
641         r.out.password = &password;
642
643         status = dcerpc_netr_ServerPasswordGet_r(b, tctx, &r);
644         torture_assert_ntstatus_ok(tctx, status, "ServerPasswordGet");
645
646         return true;
647 }
648
649 static bool test_GetTrustPasswords(struct torture_context *tctx,
650                                    struct dcerpc_pipe *p,
651                                    struct cli_credentials *machine_credentials)
652 {
653         struct netr_ServerTrustPasswordsGet r;
654         struct netlogon_creds_CredentialState *creds;
655         struct netr_Authenticator credential;
656         struct netr_Authenticator return_authenticator;
657         struct samr_Password password, password2;
658         struct dcerpc_binding_handle *b = p->binding_handle;
659
660         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
661                 return false;
662         }
663
664         netlogon_creds_client_authenticator(creds, &credential);
665
666         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
667         r.in.account_name = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
668         r.in.secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
669         r.in.computer_name = TEST_MACHINE_NAME;
670         r.in.credential = &credential;
671         r.out.return_authenticator = &return_authenticator;
672         r.out.password = &password;
673         r.out.password2 = &password2;
674
675         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerTrustPasswordsGet_r(b, tctx, &r),
676                 "ServerTrustPasswordsGet failed");
677         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerTrustPasswordsGet failed");
678
679         return true;
680 }
681
682 /*
683   try a netlogon SamLogon
684 */
685 static bool test_netlogon_ops_args(struct dcerpc_pipe *p, struct torture_context *tctx,
686                                    struct cli_credentials *credentials,
687                                    struct netlogon_creds_CredentialState *creds,
688                                    bool null_domain)
689 {
690         NTSTATUS status;
691         struct netr_LogonSamLogon r;
692         struct netr_Authenticator auth, auth2;
693         static const struct netr_Authenticator auth_zero;
694         union netr_LogonLevel logon;
695         union netr_Validation validation;
696         uint8_t authoritative;
697         struct netr_NetworkInfo ninfo;
698         DATA_BLOB names_blob, chal, lm_resp, nt_resp;
699         int i;
700         struct dcerpc_binding_handle *b = p->binding_handle;
701         int flags = CLI_CRED_NTLM_AUTH;
702         if (lpcfg_client_lanman_auth(tctx->lp_ctx)) {
703                 flags |= CLI_CRED_LANMAN_AUTH;
704         }
705
706         if (lpcfg_client_ntlmv2_auth(tctx->lp_ctx) && !null_domain) {
707                 flags |= CLI_CRED_NTLMv2_AUTH;
708         }
709
710         cli_credentials_get_ntlm_username_domain(cmdline_credentials, tctx, 
711                                                  &ninfo.identity_info.account_name.string,
712                                                  &ninfo.identity_info.domain_name.string);
713
714         if (null_domain) {
715                 ninfo.identity_info.domain_name.string = NULL;
716         }
717
718         generate_random_buffer(ninfo.challenge, 
719                                sizeof(ninfo.challenge));
720         chal = data_blob_const(ninfo.challenge, 
721                                sizeof(ninfo.challenge));
722
723         names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(credentials), 
724                                                 cli_credentials_get_domain(credentials));
725
726         status = cli_credentials_get_ntlm_response(cmdline_credentials, tctx, 
727                                                    &flags, 
728                                                    chal,
729                                                    names_blob,
730                                                    &lm_resp, &nt_resp,
731                                                    NULL, NULL);
732         torture_assert_ntstatus_ok(tctx, status, "cli_credentials_get_ntlm_response failed");
733
734         ninfo.lm.data = lm_resp.data;
735         ninfo.lm.length = lm_resp.length;
736
737         ninfo.nt.data = nt_resp.data;
738         ninfo.nt.length = nt_resp.length;
739
740         ninfo.identity_info.parameter_control = 0;
741         ninfo.identity_info.logon_id_low = 0;
742         ninfo.identity_info.logon_id_high = 0;
743         ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials);
744
745         logon.network = &ninfo;
746
747         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
748         r.in.computer_name = cli_credentials_get_workstation(credentials);
749         r.in.credential = &auth;
750         r.in.return_authenticator = &auth2;
751         r.in.logon_level = 2;
752         r.in.logon = &logon;
753         r.out.validation = &validation;
754         r.out.authoritative = &authoritative;
755
756         d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
757         
758         for (i=2;i<=3;i++) {
759                 ZERO_STRUCT(auth2);
760                 netlogon_creds_client_authenticator(creds, &auth);
761                 
762                 r.in.validation_level = i;
763                 
764                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
765                         "LogonSamLogon failed");
766                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
767                 
768                 torture_assert(tctx, netlogon_creds_client_check(creds, 
769                                                                  &r.out.return_authenticator->cred), 
770                         "Credential chaining failed");
771                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
772                                          "LogonSamLogon invalid  *r.out.authoritative");
773         }
774
775         /* this makes sure we get the unmarshalling right for invalid levels */
776         for (i=52;i<53;i++) {
777                 ZERO_STRUCT(auth2);
778                 /* the authenticator should be ignored by the server */
779                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
780
781                 r.in.validation_level = i;
782
783                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
784                                            "LogonSamLogon failed");
785                 torture_assert_ntstatus_equal(tctx, r.out.result,
786                                               NT_STATUS_INVALID_INFO_CLASS,
787                                               "LogonSamLogon failed");
788
789                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
790                                          "LogonSamLogon invalid  *r.out.authoritative");
791                 torture_assert(tctx,
792                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
793                                "Return authenticator non zero");
794         }
795
796         for (i=2;i<=3;i++) {
797                 ZERO_STRUCT(auth2);
798                 netlogon_creds_client_authenticator(creds, &auth);
799
800                 r.in.validation_level = i;
801
802                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
803                         "LogonSamLogon failed");
804                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
805
806                 torture_assert(tctx, netlogon_creds_client_check(creds,
807                                                                  &r.out.return_authenticator->cred),
808                         "Credential chaining failed");
809                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
810                                          "LogonSamLogon invalid  *r.out.authoritative");
811         }
812
813         r.in.logon_level = 52;
814
815         for (i=2;i<=3;i++) {
816                 ZERO_STRUCT(auth2);
817                 /* the authenticator should be ignored by the server */
818                 generate_random_buffer((uint8_t *) &auth, sizeof(auth));
819
820                 r.in.validation_level = i;
821
822                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
823
824                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
825                         "LogonSamLogon failed");
826                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
827                         "LogonSamLogon expected INVALID_PARAMETER");
828
829                 torture_assert(tctx,
830                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
831                                "Return authenticator non zero");
832                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
833                                          "LogonSamLogon invalid  *r.out.authoritative");
834         }
835
836         r.in.credential = NULL;
837
838         for (i=2;i<=3;i++) {
839                 ZERO_STRUCT(auth2);
840
841                 r.in.validation_level = i;
842
843                 torture_comment(tctx, "Testing SamLogon with validation level %d and a NULL credential\n", i);
844
845                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
846                         "LogonSamLogon failed");
847                 torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_INVALID_PARAMETER,
848                         "LogonSamLogon expected INVALID_PARAMETER");
849
850                 torture_assert(tctx,
851                                memcmp(&auth2, &auth_zero, sizeof(auth2)) == 0,
852                                "Return authenticator non zero");
853                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
854                                          "LogonSamLogon invalid  *r.out.authoritative");
855         }
856
857         r.in.logon_level = 2;
858         r.in.credential = &auth;
859
860         for (i=2;i<=3;i++) {
861                 ZERO_STRUCT(auth2);
862                 netlogon_creds_client_authenticator(creds, &auth);
863
864                 r.in.validation_level = i;
865
866                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonSamLogon_r(b, tctx, &r),
867                         "LogonSamLogon failed");
868                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonSamLogon failed");
869
870                 torture_assert(tctx, netlogon_creds_client_check(creds,
871                                                                  &r.out.return_authenticator->cred),
872                         "Credential chaining failed");
873                 torture_assert_int_equal(tctx, *r.out.authoritative, 1,
874                                          "LogonSamLogon invalid  *r.out.authoritative");
875         }
876
877         return true;
878 }
879
880 bool test_netlogon_ops(struct dcerpc_pipe *p, struct torture_context *tctx,
881                        struct cli_credentials *credentials,
882                        struct netlogon_creds_CredentialState *creds)
883 {
884         return test_netlogon_ops_args(p, tctx, credentials, creds, false);
885 }
886
887 /*
888   try a netlogon SamLogon
889 */
890 static bool test_SamLogon(struct torture_context *tctx, 
891                           struct dcerpc_pipe *p,
892                           struct cli_credentials *credentials)
893 {
894         struct netlogon_creds_CredentialState *creds;
895
896         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
897                 return false;
898         }
899
900         return test_netlogon_ops(p, tctx, credentials, creds);
901 }
902
903 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
904                                       struct dcerpc_pipe *p,
905                                       struct cli_credentials *credentials)
906 {
907         struct netlogon_creds_CredentialState *creds;
908
909         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
910                 return false;
911         }
912
913         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
914 }
915
916 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
917 static uint64_t sequence_nums[3];
918
919 /*
920   try a netlogon DatabaseSync
921 */
922 static bool test_DatabaseSync(struct torture_context *tctx, 
923                               struct dcerpc_pipe *p,
924                               struct cli_credentials *machine_credentials)
925 {
926         struct netr_DatabaseSync r;
927         struct netlogon_creds_CredentialState *creds;
928         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
929         int i;
930         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
931         struct netr_Authenticator credential, return_authenticator;
932         struct dcerpc_binding_handle *b = p->binding_handle;
933
934         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
935                 return false;
936         }
937
938         ZERO_STRUCT(return_authenticator);
939
940         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
941         r.in.computername = TEST_MACHINE_NAME;
942         r.in.preferredmaximumlength = (uint32_t)-1;
943         r.in.return_authenticator = &return_authenticator;
944         r.out.delta_enum_array = &delta_enum_array;
945         r.out.return_authenticator = &return_authenticator;
946
947         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
948
949                 uint32_t sync_context = 0;
950
951                 r.in.database_id = database_ids[i];
952                 r.in.sync_context = &sync_context;
953                 r.out.sync_context = &sync_context;
954
955                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
956
957                 do {
958                         netlogon_creds_client_authenticator(creds, &credential);
959
960                         r.in.credential = &credential;
961
962                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
963                                 "DatabaseSync failed");
964                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
965                             break;
966
967                         /* Native mode servers don't do this */
968                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
969                                 return true;
970                         }
971                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
972
973                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
974                                 torture_comment(tctx, "Credential chaining failed\n");
975                         }
976
977                         if (delta_enum_array &&
978                             delta_enum_array->num_deltas > 0 &&
979                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
980                             delta_enum_array->delta_enum[0].delta_union.domain) {
981                                 sequence_nums[r.in.database_id] = 
982                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
983                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
984                                        r.in.database_id, 
985                                        (unsigned long long)sequence_nums[r.in.database_id]);
986                         }
987                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
988         }
989
990         return true;
991 }
992
993
994 /*
995   try a netlogon DatabaseDeltas
996 */
997 static bool test_DatabaseDeltas(struct torture_context *tctx, 
998                                 struct dcerpc_pipe *p,
999                                 struct cli_credentials *machine_credentials)
1000 {
1001         struct netr_DatabaseDeltas r;
1002         struct netlogon_creds_CredentialState *creds;
1003         struct netr_Authenticator credential;
1004         struct netr_Authenticator return_authenticator;
1005         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1006         const uint32_t database_ids[] = {0, 1, 2}; 
1007         int i;
1008         struct dcerpc_binding_handle *b = p->binding_handle;
1009
1010         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1011                 return false;
1012         }
1013
1014         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1015         r.in.computername = TEST_MACHINE_NAME;
1016         r.in.preferredmaximumlength = (uint32_t)-1;
1017         ZERO_STRUCT(r.in.return_authenticator);
1018         r.out.return_authenticator = &return_authenticator;
1019         r.out.delta_enum_array = &delta_enum_array;
1020
1021         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1022                 r.in.database_id = database_ids[i];
1023                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1024
1025                 if (*r.in.sequence_num == 0) continue;
1026
1027                 *r.in.sequence_num -= 1;
1028
1029                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
1030                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1031
1032                 do {
1033                         netlogon_creds_client_authenticator(creds, &credential);
1034
1035                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1036                                 "DatabaseDeltas failed");
1037                         if (NT_STATUS_EQUAL(r.out.result,
1038                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1039                                 torture_comment(tctx, "not considering %s to be an error\n",
1040                                        nt_errstr(r.out.result));
1041                                 return true;
1042                         }
1043                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1044                             break;
1045
1046                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1047
1048                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1049                                 torture_comment(tctx, "Credential chaining failed\n");
1050                         }
1051
1052                         (*r.in.sequence_num)++;
1053                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1054         }
1055
1056         return true;
1057 }
1058
1059 static bool test_DatabaseRedo(struct torture_context *tctx,
1060                               struct dcerpc_pipe *p,
1061                               struct cli_credentials *machine_credentials)
1062 {
1063         struct netr_DatabaseRedo r;
1064         struct netlogon_creds_CredentialState *creds;
1065         struct netr_Authenticator credential;
1066         struct netr_Authenticator return_authenticator;
1067         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1068         struct netr_ChangeLogEntry e;
1069         struct dom_sid null_sid, *sid;
1070         int i,d;
1071         struct dcerpc_binding_handle *b = p->binding_handle;
1072
1073         ZERO_STRUCT(null_sid);
1074
1075         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1076
1077         {
1078
1079         struct {
1080                 uint32_t rid;
1081                 uint16_t flags;
1082                 uint8_t db_index;
1083                 uint8_t delta_type;
1084                 struct dom_sid sid;
1085                 const char *name;
1086                 NTSTATUS expected_error;
1087                 uint32_t expected_num_results;
1088                 uint8_t expected_delta_type_1;
1089                 uint8_t expected_delta_type_2;
1090                 const char *comment;
1091         } changes[] = {
1092
1093                 /* SAM_DATABASE_DOMAIN */
1094
1095                 {
1096                         .rid                    = 0,
1097                         .flags                  = 0,
1098                         .db_index               = SAM_DATABASE_DOMAIN,
1099                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1100                         .sid                    = null_sid,
1101                         .name                   = NULL,
1102                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1103                         .expected_num_results   = 0,
1104                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1105                 },
1106                 {
1107                         .rid                    = 0,
1108                         .flags                  = 0,
1109                         .db_index               = SAM_DATABASE_DOMAIN,
1110                         .delta_type             = 0,
1111                         .sid                    = null_sid,
1112                         .name                   = NULL,
1113                         .expected_error         = NT_STATUS_OK,
1114                         .expected_num_results   = 1,
1115                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1116                         .comment                = "NULL DELTA"
1117                 },
1118                 {
1119                         .rid                    = 0,
1120                         .flags                  = 0,
1121                         .db_index               = SAM_DATABASE_DOMAIN,
1122                         .delta_type             = NETR_DELTA_DOMAIN,
1123                         .sid                    = null_sid,
1124                         .name                   = NULL,
1125                         .expected_error         = NT_STATUS_OK,
1126                         .expected_num_results   = 1,
1127                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1128                         .comment                = "NETR_DELTA_DOMAIN"
1129                 },
1130                 {
1131                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1132                         .flags                  = 0,
1133                         .db_index               = SAM_DATABASE_DOMAIN,
1134                         .delta_type             = NETR_DELTA_USER,
1135                         .sid                    = null_sid,
1136                         .name                   = NULL,
1137                         .expected_error         = NT_STATUS_OK,
1138                         .expected_num_results   = 1,
1139                         .expected_delta_type_1  = NETR_DELTA_USER,
1140                         .comment                = "NETR_DELTA_USER by rid 500"
1141                 },
1142                 {
1143                         .rid                    = DOMAIN_RID_GUEST,
1144                         .flags                  = 0,
1145                         .db_index               = SAM_DATABASE_DOMAIN,
1146                         .delta_type             = NETR_DELTA_USER,
1147                         .sid                    = null_sid,
1148                         .name                   = NULL,
1149                         .expected_error         = NT_STATUS_OK,
1150                         .expected_num_results   = 1,
1151                         .expected_delta_type_1  = NETR_DELTA_USER,
1152                         .comment                = "NETR_DELTA_USER by rid 501"
1153                 },
1154                 {
1155                         .rid                    = 0,
1156                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1157                         .db_index               = SAM_DATABASE_DOMAIN,
1158                         .delta_type             = NETR_DELTA_USER,
1159                         .sid                    = *sid,
1160                         .name                   = NULL,
1161                         .expected_error         = NT_STATUS_OK,
1162                         .expected_num_results   = 1,
1163                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1164                         .comment                = "NETR_DELTA_USER by sid and flags"
1165                 },
1166                 {
1167                         .rid                    = 0,
1168                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1169                         .db_index               = SAM_DATABASE_DOMAIN,
1170                         .delta_type             = NETR_DELTA_USER,
1171                         .sid                    = null_sid,
1172                         .name                   = NULL,
1173                         .expected_error         = NT_STATUS_OK,
1174                         .expected_num_results   = 1,
1175                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1176                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1177                 },
1178                 {
1179                         .rid                    = 0,
1180                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1181                         .db_index               = SAM_DATABASE_DOMAIN,
1182                         .delta_type             = NETR_DELTA_USER,
1183                         .sid                    = null_sid,
1184                         .name                   = "administrator",
1185                         .expected_error         = NT_STATUS_OK,
1186                         .expected_num_results   = 1,
1187                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1188                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1189                 },
1190                 {
1191                         .rid                    = DOMAIN_RID_ADMINS,
1192                         .flags                  = 0,
1193                         .db_index               = SAM_DATABASE_DOMAIN,
1194                         .delta_type             = NETR_DELTA_GROUP,
1195                         .sid                    = null_sid,
1196                         .name                   = NULL,
1197                         .expected_error         = NT_STATUS_OK,
1198                         .expected_num_results   = 2,
1199                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1200                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1201                         .comment                = "NETR_DELTA_GROUP by rid 512"
1202                 },
1203                 {
1204                         .rid                    = DOMAIN_RID_ADMINS,
1205                         .flags                  = 0,
1206                         .db_index               = SAM_DATABASE_DOMAIN,
1207                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1208                         .sid                    = null_sid,
1209                         .name                   = NULL,
1210                         .expected_error         = NT_STATUS_OK,
1211                         .expected_num_results   = 2,
1212                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1213                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1214                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1215                 },
1216
1217
1218                 /* SAM_DATABASE_BUILTIN */
1219
1220                 {
1221                         .rid                    = 0,
1222                         .flags                  = 0,
1223                         .db_index               = SAM_DATABASE_BUILTIN,
1224                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1225                         .sid                    = null_sid,
1226                         .name                   = NULL,
1227                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1228                         .expected_num_results   = 0,
1229                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1230                 },
1231                 {
1232                         .rid                    = 0,
1233                         .flags                  = 0,
1234                         .db_index               = SAM_DATABASE_BUILTIN,
1235                         .delta_type             = NETR_DELTA_DOMAIN,
1236                         .sid                    = null_sid,
1237                         .name                   = NULL,
1238                         .expected_error         = NT_STATUS_OK,
1239                         .expected_num_results   = 1,
1240                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1241                         .comment                = "NETR_DELTA_DOMAIN"
1242                 },
1243                 {
1244                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1245                         .flags                  = 0,
1246                         .db_index               = SAM_DATABASE_BUILTIN,
1247                         .delta_type             = NETR_DELTA_USER,
1248                         .sid                    = null_sid,
1249                         .name                   = NULL,
1250                         .expected_error         = NT_STATUS_OK,
1251                         .expected_num_results   = 1,
1252                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1253                         .comment                = "NETR_DELTA_USER by rid 500"
1254                 },
1255                 {
1256                         .rid                    = 0,
1257                         .flags                  = 0,
1258                         .db_index               = SAM_DATABASE_BUILTIN,
1259                         .delta_type             = NETR_DELTA_USER,
1260                         .sid                    = null_sid,
1261                         .name                   = NULL,
1262                         .expected_error         = NT_STATUS_OK,
1263                         .expected_num_results   = 1,
1264                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1265                         .comment                = "NETR_DELTA_USER"
1266                 },
1267                 {
1268                         .rid                    = 544,
1269                         .flags                  = 0,
1270                         .db_index               = SAM_DATABASE_BUILTIN,
1271                         .delta_type             = NETR_DELTA_ALIAS,
1272                         .sid                    = null_sid,
1273                         .name                   = NULL,
1274                         .expected_error         = NT_STATUS_OK,
1275                         .expected_num_results   = 2,
1276                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1277                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1278                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1279                 },
1280                 {
1281                         .rid                    = 544,
1282                         .flags                  = 0,
1283                         .db_index               = SAM_DATABASE_BUILTIN,
1284                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1285                         .sid                    = null_sid,
1286                         .name                   = NULL,
1287                         .expected_error         = NT_STATUS_OK,
1288                         .expected_num_results   = 2,
1289                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1290                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1291                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1292                 },
1293                 {
1294                         .rid                    = 544,
1295                         .flags                  = 0,
1296                         .db_index               = SAM_DATABASE_BUILTIN,
1297                         .delta_type             = 0,
1298                         .sid                    = null_sid,
1299                         .name                   = NULL,
1300                         .expected_error         = NT_STATUS_OK,
1301                         .expected_num_results   = 1,
1302                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1303                         .comment                = "NULL DELTA by rid 544"
1304                 },
1305                 {
1306                         .rid                    = 544,
1307                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1308                         .db_index               = SAM_DATABASE_BUILTIN,
1309                         .delta_type             = 0,
1310                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1311                         .name                   = NULL,
1312                         .expected_error         = NT_STATUS_OK,
1313                         .expected_num_results   = 1,
1314                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1315                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1316                 },
1317                 {
1318                         .rid                    = 544,
1319                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1320                         .db_index               = SAM_DATABASE_BUILTIN,
1321                         .delta_type             = NETR_DELTA_ALIAS,
1322                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1323                         .name                   = NULL,
1324                         .expected_error         = NT_STATUS_OK,
1325                         .expected_num_results   = 2,
1326                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1327                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1328                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1329                 },
1330                 {
1331                         .rid                    = 0,
1332                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1333                         .db_index               = SAM_DATABASE_BUILTIN,
1334                         .delta_type             = NETR_DELTA_ALIAS,
1335                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1336                         .name                   = NULL,
1337                         .expected_error         = NT_STATUS_OK,
1338                         .expected_num_results   = 1,
1339                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1340                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1341                 },
1342
1343                 /* SAM_DATABASE_PRIVS */
1344
1345                 {
1346                         .rid                    = 0,
1347                         .flags                  = 0,
1348                         .db_index               = SAM_DATABASE_PRIVS,
1349                         .delta_type             = 0,
1350                         .sid                    = null_sid,
1351                         .name                   = NULL,
1352                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1353                         .expected_num_results   = 0,
1354                         .comment                = "NULL DELTA"
1355                 },
1356                 {
1357                         .rid                    = 0,
1358                         .flags                  = 0,
1359                         .db_index               = SAM_DATABASE_PRIVS,
1360                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1361                         .sid                    = null_sid,
1362                         .name                   = NULL,
1363                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1364                         .expected_num_results   = 0,
1365                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1366                 },
1367                 {
1368                         .rid                    = 0,
1369                         .flags                  = 0,
1370                         .db_index               = SAM_DATABASE_PRIVS,
1371                         .delta_type             = NETR_DELTA_POLICY,
1372                         .sid                    = null_sid,
1373                         .name                   = NULL,
1374                         .expected_error         = NT_STATUS_OK,
1375                         .expected_num_results   = 1,
1376                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1377                         .comment                = "NETR_DELTA_POLICY"
1378                 },
1379                 {
1380                         .rid                    = 0,
1381                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1382                         .db_index               = SAM_DATABASE_PRIVS,
1383                         .delta_type             = NETR_DELTA_POLICY,
1384                         .sid                    = null_sid,
1385                         .name                   = NULL,
1386                         .expected_error         = NT_STATUS_OK,
1387                         .expected_num_results   = 1,
1388                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1389                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1390                 },
1391                 {
1392                         .rid                    = 0,
1393                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1394                         .db_index               = SAM_DATABASE_PRIVS,
1395                         .delta_type             = NETR_DELTA_POLICY,
1396                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1397                         .name                   = NULL,
1398                         .expected_error         = NT_STATUS_OK,
1399                         .expected_num_results   = 1,
1400                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1401                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1402                 },
1403                 {
1404                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1405                         .flags                  = 0,
1406                         .db_index               = SAM_DATABASE_PRIVS,
1407                         .delta_type             = NETR_DELTA_ACCOUNT,
1408                         .sid                    = null_sid,
1409                         .name                   = NULL,
1410                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1411                         .expected_num_results   = 0,
1412                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1413                 },
1414                 {
1415                         .rid                    = 0,
1416                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1417                         .db_index               = SAM_DATABASE_PRIVS,
1418                         .delta_type             = NETR_DELTA_ACCOUNT,
1419                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1420                         .name                   = NULL,
1421                         .expected_error         = NT_STATUS_OK,
1422                         .expected_num_results   = 1,
1423                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1424                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1425                 },
1426                 {
1427                         .rid                    = 0,
1428                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1429                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1430                         .db_index               = SAM_DATABASE_PRIVS,
1431                         .delta_type             = NETR_DELTA_ACCOUNT,
1432                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1433                         .name                   = NULL,
1434                         .expected_error         = NT_STATUS_OK,
1435                         .expected_num_results   = 1,
1436                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1437                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1438                 },
1439                 {
1440                         .rid                    = 0,
1441                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1442                                                   NETR_CHANGELOG_NAME_INCLUDED,
1443                         .db_index               = SAM_DATABASE_PRIVS,
1444                         .delta_type             = NETR_DELTA_ACCOUNT,
1445                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1446                         .name                   = NULL,
1447                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1448                         .expected_num_results   = 0,
1449                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1450                 },
1451                 {
1452                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1453                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1454                         .db_index               = SAM_DATABASE_PRIVS,
1455                         .delta_type             = NETR_DELTA_ACCOUNT,
1456                         .sid                    = *sid,
1457                         .name                   = NULL,
1458                         .expected_error         = NT_STATUS_OK,
1459                         .expected_num_results   = 1,
1460                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1461                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1462                 },
1463                 {
1464                         .rid                    = 0,
1465                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1466                         .db_index               = SAM_DATABASE_PRIVS,
1467                         .delta_type             = NETR_DELTA_SECRET,
1468                         .sid                    = null_sid,
1469                         .name                   = "IsurelydontexistIhope",
1470                         .expected_error         = NT_STATUS_OK,
1471                         .expected_num_results   = 1,
1472                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1473                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1474                 },
1475                 {
1476                         .rid                    = 0,
1477                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1478                         .db_index               = SAM_DATABASE_PRIVS,
1479                         .delta_type             = NETR_DELTA_SECRET,
1480                         .sid                    = null_sid,
1481                         .name                   = "G$BCKUPKEY_P",
1482                         .expected_error         = NT_STATUS_OK,
1483                         .expected_num_results   = 1,
1484                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1485                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1486                 }
1487         };
1488
1489         ZERO_STRUCT(return_authenticator);
1490
1491         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1492         r.in.computername = TEST_MACHINE_NAME;
1493         r.in.return_authenticator = &return_authenticator;
1494         r.out.return_authenticator = &return_authenticator;
1495         r.out.delta_enum_array = &delta_enum_array;
1496
1497         for (d=0; d<3; d++) {
1498                 const char *database = NULL;
1499
1500                 switch (d) {
1501                 case 0:
1502                         database = "SAM";
1503                         break;
1504                 case 1:
1505                         database = "BUILTIN";
1506                         break;
1507                 case 2:
1508                         database = "LSA";
1509                         break;
1510                 default:
1511                         break;
1512                 }
1513
1514                 torture_comment(tctx, "Testing DatabaseRedo\n");
1515
1516                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1517                         return false;
1518                 }
1519
1520                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1521
1522                         if (d != changes[i].db_index) {
1523                                 continue;
1524                         }
1525
1526                         netlogon_creds_client_authenticator(creds, &credential);
1527
1528                         r.in.credential = &credential;
1529
1530                         e.serial_number1        = 0;
1531                         e.serial_number2        = 0;
1532                         e.object_rid            = changes[i].rid;
1533                         e.flags                 = changes[i].flags;
1534                         e.db_index              = changes[i].db_index;
1535                         e.delta_type            = changes[i].delta_type;
1536
1537                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1538                         case NETR_CHANGELOG_SID_INCLUDED:
1539                                 e.object.object_sid             = changes[i].sid;
1540                                 break;
1541                         case NETR_CHANGELOG_NAME_INCLUDED:
1542                                 e.object.object_name            = changes[i].name;
1543                                 break;
1544                         default:
1545                                 break;
1546                         }
1547
1548                         r.in.change_log_entry = e;
1549
1550                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1551                                 database, changes[i].comment);
1552
1553                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1554                                 "DatabaseRedo failed");
1555                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1556                                 return true;
1557                         }
1558
1559                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1560                         if (delta_enum_array) {
1561                                 torture_assert_int_equal(tctx,
1562                                         delta_enum_array->num_deltas,
1563                                         changes[i].expected_num_results,
1564                                         changes[i].comment);
1565                                 if (delta_enum_array->num_deltas > 0) {
1566                                         torture_assert_int_equal(tctx,
1567                                                 delta_enum_array->delta_enum[0].delta_type,
1568                                                 changes[i].expected_delta_type_1,
1569                                                 changes[i].comment);
1570                                 }
1571                                 if (delta_enum_array->num_deltas > 1) {
1572                                         torture_assert_int_equal(tctx,
1573                                                 delta_enum_array->delta_enum[1].delta_type,
1574                                                 changes[i].expected_delta_type_2,
1575                                                 changes[i].comment);
1576                                 }
1577                         }
1578
1579                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1580                                 torture_comment(tctx, "Credential chaining failed\n");
1581                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1582                                         return false;
1583                                 }
1584                         }
1585                 }
1586         }
1587         }
1588
1589         return true;
1590 }
1591
1592 /*
1593   try a netlogon AccountDeltas
1594 */
1595 static bool test_AccountDeltas(struct torture_context *tctx, 
1596                                struct dcerpc_pipe *p,
1597                                struct cli_credentials *machine_credentials)
1598 {
1599         struct netr_AccountDeltas r;
1600         struct netlogon_creds_CredentialState *creds;
1601
1602         struct netr_AccountBuffer buffer;
1603         uint32_t count_returned = 0;
1604         uint32_t total_entries = 0;
1605         struct netr_UAS_INFO_0 recordid;
1606         struct netr_Authenticator return_authenticator;
1607         struct dcerpc_binding_handle *b = p->binding_handle;
1608
1609         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1610                 return false;
1611         }
1612
1613         ZERO_STRUCT(return_authenticator);
1614
1615         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1616         r.in.computername = TEST_MACHINE_NAME;
1617         r.in.return_authenticator = &return_authenticator;
1618         netlogon_creds_client_authenticator(creds, &r.in.credential);
1619         ZERO_STRUCT(r.in.uas);
1620         r.in.count=10;
1621         r.in.level=0;
1622         r.in.buffersize=100;
1623         r.out.buffer = &buffer;
1624         r.out.count_returned = &count_returned;
1625         r.out.total_entries = &total_entries;
1626         r.out.recordid = &recordid;
1627         r.out.return_authenticator = &return_authenticator;
1628
1629         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1630         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1631                 "AccountDeltas failed");
1632         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1633
1634         return true;
1635 }
1636
1637 /*
1638   try a netlogon AccountSync
1639 */
1640 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
1641                              struct cli_credentials *machine_credentials)
1642 {
1643         struct netr_AccountSync r;
1644         struct netlogon_creds_CredentialState *creds;
1645
1646         struct netr_AccountBuffer buffer;
1647         uint32_t count_returned = 0;
1648         uint32_t total_entries = 0;
1649         uint32_t next_reference = 0;
1650         struct netr_UAS_INFO_0 recordid;
1651         struct netr_Authenticator return_authenticator;
1652         struct dcerpc_binding_handle *b = p->binding_handle;
1653
1654         ZERO_STRUCT(recordid);
1655         ZERO_STRUCT(return_authenticator);
1656
1657         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1658                 return false;
1659         }
1660
1661         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1662         r.in.computername = TEST_MACHINE_NAME;
1663         r.in.return_authenticator = &return_authenticator;
1664         netlogon_creds_client_authenticator(creds, &r.in.credential);
1665         r.in.recordid = &recordid;
1666         r.in.reference=0;
1667         r.in.level=0;
1668         r.in.buffersize=100;
1669         r.out.buffer = &buffer;
1670         r.out.count_returned = &count_returned;
1671         r.out.total_entries = &total_entries;
1672         r.out.next_reference = &next_reference;
1673         r.out.recordid = &recordid;
1674         r.out.return_authenticator = &return_authenticator;
1675
1676         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1677         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1678                 "AccountSync failed");
1679         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1680
1681         return true;
1682 }
1683
1684 /*
1685   try a netlogon GetDcName
1686 */
1687 static bool test_GetDcName(struct torture_context *tctx, 
1688                            struct dcerpc_pipe *p)
1689 {
1690         struct netr_GetDcName r;
1691         const char *dcname = NULL;
1692         struct dcerpc_binding_handle *b = p->binding_handle;
1693
1694         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1695         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1696         r.out.dcname = &dcname;
1697
1698         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1699                 "GetDcName failed");
1700         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1701
1702         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1703
1704         return true;
1705 }
1706
1707 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1708                                      enum netr_LogonControlCode function_code)
1709 {
1710         switch (function_code) {
1711         case NETLOGON_CONTROL_QUERY:
1712                 return "NETLOGON_CONTROL_QUERY";
1713         case NETLOGON_CONTROL_REPLICATE:
1714                 return "NETLOGON_CONTROL_REPLICATE";
1715         case NETLOGON_CONTROL_SYNCHRONIZE:
1716                 return "NETLOGON_CONTROL_SYNCHRONIZE";
1717         case NETLOGON_CONTROL_PDC_REPLICATE:
1718                 return "NETLOGON_CONTROL_PDC_REPLICATE";
1719         case NETLOGON_CONTROL_REDISCOVER:
1720                 return "NETLOGON_CONTROL_REDISCOVER";
1721         case NETLOGON_CONTROL_TC_QUERY:
1722                 return "NETLOGON_CONTROL_TC_QUERY";
1723         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1724                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1725         case NETLOGON_CONTROL_FIND_USER:
1726                 return "NETLOGON_CONTROL_FIND_USER";
1727         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1728                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1729         case NETLOGON_CONTROL_TC_VERIFY:
1730                 return "NETLOGON_CONTROL_TC_VERIFY";
1731         case NETLOGON_CONTROL_FORCE_DNS_REG:
1732                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1733         case NETLOGON_CONTROL_QUERY_DNS_REG:
1734                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1735         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1736                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1737         case NETLOGON_CONTROL_TRUNCATE_LOG:
1738                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1739         case NETLOGON_CONTROL_SET_DBFLAG:
1740                 return "NETLOGON_CONTROL_SET_DBFLAG";
1741         case NETLOGON_CONTROL_BREAKPOINT:
1742                 return "NETLOGON_CONTROL_BREAKPOINT";
1743         default:
1744                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1745                                        function_code);
1746         }
1747 }
1748
1749
1750 /*
1751   try a netlogon LogonControl 
1752 */
1753 static bool test_LogonControl(struct torture_context *tctx, 
1754                               struct dcerpc_pipe *p,
1755                               struct cli_credentials *machine_credentials)
1756
1757 {
1758         NTSTATUS status;
1759         struct netr_LogonControl r;
1760         union netr_CONTROL_QUERY_INFORMATION query;
1761         int i,f;
1762         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1763         struct dcerpc_binding_handle *b = p->binding_handle;
1764
1765         uint32_t function_codes[] = {
1766                 NETLOGON_CONTROL_QUERY,
1767                 NETLOGON_CONTROL_REPLICATE,
1768                 NETLOGON_CONTROL_SYNCHRONIZE,
1769                 NETLOGON_CONTROL_PDC_REPLICATE,
1770                 NETLOGON_CONTROL_REDISCOVER,
1771                 NETLOGON_CONTROL_TC_QUERY,
1772                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1773                 NETLOGON_CONTROL_FIND_USER,
1774                 NETLOGON_CONTROL_CHANGE_PASSWORD,
1775                 NETLOGON_CONTROL_TC_VERIFY,
1776                 NETLOGON_CONTROL_FORCE_DNS_REG,
1777                 NETLOGON_CONTROL_QUERY_DNS_REG,
1778                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1779                 NETLOGON_CONTROL_TRUNCATE_LOG,
1780                 NETLOGON_CONTROL_SET_DBFLAG,
1781                 NETLOGON_CONTROL_BREAKPOINT
1782         };
1783
1784         if (machine_credentials) {
1785                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1786         }
1787
1788         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1789                 secure_channel_type);
1790
1791         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1792         r.in.function_code = 1;
1793         r.out.query = &query;
1794
1795         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1796         for (i=1;i<5;i++) {
1797
1798                 r.in.function_code = function_codes[f];
1799                 r.in.level = i;
1800
1801                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1802                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1803
1804                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1805                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1806
1807                 switch (r.in.level) {
1808                 case 1:
1809                         switch (r.in.function_code) {
1810                         case NETLOGON_CONTROL_REPLICATE:
1811                         case NETLOGON_CONTROL_SYNCHRONIZE:
1812                         case NETLOGON_CONTROL_PDC_REPLICATE:
1813                         case NETLOGON_CONTROL_BREAKPOINT:
1814                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1815                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1816                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1817                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1818                                                 "LogonControl returned unexpected error code");
1819                                 } else {
1820                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1821                                                 "LogonControl returned unexpected error code");
1822                                 }
1823                                 break;
1824
1825                         case NETLOGON_CONTROL_REDISCOVER:
1826                         case NETLOGON_CONTROL_TC_QUERY:
1827                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1828                         case NETLOGON_CONTROL_FIND_USER:
1829                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1830                         case NETLOGON_CONTROL_TC_VERIFY:
1831                         case NETLOGON_CONTROL_FORCE_DNS_REG:
1832                         case NETLOGON_CONTROL_QUERY_DNS_REG:
1833                         case NETLOGON_CONTROL_SET_DBFLAG:
1834                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1835                                         "LogonControl returned unexpected error code");
1836                                 break;
1837                         case NETLOGON_CONTROL_TRUNCATE_LOG:
1838                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1839                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1840                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1841                                                 "LogonControl returned unexpected error code");
1842                                 } else {
1843                                         torture_assert_werr_ok(tctx, r.out.result,
1844                                                 "LogonControl returned unexpected result");
1845                                 }
1846                                 break;
1847                         default:
1848                                 torture_assert_werr_ok(tctx, r.out.result,
1849                                         "LogonControl returned unexpected result");
1850                                 break;
1851                         }
1852                         break;
1853                 case 2:
1854                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1855                                 "LogonControl returned unexpected error code");
1856                         break;
1857                 default:
1858                         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1859                                 "LogonControl returned unexpected error code");
1860                         break;
1861                 }
1862         }
1863         }
1864
1865         r.in.level = 52;
1866         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1867                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1868         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1869         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1870         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1871
1872         return true;
1873 }
1874
1875
1876 /*
1877   try a netlogon GetAnyDCName
1878 */
1879 static bool test_GetAnyDCName(struct torture_context *tctx, 
1880                               struct dcerpc_pipe *p)
1881 {
1882         NTSTATUS status;
1883         struct netr_GetAnyDCName r;
1884         const char *dcname = NULL;
1885         struct dcerpc_binding_handle *b = p->binding_handle;
1886
1887         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1888         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1889         r.out.dcname = &dcname;
1890
1891         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1892         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1893         if ((!W_ERROR_IS_OK(r.out.result)) &&
1894             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1895                 return false;
1896         }
1897
1898         if (dcname) {
1899             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1900         }
1901
1902         r.in.domainname = NULL;
1903
1904         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1905         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1906         if ((!W_ERROR_IS_OK(r.out.result)) &&
1907             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1908                 return false;
1909         }
1910
1911         r.in.domainname = "";
1912
1913         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1914         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1915         if ((!W_ERROR_IS_OK(r.out.result)) &&
1916             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1917                 return false;
1918         }
1919
1920         return true;
1921 }
1922
1923
1924 /*
1925   try a netlogon LogonControl2
1926 */
1927 static bool test_LogonControl2(struct torture_context *tctx, 
1928                                struct dcerpc_pipe *p,
1929                                struct cli_credentials *machine_credentials)
1930
1931 {
1932         NTSTATUS status;
1933         struct netr_LogonControl2 r;
1934         union netr_CONTROL_DATA_INFORMATION data;
1935         union netr_CONTROL_QUERY_INFORMATION query;
1936         int i;
1937         struct dcerpc_binding_handle *b = p->binding_handle;
1938
1939         data.domain = lpcfg_workgroup(tctx->lp_ctx);
1940
1941         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1942
1943         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1944         r.in.data = &data;
1945         r.out.query = &query;
1946
1947         for (i=1;i<4;i++) {
1948                 r.in.level = i;
1949
1950                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1951                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1952
1953                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1954                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1955         }
1956
1957         data.domain = lpcfg_workgroup(tctx->lp_ctx);
1958
1959         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
1960         r.in.data = &data;
1961
1962         for (i=1;i<4;i++) {
1963                 r.in.level = i;
1964
1965                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1966                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1967
1968                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1969                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1970         }
1971
1972         data.domain = lpcfg_workgroup(tctx->lp_ctx);
1973
1974         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
1975         r.in.data = &data;
1976
1977         for (i=1;i<4;i++) {
1978                 r.in.level = i;
1979
1980                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1981                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1982
1983                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1984                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
1985         }
1986
1987         data.debug_level = ~0;
1988
1989         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
1990         r.in.data = &data;
1991
1992         for (i=1;i<4;i++) {
1993                 r.in.level = i;
1994
1995                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
1996                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1997
1998                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
1999                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2000         }
2001
2002         ZERO_STRUCT(data);
2003         r.in.function_code = 52;
2004         r.in.data = &data;
2005
2006         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2007                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2008
2009         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2010         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2011         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2012
2013         data.debug_level = ~0;
2014
2015         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2016         r.in.data = &data;
2017
2018         r.in.level = 52;
2019         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2020                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2021
2022         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2023         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2024         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2025
2026         return true;
2027 }
2028
2029 /*
2030   try a netlogon DatabaseSync2
2031 */
2032 static bool test_DatabaseSync2(struct torture_context *tctx, 
2033                                struct dcerpc_pipe *p,
2034                                struct cli_credentials *machine_credentials)
2035 {
2036         struct netr_DatabaseSync2 r;
2037         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2038         struct netr_Authenticator return_authenticator, credential;
2039
2040         struct netlogon_creds_CredentialState *creds;
2041         const uint32_t database_ids[] = {0, 1, 2}; 
2042         int i;
2043         struct dcerpc_binding_handle *b = p->binding_handle;
2044
2045         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
2046                                     machine_credentials,
2047                                     cli_credentials_get_secure_channel_type(machine_credentials),
2048                                     &creds)) {
2049                 return false;
2050         }
2051
2052         ZERO_STRUCT(return_authenticator);
2053
2054         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2055         r.in.computername = TEST_MACHINE_NAME;
2056         r.in.preferredmaximumlength = (uint32_t)-1;
2057         r.in.return_authenticator = &return_authenticator;
2058         r.out.return_authenticator = &return_authenticator;
2059         r.out.delta_enum_array = &delta_enum_array;
2060
2061         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2062
2063                 uint32_t sync_context = 0;
2064
2065                 r.in.database_id = database_ids[i];
2066                 r.in.sync_context = &sync_context;
2067                 r.out.sync_context = &sync_context;
2068                 r.in.restart_state = 0;
2069
2070                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2071
2072                 do {
2073                         netlogon_creds_client_authenticator(creds, &credential);
2074
2075                         r.in.credential = &credential;
2076
2077                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2078                                 "DatabaseSync2 failed");
2079                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2080                             break;
2081
2082                         /* Native mode servers don't do this */
2083                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2084                                 return true;
2085                         }
2086
2087                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2088
2089                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2090                                 torture_comment(tctx, "Credential chaining failed\n");
2091                         }
2092
2093                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2094         }
2095
2096         return true;
2097 }
2098
2099
2100 /*
2101   try a netlogon LogonControl2Ex
2102 */
2103 static bool test_LogonControl2Ex(struct torture_context *tctx, 
2104                                  struct dcerpc_pipe *p,
2105                                  struct cli_credentials *machine_credentials)
2106
2107 {
2108         NTSTATUS status;
2109         struct netr_LogonControl2Ex r;
2110         union netr_CONTROL_DATA_INFORMATION data;
2111         union netr_CONTROL_QUERY_INFORMATION query;
2112         int i;
2113         struct dcerpc_binding_handle *b = p->binding_handle;
2114
2115         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2116
2117         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2118
2119         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2120         r.in.data = &data;
2121         r.out.query = &query;
2122
2123         for (i=1;i<4;i++) {
2124                 r.in.level = i;
2125
2126                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2127                        i, r.in.function_code);
2128
2129                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2130                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2131         }
2132
2133         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2134
2135         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2136         r.in.data = &data;
2137
2138         for (i=1;i<4;i++) {
2139                 r.in.level = i;
2140
2141                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2142                        i, r.in.function_code);
2143
2144                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2145                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2146         }
2147
2148         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2149
2150         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2151         r.in.data = &data;
2152
2153         for (i=1;i<4;i++) {
2154                 r.in.level = i;
2155
2156                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2157                        i, r.in.function_code);
2158
2159                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2160                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2161         }
2162
2163         data.debug_level = ~0;
2164
2165         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2166         r.in.data = &data;
2167
2168         for (i=1;i<4;i++) {
2169                 r.in.level = i;
2170
2171                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2172                        i, r.in.function_code);
2173
2174                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2175                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2176         }
2177
2178         return true;
2179 }
2180
2181 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2182                                                 struct dcerpc_pipe *p,
2183                                                 struct cli_credentials *machine_credentials)
2184 {
2185         struct netr_GetForestTrustInformation r;
2186         struct netlogon_creds_CredentialState *creds;
2187         struct netr_Authenticator a;
2188         struct netr_Authenticator return_authenticator;
2189         struct lsa_ForestTrustInformation *forest_trust_info;
2190         struct dcerpc_binding_handle *b = p->binding_handle;
2191
2192         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2193                                     machine_credentials, &creds)) {
2194                 return false;
2195         }
2196
2197         netlogon_creds_client_authenticator(creds, &a);
2198
2199         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2200         r.in.computer_name = TEST_MACHINE_NAME;
2201         r.in.credential = &a;
2202         r.in.flags = 0;
2203         r.out.return_authenticator = &return_authenticator;
2204         r.out.forest_trust_info = &forest_trust_info;
2205
2206         torture_assert_ntstatus_ok(tctx,
2207                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2208                 "netr_GetForestTrustInformation failed");
2209         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2210                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2211         } else {
2212                 torture_assert_ntstatus_ok(tctx, r.out.result,
2213                         "netr_GetForestTrustInformation failed");
2214         }
2215
2216         torture_assert(tctx,
2217                 netlogon_creds_client_check(creds, &return_authenticator.cred),
2218                 "Credential chaining failed");
2219
2220         return true;
2221 }
2222
2223 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
2224                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
2225 {
2226         NTSTATUS status;
2227         struct netr_DsRGetForestTrustInformation r;
2228         struct lsa_ForestTrustInformation info, *info_ptr;
2229         struct dcerpc_binding_handle *b = p->binding_handle;
2230
2231         info_ptr = &info;
2232
2233         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2234         r.in.trusted_domain_name = trusted_domain_name;
2235         r.in.flags = 0;
2236         r.out.forest_trust_info = &info_ptr;
2237
2238         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2239
2240         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2241         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2242         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2243
2244         return true;
2245 }
2246
2247 /*
2248   try a netlogon netr_DsrEnumerateDomainTrusts
2249 */
2250 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
2251                                           struct dcerpc_pipe *p)
2252 {
2253         NTSTATUS status;
2254         struct netr_DsrEnumerateDomainTrusts r;
2255         struct netr_DomainTrustList trusts;
2256         int i;
2257         struct dcerpc_binding_handle *b = p->binding_handle;
2258
2259         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2260         r.in.trust_flags = 0x3f;
2261         r.out.trusts = &trusts;
2262
2263         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2264         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2265         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2266
2267         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2268          * will show non-forest trusts and all UPN suffixes of the own forest
2269          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2270
2271         if (r.out.trusts->count) {
2272                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2273                         return false;
2274                 }
2275         }
2276
2277         for (i=0; i<r.out.trusts->count; i++) {
2278
2279                 /* get info for transitive forest trusts */
2280
2281                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2282                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
2283                                                                     r.out.trusts->array[i].dns_name)) {
2284                                 return false;
2285                         }
2286                 }
2287         }
2288
2289         return true;
2290 }
2291
2292 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2293                                                   struct dcerpc_pipe *p)
2294 {
2295         NTSTATUS status;
2296         struct netr_NetrEnumerateTrustedDomains r;
2297         struct netr_Blob trusted_domains_blob;
2298         struct dcerpc_binding_handle *b = p->binding_handle;
2299
2300         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2301         r.out.trusted_domains_blob = &trusted_domains_blob;
2302
2303         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2304         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2305         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2306
2307         return true;
2308 }
2309
2310 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2311                                                     struct dcerpc_pipe *p)
2312 {
2313         NTSTATUS status;
2314         struct netr_NetrEnumerateTrustedDomainsEx r;
2315         struct netr_DomainTrustList dom_trust_list;
2316         struct dcerpc_binding_handle *b = p->binding_handle;
2317
2318         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2319         r.out.dom_trust_list = &dom_trust_list;
2320
2321         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2322         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2323         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2324
2325         return true;
2326 }
2327
2328
2329 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2330                                      const char *computer_name, 
2331                                      const char *expected_site) 
2332 {
2333         NTSTATUS status;
2334         struct netr_DsRGetSiteName r;
2335         const char *site = NULL;
2336         struct dcerpc_binding_handle *b = p->binding_handle;
2337
2338         r.in.computer_name              = computer_name;
2339         r.out.site                      = &site;
2340         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2341
2342         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2343         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2344         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2345         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2346
2347         if (torture_setting_bool(tctx, "samba4", false))
2348                 torture_skip(tctx, "skipping computer name check against Samba4");
2349
2350         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
2351         torture_comment(tctx, 
2352                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2353
2354         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2355         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2356         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2357
2358         return true;
2359 }
2360
2361 /*
2362   try a netlogon netr_DsRGetDCName
2363 */
2364 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
2365                                    struct dcerpc_pipe *p)
2366 {
2367         NTSTATUS status;
2368         struct netr_DsRGetDCName r;
2369         struct netr_DsRGetDCNameInfo *info = NULL;
2370         struct dcerpc_binding_handle *b = p->binding_handle;
2371
2372         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2374         r.in.domain_guid        = NULL;
2375         r.in.site_guid          = NULL;
2376         r.in.flags              = DS_RETURN_DNS_NAME;
2377         r.out.info              = &info;
2378
2379         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2380         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2381         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2382
2383         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2384
2385         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2386         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2387         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2388
2389         return test_netr_DsRGetSiteName(p, tctx, 
2390                                        info->dc_unc,
2391                                        info->dc_site_name);
2392 }
2393
2394 /*
2395   try a netlogon netr_DsRGetDCNameEx
2396 */
2397 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
2398                                      struct dcerpc_pipe *p)
2399 {
2400         NTSTATUS status;
2401         struct netr_DsRGetDCNameEx r;
2402         struct netr_DsRGetDCNameInfo *info = NULL;
2403         struct dcerpc_binding_handle *b = p->binding_handle;
2404
2405         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2406         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2407         r.in.domain_guid        = NULL;
2408         r.in.site_name          = NULL;
2409         r.in.flags              = DS_RETURN_DNS_NAME;
2410         r.out.info              = &info;
2411
2412         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2413         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2414         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2415
2416         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2417
2418         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2419         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2420         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2421
2422         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2423                                         info->dc_site_name);
2424 }
2425
2426 /*
2427   try a netlogon netr_DsRGetDCNameEx2
2428 */
2429 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
2430                                       struct dcerpc_pipe *p)
2431 {
2432         NTSTATUS status;
2433         struct netr_DsRGetDCNameEx2 r;
2434         struct netr_DsRGetDCNameInfo *info = NULL;
2435         struct dcerpc_binding_handle *b = p->binding_handle;
2436
2437         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2438         ZERO_STRUCT(r.in);
2439         r.in.flags              = DS_RETURN_DNS_NAME;
2440         r.out.info              = &info;
2441
2442         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2443         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2444         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2445
2446         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2447         r.in.client_account     = NULL;
2448         r.in.mask               = 0x00000000;
2449         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2450         r.in.domain_guid        = NULL;
2451         r.in.site_name          = NULL;
2452         r.in.flags              = DS_RETURN_DNS_NAME;
2453         r.out.info              = &info;
2454
2455         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2456
2457         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2458         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2459         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2460
2461         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2462
2463         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2464         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2465         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2466
2467         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2468         r.in.client_account     = TEST_MACHINE_NAME"$";
2469         r.in.mask               = ACB_SVRTRUST;
2470         r.in.flags              = DS_RETURN_FLAT_NAME;
2471         r.out.info              = &info;
2472
2473         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2474         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2475         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2476
2477         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2478                                         info->dc_site_name);
2479 }
2480
2481 /* This is a substitution for "samdb_server_site_name" which relies on the
2482  * correct "lp_ctx" and therefore can't be used here. */
2483 static const char *server_site_name(struct torture_context *tctx,
2484                                     struct ldb_context *ldb)
2485 {
2486         TALLOC_CTX *tmp_ctx;
2487         struct ldb_dn *dn, *server_dn;
2488         const struct ldb_val *site_name_val;
2489         const char *server_dn_str, *site_name;
2490
2491         tmp_ctx = talloc_new(ldb);
2492         if (tmp_ctx == NULL) {
2493                 goto failed;
2494         }
2495
2496         dn = ldb_dn_new(tmp_ctx, ldb, "");
2497         if (dn == NULL) {
2498                 goto failed;
2499         }
2500
2501         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2502                                             NULL);
2503         if (server_dn_str == NULL) {
2504                 goto failed;
2505         }
2506
2507         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2508         if (server_dn == NULL) {
2509                 goto failed;
2510         }
2511
2512         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2513         site_name_val = ldb_dn_get_component_val(server_dn, 2);
2514         if (site_name_val == NULL) {
2515                 goto failed;
2516         }
2517
2518         site_name = (const char *) site_name_val->data;
2519
2520         talloc_steal(tctx, site_name);
2521         talloc_free(tmp_ctx);
2522
2523         return site_name;
2524
2525 failed:
2526         talloc_free(tmp_ctx);
2527         return NULL;
2528 }
2529
2530 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
2531                                             struct dcerpc_pipe *p)
2532 {
2533         char *url;
2534         struct ldb_context *sam_ctx = NULL;
2535         NTSTATUS status;
2536         struct netr_DsrGetDcSiteCoverageW r;
2537         struct DcSitesCtr *ctr = NULL;
2538         struct dcerpc_binding_handle *b = p->binding_handle;
2539
2540         torture_comment(tctx, "This does only pass with the default site\n");
2541
2542         /* We won't double-check this when we are over 'local' transports */
2543         if (dcerpc_server_name(p)) {
2544                 /* Set up connection to SAMDB on DC */
2545                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2546                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2547                                            NULL,
2548                                            cmdline_credentials,
2549                                            0);
2550
2551                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2552         }
2553
2554         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2555         r.out.ctr = &ctr;
2556
2557         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2558         torture_assert_ntstatus_ok(tctx, status, "failed");
2559         torture_assert_werr_ok(tctx, r.out.result, "failed");
2560
2561         torture_assert(tctx, ctr->num_sites == 1,
2562                        "we should per default only get the default site");
2563         if (sam_ctx != NULL) {
2564                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2565                                              server_site_name(tctx, sam_ctx),
2566                                              "didn't return default site");
2567         }
2568
2569         return true;
2570 }
2571
2572 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2573                                              struct dcerpc_pipe *p)
2574 {
2575         char *url;
2576         struct ldb_context *sam_ctx = NULL;
2577         NTSTATUS status;
2578         struct netr_DsRAddressToSitenamesW r;
2579         struct netr_DsRAddress addrs[6];
2580         struct sockaddr_in *addr;
2581 #ifdef HAVE_IPV6
2582         struct sockaddr_in6 *addr6;
2583 #endif
2584         struct netr_DsRAddressToSitenamesWCtr *ctr;
2585         struct dcerpc_binding_handle *b = p->binding_handle;
2586         uint32_t i;
2587         int ret;
2588
2589         torture_comment(tctx, "This does only pass with the default site\n");
2590
2591         /* We won't double-check this when we are over 'local' transports */
2592         if (dcerpc_server_name(p)) {
2593                 /* Set up connection to SAMDB on DC */
2594                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2595                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2596                                            NULL,
2597                                            cmdline_credentials,
2598                                            0);
2599
2600                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2601         }
2602
2603         /* First try valid IP addresses */
2604
2605         addrs[0].size = sizeof(struct sockaddr_in);
2606         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2607         addr = (struct sockaddr_in *) addrs[0].buffer;
2608         addrs[0].buffer[0] = AF_INET;
2609         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2610         torture_assert(tctx, ret > 0, "inet_pton failed");
2611
2612         addrs[1].size = sizeof(struct sockaddr_in);
2613         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2614         addr = (struct sockaddr_in *) addrs[1].buffer;
2615         addrs[1].buffer[0] = AF_INET;
2616         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2617         torture_assert(tctx, ret > 0, "inet_pton failed");
2618
2619         addrs[2].size = sizeof(struct sockaddr_in);
2620         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2621         addr = (struct sockaddr_in *) addrs[2].buffer;
2622         addrs[2].buffer[0] = AF_INET;
2623         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2624         torture_assert(tctx, ret > 0, "inet_pton failed");
2625
2626 #ifdef HAVE_IPV6
2627         addrs[3].size = sizeof(struct sockaddr_in6);
2628         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2629         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2630         addrs[3].buffer[0] = AF_INET6;
2631         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2632         torture_assert(tctx, ret > 0, "inet_pton failed");
2633
2634         addrs[4].size = sizeof(struct sockaddr_in6);
2635         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2636         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2637         addrs[4].buffer[0] = AF_INET6;
2638         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2639         torture_assert(tctx, ret > 0, "inet_pton failed");
2640
2641         addrs[5].size = sizeof(struct sockaddr_in6);
2642         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2643         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2644         addrs[5].buffer[0] = AF_INET6;
2645         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2646         torture_assert(tctx, ret > 0, "inet_pton failed");
2647 #else
2648         /* the test cases are repeated to have exactly 6. This is for
2649          * compatibility with IPv4-only machines */
2650         addrs[3].size = sizeof(struct sockaddr_in);
2651         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2652         addr = (struct sockaddr_in *) addrs[3].buffer;
2653         addrs[3].buffer[0] = AF_INET;
2654         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2655         torture_assert(tctx, ret > 0, "inet_pton failed");
2656
2657         addrs[4].size = sizeof(struct sockaddr_in);
2658         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2659         addr = (struct sockaddr_in *) addrs[4].buffer;
2660         addrs[4].buffer[0] = AF_INET;
2661         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2662         torture_assert(tctx, ret > 0, "inet_pton failed");
2663
2664         addrs[5].size = sizeof(struct sockaddr_in);
2665         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2666         addr = (struct sockaddr_in *) addrs[5].buffer;
2667         addrs[5].buffer[0] = AF_INET;
2668         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2669         torture_assert(tctx, ret > 0, "inet_pton failed");
2670 #endif
2671
2672         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2673
2674         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2675         r.in.count = 6;
2676         r.in.addresses = addrs;
2677         r.out.ctr = &ctr;
2678
2679         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2680         torture_assert_ntstatus_ok(tctx, status, "failed");
2681         torture_assert_werr_ok(tctx, r.out.result, "failed");
2682
2683         if (sam_ctx != NULL) {
2684                 for (i = 0; i < 3; i++) {
2685                         torture_assert_casestr_equal(tctx,
2686                                                      ctr->sitename[i].string,
2687                                                      server_site_name(tctx, sam_ctx),
2688                                                      "didn't return default site");
2689                 }
2690                 for (i = 3; i < 6; i++) {
2691                         /* Windows returns "NULL" for the sitename if it isn't
2692                          * IPv6 configured */
2693                         if (torture_setting_bool(tctx, "samba4", false)) {
2694                                 torture_assert_casestr_equal(tctx,
2695                                                              ctr->sitename[i].string,
2696                                                              server_site_name(tctx, sam_ctx),
2697                                                              "didn't return default site");
2698                         }
2699                 }
2700         }
2701
2702         /* Now try invalid ones (too short buffers) */
2703
2704         addrs[0].size = 0;
2705         addrs[1].size = 1;
2706         addrs[2].size = 4;
2707
2708         addrs[3].size = 0;
2709         addrs[4].size = 1;
2710         addrs[5].size = 4;
2711
2712         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2713         torture_assert_ntstatus_ok(tctx, status, "failed");
2714         torture_assert_werr_ok(tctx, r.out.result, "failed");
2715
2716         for (i = 0; i < 6; i++) {
2717                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2718                                "sitename should be null");
2719         }
2720
2721         /* Now try invalid ones (wrong address types) */
2722
2723         addrs[0].size = 10;
2724         addrs[0].buffer[0] = AF_UNSPEC;
2725         addrs[1].size = 10;
2726         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2727         addrs[2].size = 10;
2728         addrs[2].buffer[0] = AF_UNIX;
2729
2730         addrs[3].size = 10;
2731         addrs[3].buffer[0] = 250;
2732         addrs[4].size = 10;
2733         addrs[4].buffer[0] = 251;
2734         addrs[5].size = 10;
2735         addrs[5].buffer[0] = 252;
2736
2737         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2738         torture_assert_ntstatus_ok(tctx, status, "failed");
2739         torture_assert_werr_ok(tctx, r.out.result, "failed");
2740
2741         for (i = 0; i < 6; i++) {
2742                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2743                                "sitename should be null");
2744         }
2745
2746         return true;
2747 }
2748
2749 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2750                                                struct dcerpc_pipe *p)
2751 {
2752         char *url;
2753         struct ldb_context *sam_ctx = NULL;
2754         NTSTATUS status;
2755         struct netr_DsRAddressToSitenamesExW r;
2756         struct netr_DsRAddress addrs[6];
2757         struct sockaddr_in *addr;
2758 #ifdef HAVE_IPV6
2759         struct sockaddr_in6 *addr6;
2760 #endif
2761         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2762         struct dcerpc_binding_handle *b = p->binding_handle;
2763         uint32_t i;
2764         int ret;
2765
2766         torture_comment(tctx, "This does pass with the default site\n");
2767
2768         /* We won't double-check this when we are over 'local' transports */
2769         if (dcerpc_server_name(p)) {
2770                 /* Set up connection to SAMDB on DC */
2771                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2772                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2773                                            NULL,
2774                                            cmdline_credentials,
2775                                            0);
2776
2777                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2778         }
2779
2780         /* First try valid IP addresses */
2781
2782         addrs[0].size = sizeof(struct sockaddr_in);
2783         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2784         addr = (struct sockaddr_in *) addrs[0].buffer;
2785         addrs[0].buffer[0] = AF_INET;
2786         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2787         torture_assert(tctx, ret > 0, "inet_pton failed");
2788
2789         addrs[1].size = sizeof(struct sockaddr_in);
2790         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2791         addr = (struct sockaddr_in *) addrs[1].buffer;
2792         addrs[1].buffer[0] = AF_INET;
2793         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2794         torture_assert(tctx, ret > 0, "inet_pton failed");
2795
2796         addrs[2].size = sizeof(struct sockaddr_in);
2797         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2798         addr = (struct sockaddr_in *) addrs[2].buffer;
2799         addrs[2].buffer[0] = AF_INET;
2800         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2801         torture_assert(tctx, ret > 0, "inet_pton failed");
2802
2803 #ifdef HAVE_IPV6
2804         addrs[3].size = sizeof(struct sockaddr_in6);
2805         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2806         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2807         addrs[3].buffer[0] = AF_INET6;
2808         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2809         torture_assert(tctx, ret > 0, "inet_pton failed");
2810
2811         addrs[4].size = sizeof(struct sockaddr_in6);
2812         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2813         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2814         addrs[4].buffer[0] = AF_INET6;
2815         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2816         torture_assert(tctx, ret > 0, "inet_pton failed");
2817
2818         addrs[5].size = sizeof(struct sockaddr_in6);
2819         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2820         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2821         addrs[5].buffer[0] = AF_INET6;
2822         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2823         torture_assert(tctx, ret > 0, "inet_pton failed");
2824 #else
2825         /* the test cases are repeated to have exactly 6. This is for
2826          * compatibility with IPv4-only machines */
2827         addrs[3].size = sizeof(struct sockaddr_in);
2828         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2829         addr = (struct sockaddr_in *) addrs[3].buffer;
2830         addrs[3].buffer[0] = AF_INET;
2831         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2832         torture_assert(tctx, ret > 0, "inet_pton failed");
2833
2834         addrs[4].size = sizeof(struct sockaddr_in);
2835         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2836         addr = (struct sockaddr_in *) addrs[4].buffer;
2837         addrs[4].buffer[0] = AF_INET;
2838         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2839         torture_assert(tctx, ret > 0, "inet_pton failed");
2840
2841         addrs[5].size = sizeof(struct sockaddr_in);
2842         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2843         addr = (struct sockaddr_in *) addrs[5].buffer;
2844         addrs[5].buffer[0] = AF_INET;
2845         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2846         torture_assert(tctx, ret > 0, "inet_pton failed");
2847 #endif
2848
2849         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2850
2851         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2852         r.in.count = 6;
2853         r.in.addresses = addrs;
2854         r.out.ctr = &ctr;
2855
2856         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2857         torture_assert_ntstatus_ok(tctx, status, "failed");
2858         torture_assert_werr_ok(tctx, r.out.result, "failed");
2859
2860         if (sam_ctx != NULL) {
2861                 for (i = 0; i < 3; i++) {
2862                         torture_assert_casestr_equal(tctx,
2863                                                      ctr->sitename[i].string,
2864                                                      server_site_name(tctx, sam_ctx),
2865                                                      "didn't return default site");
2866                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2867                                        "subnet should be null");
2868                 }
2869                 for (i = 3; i < 6; i++) {
2870                         /* Windows returns "NULL" for the sitename if it isn't
2871                          * IPv6 configured */
2872                         if (torture_setting_bool(tctx, "samba4", false)) {
2873                                 torture_assert_casestr_equal(tctx,
2874                                                              ctr->sitename[i].string,
2875                                                              server_site_name(tctx, sam_ctx),
2876                                                              "didn't return default site");
2877                         }
2878                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2879                                        "subnet should be null");
2880                 }
2881         }
2882
2883         /* Now try invalid ones (too short buffers) */
2884
2885         addrs[0].size = 0;
2886         addrs[1].size = 1;
2887         addrs[2].size = 4;
2888
2889         addrs[3].size = 0;
2890         addrs[4].size = 1;
2891         addrs[5].size = 4;
2892
2893         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2894         torture_assert_ntstatus_ok(tctx, status, "failed");
2895         torture_assert_werr_ok(tctx, r.out.result, "failed");
2896
2897         for (i = 0; i < 6; i++) {
2898                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2899                                "sitename should be null");
2900                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2901                                "subnet should be null");
2902         }
2903
2904         addrs[0].size = 10;
2905         addrs[0].buffer[0] = AF_UNSPEC;
2906         addrs[1].size = 10;
2907         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2908         addrs[2].size = 10;
2909         addrs[2].buffer[0] = AF_UNIX;
2910
2911         addrs[3].size = 10;
2912         addrs[3].buffer[0] = 250;
2913         addrs[4].size = 10;
2914         addrs[4].buffer[0] = 251;
2915         addrs[5].size = 10;
2916         addrs[5].buffer[0] = 252;
2917
2918         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2919         torture_assert_ntstatus_ok(tctx, status, "failed");
2920         torture_assert_werr_ok(tctx, r.out.result, "failed");
2921
2922         for (i = 0; i < 6; i++) {
2923                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2924                                "sitename should be null");
2925                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2926                                "subnet should be null");
2927         }
2928
2929         return true;
2930 }
2931
2932 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2933                                          struct dcerpc_pipe *p,
2934                                          struct cli_credentials *machine_credentials)
2935 {
2936         struct netr_ServerGetTrustInfo r;
2937
2938         struct netr_Authenticator a;
2939         struct netr_Authenticator return_authenticator;
2940         struct samr_Password new_owf_password;
2941         struct samr_Password old_owf_password;
2942         struct netr_TrustInfo *trust_info;
2943
2944         struct netlogon_creds_CredentialState *creds;
2945         struct dcerpc_binding_handle *b = p->binding_handle;
2946
2947         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2948                                     machine_credentials, &creds)) {
2949                 return false;
2950         }
2951
2952         netlogon_creds_client_authenticator(creds, &a);
2953
2954         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2955         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
2956         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
2957         r.in.computer_name              = TEST_MACHINE_NAME;
2958         r.in.credential                 = &a;
2959
2960         r.out.return_authenticator      = &return_authenticator;
2961         r.out.new_owf_password          = &new_owf_password;
2962         r.out.old_owf_password          = &old_owf_password;
2963         r.out.trust_info                = &trust_info;
2964
2965         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
2966                 "ServerGetTrustInfo failed");
2967         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
2968         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
2969
2970         return true;
2971 }
2972
2973
2974 static bool test_GetDomainInfo(struct torture_context *tctx, 
2975                                struct dcerpc_pipe *p,
2976                                struct cli_credentials *machine_credentials)
2977 {
2978         struct netr_LogonGetDomainInfo r;
2979         struct netr_WorkstationInformation q1;
2980         struct netr_Authenticator a;
2981         struct netlogon_creds_CredentialState *creds;
2982         struct netr_OsVersion os;
2983         union netr_WorkstationInfo query;
2984         union netr_DomainInfo info;
2985         const char* const attrs[] = { "dNSHostName", "operatingSystem",
2986                 "operatingSystemServicePack", "operatingSystemVersion",
2987                 "servicePrincipalName", NULL };
2988         char *url;
2989         struct ldb_context *sam_ctx = NULL;
2990         struct ldb_message **res;
2991         struct ldb_message_element *spn_el;
2992         int ret, i;
2993         char *version_str;
2994         const char *old_dnsname = NULL;
2995         char **spns = NULL;
2996         int num_spns = 0;
2997         char *temp_str;
2998         struct dcerpc_binding_handle *b = p->binding_handle;
2999
3000         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3001
3002         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3003                                     machine_credentials, &creds)) {
3004                 return false;
3005         }
3006
3007         /* We won't double-check this when we are over 'local' transports */
3008         if (dcerpc_server_name(p)) {
3009                 /* Set up connection to SAMDB on DC */
3010                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3011                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3012                                            NULL,
3013                                            cmdline_credentials,
3014                                            0);
3015                 
3016                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3017         }
3018
3019         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3020         netlogon_creds_client_authenticator(creds, &a);
3021
3022         ZERO_STRUCT(r);
3023         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3024         r.in.computer_name = TEST_MACHINE_NAME;
3025         r.in.credential = &a;
3026         r.in.level = 1;
3027         r.in.return_authenticator = &a;
3028         r.in.query = &query;
3029         r.out.return_authenticator = &a;
3030         r.out.info = &info;
3031
3032         ZERO_STRUCT(os);
3033         os.os.MajorVersion = 123;
3034         os.os.MinorVersion = 456;
3035         os.os.BuildNumber = 789;
3036         os.os.CSDVersion = "Service Pack 10";
3037         os.os.ServicePackMajor = 10;
3038         os.os.ServicePackMinor = 1;
3039         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3040         os.os.ProductType = NETR_VER_NT_SERVER;
3041         os.os.Reserved = 0;
3042
3043         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3044                 os.os.MinorVersion, os.os.BuildNumber);
3045
3046         ZERO_STRUCT(q1);
3047         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3048                 lpcfg_dnsdomain(tctx->lp_ctx));
3049         q1.sitename = "Default-First-Site-Name";
3050         q1.os_version.os = &os;
3051         q1.os_name.string = talloc_asprintf(tctx,
3052                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3053                                             timestring(tctx, time(NULL)));
3054
3055         /* The workstation handles the "servicePrincipalName" and DNS hostname
3056            updates */
3057         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3058
3059         query.workstation_info = &q1;
3060
3061         if (sam_ctx) {
3062                 /* Gets back the old DNS hostname in AD */
3063                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3064                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3065                 old_dnsname =
3066                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3067                 
3068                 /* Gets back the "servicePrincipalName"s in AD */
3069                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3070                 if (spn_el != NULL) {
3071                         for (i=0; i < spn_el->num_values; i++) {
3072                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3073                                 spns[i] = (char *) spn_el->values[i].data;
3074                         }
3075                         num_spns = i;
3076                 }
3077         }
3078
3079         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3080                 "LogonGetDomainInfo failed");
3081         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3082         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3083
3084         smb_msleep(250);
3085
3086         if (sam_ctx) {
3087                 /* AD workstation infos entry check */
3088                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3089                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3090                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3091                 torture_assert_str_equal(tctx,
3092                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3093                                          q1.os_name.string, "'operatingSystem' wrong!");
3094                 torture_assert_str_equal(tctx,
3095                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3096                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3097                 torture_assert_str_equal(tctx,
3098                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3099                                          version_str, "'operatingSystemVersion' wrong!");
3100
3101                 if (old_dnsname != NULL) {
3102                         /* If before a DNS hostname was set then it should remain
3103                            the same in combination with the "servicePrincipalName"s.
3104                            The DNS hostname should also be returned by our
3105                            "LogonGetDomainInfo" call (in the domain info structure). */
3106                         
3107                         torture_assert_str_equal(tctx,
3108                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3109                                                  old_dnsname, "'DNS hostname' was not set!");
3110                         
3111                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3112                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3113                                        "'servicePrincipalName's not set!");
3114                         torture_assert(tctx, spn_el->num_values == num_spns,
3115                                        "'servicePrincipalName's incorrect!");
3116                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3117                                 torture_assert_str_equal(tctx,
3118                                                          (char *) spn_el->values[i].data,
3119                                 spns[i], "'servicePrincipalName's incorrect!");
3120
3121                         torture_assert_str_equal(tctx,
3122                                                  info.domain_info->dns_hostname.string,
3123                                                  old_dnsname,
3124                                                  "Out 'DNS hostname' doesn't match the old one!");
3125                 } else {
3126                         /* If no DNS hostname was set then also now none should be set,
3127                            the "servicePrincipalName"s should remain empty and no DNS
3128                            hostname should be returned by our "LogonGetDomainInfo"
3129                            call (in the domain info structure). */
3130                         
3131                         torture_assert(tctx,
3132                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3133                                        "'DNS hostname' was set!");
3134                         
3135                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3136                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3137                                        "'servicePrincipalName's were set!");
3138                         
3139                         torture_assert(tctx,
3140                                        info.domain_info->dns_hostname.string == NULL,
3141                                        "Out 'DNS host name' was set!");
3142                 }
3143         }
3144
3145         /* Checks "workstation flags" */
3146         torture_assert(tctx,
3147                 info.domain_info->workstation_flags
3148                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3149                 "Out 'workstation flags' don't match!");
3150
3151
3152         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3153         netlogon_creds_client_authenticator(creds, &a);
3154
3155         /* Wipe out the osVersion, and prove which values still 'stick' */
3156         q1.os_version.os = NULL;
3157
3158         /* Change also the DNS hostname to test differences in behaviour */
3159         talloc_free(discard_const_p(char, q1.dns_hostname));
3160         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3161                 lpcfg_dnsdomain(tctx->lp_ctx));
3162
3163         /* The workstation handles the "servicePrincipalName" and DNS hostname
3164            updates */
3165         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3166
3167         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3168                 "LogonGetDomainInfo failed");
3169         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3170
3171         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3172
3173         smb_msleep(250);
3174
3175         if (sam_ctx) {
3176                 /* AD workstation infos entry check */
3177                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3178                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3179                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3180
3181                 torture_assert_str_equal(tctx,
3182                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3183                                          q1.os_name.string, "'operatingSystem' should stick!");
3184                 torture_assert(tctx,
3185                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3186                                "'operatingSystemServicePack' shouldn't stick!");
3187                 torture_assert(tctx,
3188                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3189                                "'operatingSystemVersion' shouldn't stick!");
3190
3191                 /* The DNS host name shouldn't have been updated by the server */
3192
3193                 torture_assert_str_equal(tctx,
3194                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3195                                          old_dnsname, "'DNS host name' did change!");
3196                 
3197                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3198                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3199                    3.5.4.3.9 */
3200                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3201                 torture_assert(tctx, spn_el != NULL,
3202                                "There should exist 'servicePrincipalName's in AD!");
3203                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3204                 for (i=0; i < spn_el->num_values; i++)
3205                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3206                                 break;
3207                 torture_assert(tctx, i != spn_el->num_values,
3208                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3209                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3210                 for (i=0; i < spn_el->num_values; i++)
3211                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3212                                 break;
3213                 torture_assert(tctx, i != spn_el->num_values,
3214                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3215                 
3216                 /* Check that the out DNS hostname was set properly */
3217                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3218                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3219         }
3220
3221         /* Checks "workstation flags" */
3222         torture_assert(tctx,
3223                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3224                 "Out 'workstation flags' don't match!");
3225
3226
3227         /* Now try the same but the workstation flags set to 0 */
3228
3229         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3230         netlogon_creds_client_authenticator(creds, &a);
3231
3232         /* Change also the DNS hostname to test differences in behaviour */
3233         talloc_free(discard_const_p(char, q1.dns_hostname));
3234         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3235                 lpcfg_dnsdomain(tctx->lp_ctx));
3236
3237         /* Wipe out the osVersion, and prove which values still 'stick' */
3238         q1.os_version.os = NULL;
3239
3240         /* Let the DC handle the "servicePrincipalName" and DNS hostname
3241            updates */
3242         q1.workstation_flags = 0;
3243
3244         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3245                 "LogonGetDomainInfo failed");
3246         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3247         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3248
3249         smb_msleep(250);
3250
3251         if (sam_ctx) {
3252                 /* AD workstation infos entry check */
3253                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3254                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3255                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3256
3257                 torture_assert_str_equal(tctx,
3258                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3259                                          q1.os_name.string, "'operatingSystem' should stick!");
3260                 torture_assert(tctx,
3261                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3262                                "'operatingSystemServicePack' shouldn't stick!");
3263                 torture_assert(tctx,
3264                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3265                                "'operatingSystemVersion' shouldn't stick!");
3266
3267                 /* The DNS host name shouldn't have been updated by the server */
3268
3269                 torture_assert_str_equal(tctx,
3270                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3271                                          old_dnsname, "'DNS host name' did change!");
3272
3273                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3274                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3275                    3.5.4.3.9 */
3276                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3277                 torture_assert(tctx, spn_el != NULL,
3278                                "There should exist 'servicePrincipalName's in AD!");
3279                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3280                 for (i=0; i < spn_el->num_values; i++)
3281                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3282                                 break;
3283                 torture_assert(tctx, i != spn_el->num_values,
3284                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3285                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3286                 for (i=0; i < spn_el->num_values; i++)
3287                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3288                                 break;
3289                 torture_assert(tctx, i != spn_el->num_values,
3290                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3291
3292                 /* Here the server gives us NULL as the out DNS hostname */
3293                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3294                                "Out 'DNS hostname' should be NULL!");
3295         }
3296
3297         /* Checks "workstation flags" */
3298         torture_assert(tctx,
3299                 info.domain_info->workstation_flags == 0,
3300                 "Out 'workstation flags' don't match!");
3301
3302
3303         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3304         netlogon_creds_client_authenticator(creds, &a);
3305
3306         /* Put the DNS hostname back */
3307         talloc_free(discard_const_p(char, q1.dns_hostname));
3308         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3309                 lpcfg_dnsdomain(tctx->lp_ctx));
3310
3311         /* The workstation handles the "servicePrincipalName" and DNS hostname
3312            updates */
3313         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3314
3315         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3316                 "LogonGetDomainInfo failed");
3317         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3318         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3319
3320         smb_msleep(250);
3321
3322         /* Now the in/out DNS hostnames should be the same */
3323         torture_assert_str_equal(tctx,
3324                 info.domain_info->dns_hostname.string,
3325                 query.workstation_info->dns_hostname,
3326                 "In/Out 'DNS hostnames' don't match!");
3327         old_dnsname = info.domain_info->dns_hostname.string;
3328
3329         /* Checks "workstation flags" */
3330         torture_assert(tctx,
3331                 info.domain_info->workstation_flags
3332                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3333                 "Out 'workstation flags' don't match!");
3334
3335         /* Checks for trusted domains */
3336         torture_assert(tctx,
3337                 (info.domain_info->trusted_domain_count != 0)
3338                 && (info.domain_info->trusted_domains != NULL),
3339                 "Trusted domains have been requested!");
3340
3341
3342         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3343         netlogon_creds_client_authenticator(creds, &a);
3344
3345         /* The workstation handles the "servicePrincipalName" and DNS hostname
3346            updates and requests inbound trusts */
3347         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3348                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3349
3350         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3351                 "LogonGetDomainInfo failed");
3352         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3353         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3354
3355         smb_msleep(250);
3356
3357         /* Checks "workstation flags" */
3358         torture_assert(tctx,
3359                 info.domain_info->workstation_flags
3360                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3361                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3362                 "Out 'workstation flags' don't match!");
3363
3364         /* Checks for trusted domains */
3365         torture_assert(tctx,
3366                 (info.domain_info->trusted_domain_count != 0)
3367                 && (info.domain_info->trusted_domains != NULL),
3368                 "Trusted domains have been requested!");
3369
3370
3371         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3372         netlogon_creds_client_authenticator(creds, &a);
3373
3374         query.workstation_info->dns_hostname = NULL;
3375
3376         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3377                 "LogonGetDomainInfo failed");
3378         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3379         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3380
3381         /* The old DNS hostname should stick */
3382         torture_assert_str_equal(tctx,
3383                 info.domain_info->dns_hostname.string,
3384                 old_dnsname,
3385                 "'DNS hostname' changed!");
3386
3387
3388         if (!torture_setting_bool(tctx, "dangerous", false)) {
3389                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n");
3390         } else {
3391                 /* Try a call without the workstation information structure */
3392
3393                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n");
3394                 netlogon_creds_client_authenticator(creds, &a);
3395
3396                 query.workstation_info = NULL;
3397
3398                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3399                         "LogonGetDomainInfo failed");
3400                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3401                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3402         }
3403
3404         return true;
3405 }
3406
3407 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
3408                                      struct dcerpc_pipe *p,
3409                                      struct cli_credentials *machine_credentials)
3410 {
3411         NTSTATUS status;
3412         struct netr_LogonGetDomainInfo r;
3413         struct netr_WorkstationInformation q1;
3414         struct netr_Authenticator a;
3415 #define ASYNC_COUNT 100
3416         struct netlogon_creds_CredentialState *creds;
3417         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3418         struct tevent_req *req[ASYNC_COUNT];
3419         int i;
3420         union netr_WorkstationInfo query;
3421         union netr_DomainInfo info;
3422
3423         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3424
3425         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3426                                     machine_credentials, &creds)) {
3427                 return false;
3428         }
3429
3430         ZERO_STRUCT(r);
3431         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3432         r.in.computer_name = TEST_MACHINE_NAME;
3433         r.in.credential = &a;
3434         r.in.level = 1;
3435         r.in.return_authenticator = &a;
3436         r.in.query = &query;
3437         r.out.return_authenticator = &a;
3438         r.out.info = &info;
3439
3440         ZERO_STRUCT(q1);
3441         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3442                 lpcfg_dnsdomain(tctx->lp_ctx));
3443         q1.sitename = "Default-First-Site-Name";
3444         q1.os_name.string = "UNIX/Linux or similar";
3445
3446         query.workstation_info = &q1;
3447
3448         for (i=0;i<ASYNC_COUNT;i++) {
3449                 netlogon_creds_client_authenticator(creds, &a);
3450
3451                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3452                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3453
3454                 /* even with this flush per request a w2k3 server seems to 
3455                    clag with multiple outstanding requests. bleergh. */
3456                 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0, 
3457                                          "tevent_loop_once failed");
3458         }
3459
3460         for (i=0;i<ASYNC_COUNT;i++) {
3461                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3462                                          "tevent_req_poll() failed");
3463
3464                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3465
3466                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3467                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
3468
3469                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
3470                         "Credential chaining failed at async");
3471         }
3472
3473         torture_comment(tctx, 
3474                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3475
3476         return true;
3477 }
3478
3479 static bool test_ManyGetDCName(struct torture_context *tctx, 
3480                                struct dcerpc_pipe *p)
3481 {
3482         NTSTATUS status;
3483         struct dcerpc_pipe *p2;
3484         struct lsa_ObjectAttribute attr;
3485         struct lsa_QosInfo qos;
3486         struct lsa_OpenPolicy2 o;
3487         struct policy_handle lsa_handle;
3488         struct lsa_DomainList domains;
3489
3490         struct lsa_EnumTrustDom t;
3491         uint32_t resume_handle = 0;
3492         struct netr_GetAnyDCName d;
3493         const char *dcname = NULL;
3494         struct dcerpc_binding_handle *b = p->binding_handle;
3495         struct dcerpc_binding_handle *b2;
3496
3497         int i;
3498
3499         if (p->conn->transport.transport != NCACN_NP) {
3500                 return true;
3501         }
3502
3503         torture_comment(tctx, "Torturing GetDCName\n");
3504
3505         status = dcerpc_secondary_connection(p, &p2, p->binding);
3506         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3507
3508         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3509         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3510         b2 = p2->binding_handle;
3511
3512         qos.len = 0;
3513         qos.impersonation_level = 2;
3514         qos.context_mode = 1;
3515         qos.effective_only = 0;
3516
3517         attr.len = 0;
3518         attr.root_dir = NULL;
3519         attr.object_name = NULL;
3520         attr.attributes = 0;
3521         attr.sec_desc = NULL;
3522         attr.sec_qos = &qos;
3523
3524         o.in.system_name = "\\";
3525         o.in.attr = &attr;
3526         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3527         o.out.handle = &lsa_handle;
3528
3529         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3530                 "OpenPolicy2 failed");
3531         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3532
3533         t.in.handle = &lsa_handle;
3534         t.in.resume_handle = &resume_handle;
3535         t.in.max_size = 1000;
3536         t.out.domains = &domains;
3537         t.out.resume_handle = &resume_handle;
3538
3539         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3540                 "EnumTrustDom failed");
3541
3542         if ((!NT_STATUS_IS_OK(t.out.result) &&
3543              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3544                 torture_fail(tctx, "Could not list domains");
3545
3546         talloc_free(p2);
3547
3548         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3549                                             dcerpc_server_name(p));
3550         d.out.dcname = &dcname;
3551
3552         for (i=0; i<domains.count * 4; i++) {
3553                 struct lsa_DomainInfo *info =
3554                         &domains.domains[rand()%domains.count];
3555
3556                 d.in.domainname = info->name.string;
3557
3558                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3559                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3560
3561                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3562                        dcname ? dcname : "unknown");
3563         }
3564
3565         return true;
3566 }
3567
3568 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3569                                         struct dcerpc_pipe *p,
3570                                         struct cli_credentials *machine_credentials)
3571 {
3572         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3573         struct netlogon_creds_CredentialState *creds;
3574         int i;
3575
3576         if (!test_SetupCredentials2(p, tctx, 0,
3577                                     machine_credentials,
3578                                     cli_credentials_get_secure_channel_type(machine_credentials),
3579                                     &creds)) {
3580                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3581         }
3582
3583         for (i=0; i < ARRAY_SIZE(flags); i++) {
3584                 torture_assert(tctx,
3585                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3586                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3587         }
3588
3589         return true;
3590 }
3591
3592 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3593 {
3594         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3595         struct torture_rpc_tcase *tcase;
3596         struct torture_test *test;
3597
3598         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3599                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3600
3601         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3602         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3603         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3604         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3605         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3606         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3607         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3608         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3609         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3610         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3611         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3612         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3613         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3614         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3615         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3616         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3617         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3618         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3619         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3620         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3621         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3622         test->dangerous = true;
3623         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3624         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3625         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3626         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3627         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3628         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3629         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3630         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3631
3632         return suite;
3633 }
3634
3635 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3636 {
3637         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3638         struct torture_rpc_tcase *tcase;
3639
3640         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3641                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3642
3643         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3644         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3645         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3646         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3647         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3648         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3649
3650         return suite;
3651 }
3652
3653 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3654 {
3655         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3656         struct torture_rpc_tcase *tcase;
3657
3658         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3659                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3660         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3661         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3662         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3663
3664         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3665                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3666         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3667         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3668         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3669
3670         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3671                                                   &ndr_table_netlogon);
3672         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3673         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3674         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3675
3676         return suite;
3677 }