s4-torture: Test rpc schannel netr_LogonGetCapability.
[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 GetCapabilities
889 */
890 bool test_netlogon_capabilities(struct dcerpc_pipe *p, struct torture_context *tctx,
891                                 struct cli_credentials *credentials,
892                                 struct netlogon_creds_CredentialState *creds)
893 {
894         NTSTATUS status;
895         struct netr_LogonGetCapabilities r;
896         union netr_Capabilities capabilities;
897         struct netr_Authenticator auth, return_auth;
898         struct netlogon_creds_CredentialState tmp_creds;
899         struct dcerpc_binding_handle *b = p->binding_handle;
900
901         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
902         r.in.computer_name = cli_credentials_get_workstation(credentials);
903         r.in.credential = &auth;
904         r.in.return_authenticator = &return_auth;
905         r.in.query_level = 1;
906         r.out.capabilities = &capabilities;
907         r.out.return_authenticator = &return_auth;
908
909         torture_comment(tctx, "Testing LogonGetCapabilities\n");
910
911         ZERO_STRUCT(return_auth);
912
913         /*
914          * we need to operate on a temporary copy of creds
915          * because dcerpc_netr_LogonGetCapabilities was
916          * dcerpc_netr_DummyFunction and returns NT_STATUS_NOT_IMPLEMENTED
917          * without looking a the authenticator.
918          */
919         tmp_creds = *creds;
920         netlogon_creds_client_authenticator(&tmp_creds, &auth);
921
922         status = dcerpc_netr_LogonGetCapabilities_r(b, tctx, &r);
923         torture_assert_ntstatus_ok(tctx, status, "LogonGetCapabilities failed");
924         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
925                 return true;
926         }
927
928         *creds = tmp_creds;
929
930         torture_assert(tctx, netlogon_creds_client_check(creds,
931                                                          &r.out.return_authenticator->cred),
932                        "Credential chaining failed");
933
934         torture_assert_int_equal(tctx, creds->negotiate_flags,
935                                  capabilities.server_capabilities,
936                                  "negotiate flags");
937
938         return true;
939 }
940
941 /*
942   try a netlogon SamLogon
943 */
944 static bool test_SamLogon(struct torture_context *tctx, 
945                           struct dcerpc_pipe *p,
946                           struct cli_credentials *credentials)
947 {
948         struct netlogon_creds_CredentialState *creds;
949
950         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
951                 return false;
952         }
953
954         return test_netlogon_ops(p, tctx, credentials, creds);
955 }
956
957 static bool test_SamLogon_NULL_domain(struct torture_context *tctx,
958                                       struct dcerpc_pipe *p,
959                                       struct cli_credentials *credentials)
960 {
961         struct netlogon_creds_CredentialState *creds;
962
963         if (!test_SetupCredentials(p, tctx, credentials, &creds)) {
964                 return false;
965         }
966
967         return test_netlogon_ops_args(p, tctx, credentials, creds, true);
968 }
969
970 /* we remember the sequence numbers so we can easily do a DatabaseDelta */
971 static uint64_t sequence_nums[3];
972
973 /*
974   try a netlogon DatabaseSync
975 */
976 static bool test_DatabaseSync(struct torture_context *tctx, 
977                               struct dcerpc_pipe *p,
978                               struct cli_credentials *machine_credentials)
979 {
980         struct netr_DatabaseSync r;
981         struct netlogon_creds_CredentialState *creds;
982         const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS}; 
983         int i;
984         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
985         struct netr_Authenticator credential, return_authenticator;
986         struct dcerpc_binding_handle *b = p->binding_handle;
987
988         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
989                 return false;
990         }
991
992         ZERO_STRUCT(return_authenticator);
993
994         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
995         r.in.computername = TEST_MACHINE_NAME;
996         r.in.preferredmaximumlength = (uint32_t)-1;
997         r.in.return_authenticator = &return_authenticator;
998         r.out.delta_enum_array = &delta_enum_array;
999         r.out.return_authenticator = &return_authenticator;
1000
1001         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1002
1003                 uint32_t sync_context = 0;
1004
1005                 r.in.database_id = database_ids[i];
1006                 r.in.sync_context = &sync_context;
1007                 r.out.sync_context = &sync_context;
1008
1009                 torture_comment(tctx, "Testing DatabaseSync of id %d\n", r.in.database_id);
1010
1011                 do {
1012                         netlogon_creds_client_authenticator(creds, &credential);
1013
1014                         r.in.credential = &credential;
1015
1016                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync_r(b, tctx, &r),
1017                                 "DatabaseSync failed");
1018                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1019                             break;
1020
1021                         /* Native mode servers don't do this */
1022                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1023                                 return true;
1024                         }
1025                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync");
1026
1027                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
1028                                 torture_comment(tctx, "Credential chaining failed\n");
1029                         }
1030
1031                         if (delta_enum_array &&
1032                             delta_enum_array->num_deltas > 0 &&
1033                             delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
1034                             delta_enum_array->delta_enum[0].delta_union.domain) {
1035                                 sequence_nums[r.in.database_id] = 
1036                                         delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
1037                                 torture_comment(tctx, "\tsequence_nums[%d]=%llu\n",
1038                                        r.in.database_id, 
1039                                        (unsigned long long)sequence_nums[r.in.database_id]);
1040                         }
1041                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1042         }
1043
1044         return true;
1045 }
1046
1047
1048 /*
1049   try a netlogon DatabaseDeltas
1050 */
1051 static bool test_DatabaseDeltas(struct torture_context *tctx, 
1052                                 struct dcerpc_pipe *p,
1053                                 struct cli_credentials *machine_credentials)
1054 {
1055         struct netr_DatabaseDeltas r;
1056         struct netlogon_creds_CredentialState *creds;
1057         struct netr_Authenticator credential;
1058         struct netr_Authenticator return_authenticator;
1059         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1060         const uint32_t database_ids[] = {0, 1, 2}; 
1061         int i;
1062         struct dcerpc_binding_handle *b = p->binding_handle;
1063
1064         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1065                 return false;
1066         }
1067
1068         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1069         r.in.computername = TEST_MACHINE_NAME;
1070         r.in.preferredmaximumlength = (uint32_t)-1;
1071         ZERO_STRUCT(r.in.return_authenticator);
1072         r.out.return_authenticator = &return_authenticator;
1073         r.out.delta_enum_array = &delta_enum_array;
1074
1075         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
1076                 r.in.database_id = database_ids[i];
1077                 r.in.sequence_num = &sequence_nums[r.in.database_id];
1078
1079                 if (*r.in.sequence_num == 0) continue;
1080
1081                 *r.in.sequence_num -= 1;
1082
1083                 torture_comment(tctx, "Testing DatabaseDeltas of id %d at %llu\n", 
1084                        r.in.database_id, (unsigned long long)*r.in.sequence_num);
1085
1086                 do {
1087                         netlogon_creds_client_authenticator(creds, &credential);
1088
1089                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseDeltas_r(b, tctx, &r),
1090                                 "DatabaseDeltas failed");
1091                         if (NT_STATUS_EQUAL(r.out.result,
1092                                              NT_STATUS_SYNCHRONIZATION_REQUIRED)) {
1093                                 torture_comment(tctx, "not considering %s to be an error\n",
1094                                        nt_errstr(r.out.result));
1095                                 return true;
1096                         }
1097                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
1098                             break;
1099
1100                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseDeltas");
1101
1102                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1103                                 torture_comment(tctx, "Credential chaining failed\n");
1104                         }
1105
1106                         (*r.in.sequence_num)++;
1107                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
1108         }
1109
1110         return true;
1111 }
1112
1113 static bool test_DatabaseRedo(struct torture_context *tctx,
1114                               struct dcerpc_pipe *p,
1115                               struct cli_credentials *machine_credentials)
1116 {
1117         struct netr_DatabaseRedo r;
1118         struct netlogon_creds_CredentialState *creds;
1119         struct netr_Authenticator credential;
1120         struct netr_Authenticator return_authenticator;
1121         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
1122         struct netr_ChangeLogEntry e;
1123         struct dom_sid null_sid, *sid;
1124         int i,d;
1125         struct dcerpc_binding_handle *b = p->binding_handle;
1126
1127         ZERO_STRUCT(null_sid);
1128
1129         sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
1130
1131         {
1132
1133         struct {
1134                 uint32_t rid;
1135                 uint16_t flags;
1136                 uint8_t db_index;
1137                 uint8_t delta_type;
1138                 struct dom_sid sid;
1139                 const char *name;
1140                 NTSTATUS expected_error;
1141                 uint32_t expected_num_results;
1142                 uint8_t expected_delta_type_1;
1143                 uint8_t expected_delta_type_2;
1144                 const char *comment;
1145         } changes[] = {
1146
1147                 /* SAM_DATABASE_DOMAIN */
1148
1149                 {
1150                         .rid                    = 0,
1151                         .flags                  = 0,
1152                         .db_index               = SAM_DATABASE_DOMAIN,
1153                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1154                         .sid                    = null_sid,
1155                         .name                   = NULL,
1156                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1157                         .expected_num_results   = 0,
1158                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1159                 },
1160                 {
1161                         .rid                    = 0,
1162                         .flags                  = 0,
1163                         .db_index               = SAM_DATABASE_DOMAIN,
1164                         .delta_type             = 0,
1165                         .sid                    = null_sid,
1166                         .name                   = NULL,
1167                         .expected_error         = NT_STATUS_OK,
1168                         .expected_num_results   = 1,
1169                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1170                         .comment                = "NULL DELTA"
1171                 },
1172                 {
1173                         .rid                    = 0,
1174                         .flags                  = 0,
1175                         .db_index               = SAM_DATABASE_DOMAIN,
1176                         .delta_type             = NETR_DELTA_DOMAIN,
1177                         .sid                    = null_sid,
1178                         .name                   = NULL,
1179                         .expected_error         = NT_STATUS_OK,
1180                         .expected_num_results   = 1,
1181                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1182                         .comment                = "NETR_DELTA_DOMAIN"
1183                 },
1184                 {
1185                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1186                         .flags                  = 0,
1187                         .db_index               = SAM_DATABASE_DOMAIN,
1188                         .delta_type             = NETR_DELTA_USER,
1189                         .sid                    = null_sid,
1190                         .name                   = NULL,
1191                         .expected_error         = NT_STATUS_OK,
1192                         .expected_num_results   = 1,
1193                         .expected_delta_type_1  = NETR_DELTA_USER,
1194                         .comment                = "NETR_DELTA_USER by rid 500"
1195                 },
1196                 {
1197                         .rid                    = DOMAIN_RID_GUEST,
1198                         .flags                  = 0,
1199                         .db_index               = SAM_DATABASE_DOMAIN,
1200                         .delta_type             = NETR_DELTA_USER,
1201                         .sid                    = null_sid,
1202                         .name                   = NULL,
1203                         .expected_error         = NT_STATUS_OK,
1204                         .expected_num_results   = 1,
1205                         .expected_delta_type_1  = NETR_DELTA_USER,
1206                         .comment                = "NETR_DELTA_USER by rid 501"
1207                 },
1208                 {
1209                         .rid                    = 0,
1210                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1211                         .db_index               = SAM_DATABASE_DOMAIN,
1212                         .delta_type             = NETR_DELTA_USER,
1213                         .sid                    = *sid,
1214                         .name                   = NULL,
1215                         .expected_error         = NT_STATUS_OK,
1216                         .expected_num_results   = 1,
1217                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1218                         .comment                = "NETR_DELTA_USER by sid and flags"
1219                 },
1220                 {
1221                         .rid                    = 0,
1222                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1223                         .db_index               = SAM_DATABASE_DOMAIN,
1224                         .delta_type             = NETR_DELTA_USER,
1225                         .sid                    = null_sid,
1226                         .name                   = NULL,
1227                         .expected_error         = NT_STATUS_OK,
1228                         .expected_num_results   = 1,
1229                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1230                         .comment                = "NETR_DELTA_USER by null_sid and flags"
1231                 },
1232                 {
1233                         .rid                    = 0,
1234                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1235                         .db_index               = SAM_DATABASE_DOMAIN,
1236                         .delta_type             = NETR_DELTA_USER,
1237                         .sid                    = null_sid,
1238                         .name                   = "administrator",
1239                         .expected_error         = NT_STATUS_OK,
1240                         .expected_num_results   = 1,
1241                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1242                         .comment                = "NETR_DELTA_USER by name 'administrator'"
1243                 },
1244                 {
1245                         .rid                    = DOMAIN_RID_ADMINS,
1246                         .flags                  = 0,
1247                         .db_index               = SAM_DATABASE_DOMAIN,
1248                         .delta_type             = NETR_DELTA_GROUP,
1249                         .sid                    = null_sid,
1250                         .name                   = NULL,
1251                         .expected_error         = NT_STATUS_OK,
1252                         .expected_num_results   = 2,
1253                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1254                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1255                         .comment                = "NETR_DELTA_GROUP by rid 512"
1256                 },
1257                 {
1258                         .rid                    = DOMAIN_RID_ADMINS,
1259                         .flags                  = 0,
1260                         .db_index               = SAM_DATABASE_DOMAIN,
1261                         .delta_type             = NETR_DELTA_GROUP_MEMBER,
1262                         .sid                    = null_sid,
1263                         .name                   = NULL,
1264                         .expected_error         = NT_STATUS_OK,
1265                         .expected_num_results   = 2,
1266                         .expected_delta_type_1  = NETR_DELTA_GROUP,
1267                         .expected_delta_type_2  = NETR_DELTA_GROUP_MEMBER,
1268                         .comment                = "NETR_DELTA_GROUP_MEMBER by rid 512"
1269                 },
1270
1271
1272                 /* SAM_DATABASE_BUILTIN */
1273
1274                 {
1275                         .rid                    = 0,
1276                         .flags                  = 0,
1277                         .db_index               = SAM_DATABASE_BUILTIN,
1278                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1279                         .sid                    = null_sid,
1280                         .name                   = NULL,
1281                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1282                         .expected_num_results   = 0,
1283                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1284                 },
1285                 {
1286                         .rid                    = 0,
1287                         .flags                  = 0,
1288                         .db_index               = SAM_DATABASE_BUILTIN,
1289                         .delta_type             = NETR_DELTA_DOMAIN,
1290                         .sid                    = null_sid,
1291                         .name                   = NULL,
1292                         .expected_error         = NT_STATUS_OK,
1293                         .expected_num_results   = 1,
1294                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1295                         .comment                = "NETR_DELTA_DOMAIN"
1296                 },
1297                 {
1298                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1299                         .flags                  = 0,
1300                         .db_index               = SAM_DATABASE_BUILTIN,
1301                         .delta_type             = NETR_DELTA_USER,
1302                         .sid                    = null_sid,
1303                         .name                   = NULL,
1304                         .expected_error         = NT_STATUS_OK,
1305                         .expected_num_results   = 1,
1306                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1307                         .comment                = "NETR_DELTA_USER by rid 500"
1308                 },
1309                 {
1310                         .rid                    = 0,
1311                         .flags                  = 0,
1312                         .db_index               = SAM_DATABASE_BUILTIN,
1313                         .delta_type             = NETR_DELTA_USER,
1314                         .sid                    = null_sid,
1315                         .name                   = NULL,
1316                         .expected_error         = NT_STATUS_OK,
1317                         .expected_num_results   = 1,
1318                         .expected_delta_type_1  = NETR_DELTA_DELETE_USER,
1319                         .comment                = "NETR_DELTA_USER"
1320                 },
1321                 {
1322                         .rid                    = 544,
1323                         .flags                  = 0,
1324                         .db_index               = SAM_DATABASE_BUILTIN,
1325                         .delta_type             = NETR_DELTA_ALIAS,
1326                         .sid                    = null_sid,
1327                         .name                   = NULL,
1328                         .expected_error         = NT_STATUS_OK,
1329                         .expected_num_results   = 2,
1330                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1331                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1332                         .comment                = "NETR_DELTA_ALIAS by rid 544"
1333                 },
1334                 {
1335                         .rid                    = 544,
1336                         .flags                  = 0,
1337                         .db_index               = SAM_DATABASE_BUILTIN,
1338                         .delta_type             = NETR_DELTA_ALIAS_MEMBER,
1339                         .sid                    = null_sid,
1340                         .name                   = NULL,
1341                         .expected_error         = NT_STATUS_OK,
1342                         .expected_num_results   = 2,
1343                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1344                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1345                         .comment                = "NETR_DELTA_ALIAS_MEMBER by rid 544"
1346                 },
1347                 {
1348                         .rid                    = 544,
1349                         .flags                  = 0,
1350                         .db_index               = SAM_DATABASE_BUILTIN,
1351                         .delta_type             = 0,
1352                         .sid                    = null_sid,
1353                         .name                   = NULL,
1354                         .expected_error         = NT_STATUS_OK,
1355                         .expected_num_results   = 1,
1356                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1357                         .comment                = "NULL DELTA by rid 544"
1358                 },
1359                 {
1360                         .rid                    = 544,
1361                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1362                         .db_index               = SAM_DATABASE_BUILTIN,
1363                         .delta_type             = 0,
1364                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1365                         .name                   = NULL,
1366                         .expected_error         = NT_STATUS_OK,
1367                         .expected_num_results   = 1,
1368                         .expected_delta_type_1  = NETR_DELTA_DOMAIN,
1369                         .comment                = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
1370                 },
1371                 {
1372                         .rid                    = 544,
1373                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1374                         .db_index               = SAM_DATABASE_BUILTIN,
1375                         .delta_type             = NETR_DELTA_ALIAS,
1376                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1377                         .name                   = NULL,
1378                         .expected_error         = NT_STATUS_OK,
1379                         .expected_num_results   = 2,
1380                         .expected_delta_type_1  = NETR_DELTA_ALIAS,
1381                         .expected_delta_type_2  = NETR_DELTA_ALIAS_MEMBER,
1382                         .comment                = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
1383                 },
1384                 {
1385                         .rid                    = 0,
1386                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1387                         .db_index               = SAM_DATABASE_BUILTIN,
1388                         .delta_type             = NETR_DELTA_ALIAS,
1389                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
1390                         .name                   = NULL,
1391                         .expected_error         = NT_STATUS_OK,
1392                         .expected_num_results   = 1,
1393                         .expected_delta_type_1  = NETR_DELTA_DELETE_ALIAS,
1394                         .comment                = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
1395                 },
1396
1397                 /* SAM_DATABASE_PRIVS */
1398
1399                 {
1400                         .rid                    = 0,
1401                         .flags                  = 0,
1402                         .db_index               = SAM_DATABASE_PRIVS,
1403                         .delta_type             = 0,
1404                         .sid                    = null_sid,
1405                         .name                   = NULL,
1406                         .expected_error         = NT_STATUS_ACCESS_DENIED,
1407                         .expected_num_results   = 0,
1408                         .comment                = "NULL DELTA"
1409                 },
1410                 {
1411                         .rid                    = 0,
1412                         .flags                  = 0,
1413                         .db_index               = SAM_DATABASE_PRIVS,
1414                         .delta_type             = NETR_DELTA_MODIFY_COUNT,
1415                         .sid                    = null_sid,
1416                         .name                   = NULL,
1417                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED,
1418                         .expected_num_results   = 0,
1419                         .comment                = "NETR_DELTA_MODIFY_COUNT"
1420                 },
1421                 {
1422                         .rid                    = 0,
1423                         .flags                  = 0,
1424                         .db_index               = SAM_DATABASE_PRIVS,
1425                         .delta_type             = NETR_DELTA_POLICY,
1426                         .sid                    = null_sid,
1427                         .name                   = NULL,
1428                         .expected_error         = NT_STATUS_OK,
1429                         .expected_num_results   = 1,
1430                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1431                         .comment                = "NETR_DELTA_POLICY"
1432                 },
1433                 {
1434                         .rid                    = 0,
1435                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1436                         .db_index               = SAM_DATABASE_PRIVS,
1437                         .delta_type             = NETR_DELTA_POLICY,
1438                         .sid                    = null_sid,
1439                         .name                   = NULL,
1440                         .expected_error         = NT_STATUS_OK,
1441                         .expected_num_results   = 1,
1442                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1443                         .comment                = "NETR_DELTA_POLICY by null sid and flags"
1444                 },
1445                 {
1446                         .rid                    = 0,
1447                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1448                         .db_index               = SAM_DATABASE_PRIVS,
1449                         .delta_type             = NETR_DELTA_POLICY,
1450                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
1451                         .name                   = NULL,
1452                         .expected_error         = NT_STATUS_OK,
1453                         .expected_num_results   = 1,
1454                         .expected_delta_type_1  = NETR_DELTA_POLICY,
1455                         .comment                = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
1456                 },
1457                 {
1458                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1459                         .flags                  = 0,
1460                         .db_index               = SAM_DATABASE_PRIVS,
1461                         .delta_type             = NETR_DELTA_ACCOUNT,
1462                         .sid                    = null_sid,
1463                         .name                   = NULL,
1464                         .expected_error         = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
1465                         .expected_num_results   = 0,
1466                         .comment                = "NETR_DELTA_ACCOUNT by rid 500"
1467                 },
1468                 {
1469                         .rid                    = 0,
1470                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1471                         .db_index               = SAM_DATABASE_PRIVS,
1472                         .delta_type             = NETR_DELTA_ACCOUNT,
1473                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1474                         .name                   = NULL,
1475                         .expected_error         = NT_STATUS_OK,
1476                         .expected_num_results   = 1,
1477                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1478                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
1479                 },
1480                 {
1481                         .rid                    = 0,
1482                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1483                                                   NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
1484                         .db_index               = SAM_DATABASE_PRIVS,
1485                         .delta_type             = NETR_DELTA_ACCOUNT,
1486                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1487                         .name                   = NULL,
1488                         .expected_error         = NT_STATUS_OK,
1489                         .expected_num_results   = 1,
1490                         .expected_delta_type_1  = NETR_DELTA_ACCOUNT,
1491                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
1492                 },
1493                 {
1494                         .rid                    = 0,
1495                         .flags                  = NETR_CHANGELOG_SID_INCLUDED |
1496                                                   NETR_CHANGELOG_NAME_INCLUDED,
1497                         .db_index               = SAM_DATABASE_PRIVS,
1498                         .delta_type             = NETR_DELTA_ACCOUNT,
1499                         .sid                    = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
1500                         .name                   = NULL,
1501                         .expected_error         = NT_STATUS_INVALID_PARAMETER,
1502                         .expected_num_results   = 0,
1503                         .comment                = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
1504                 },
1505                 {
1506                         .rid                    = DOMAIN_RID_ADMINISTRATOR,
1507                         .flags                  = NETR_CHANGELOG_SID_INCLUDED,
1508                         .db_index               = SAM_DATABASE_PRIVS,
1509                         .delta_type             = NETR_DELTA_ACCOUNT,
1510                         .sid                    = *sid,
1511                         .name                   = NULL,
1512                         .expected_error         = NT_STATUS_OK,
1513                         .expected_num_results   = 1,
1514                         .expected_delta_type_1  = NETR_DELTA_DELETE_ACCOUNT,
1515                         .comment                = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
1516                 },
1517                 {
1518                         .rid                    = 0,
1519                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1520                         .db_index               = SAM_DATABASE_PRIVS,
1521                         .delta_type             = NETR_DELTA_SECRET,
1522                         .sid                    = null_sid,
1523                         .name                   = "IsurelydontexistIhope",
1524                         .expected_error         = NT_STATUS_OK,
1525                         .expected_num_results   = 1,
1526                         .expected_delta_type_1  = NETR_DELTA_DELETE_SECRET,
1527                         .comment                = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
1528                 },
1529                 {
1530                         .rid                    = 0,
1531                         .flags                  = NETR_CHANGELOG_NAME_INCLUDED,
1532                         .db_index               = SAM_DATABASE_PRIVS,
1533                         .delta_type             = NETR_DELTA_SECRET,
1534                         .sid                    = null_sid,
1535                         .name                   = "G$BCKUPKEY_P",
1536                         .expected_error         = NT_STATUS_OK,
1537                         .expected_num_results   = 1,
1538                         .expected_delta_type_1  = NETR_DELTA_SECRET,
1539                         .comment                = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
1540                 }
1541         };
1542
1543         ZERO_STRUCT(return_authenticator);
1544
1545         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1546         r.in.computername = TEST_MACHINE_NAME;
1547         r.in.return_authenticator = &return_authenticator;
1548         r.out.return_authenticator = &return_authenticator;
1549         r.out.delta_enum_array = &delta_enum_array;
1550
1551         for (d=0; d<3; d++) {
1552                 const char *database = NULL;
1553
1554                 switch (d) {
1555                 case 0:
1556                         database = "SAM";
1557                         break;
1558                 case 1:
1559                         database = "BUILTIN";
1560                         break;
1561                 case 2:
1562                         database = "LSA";
1563                         break;
1564                 default:
1565                         break;
1566                 }
1567
1568                 torture_comment(tctx, "Testing DatabaseRedo\n");
1569
1570                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1571                         return false;
1572                 }
1573
1574                 for (i=0;i<ARRAY_SIZE(changes);i++) {
1575
1576                         if (d != changes[i].db_index) {
1577                                 continue;
1578                         }
1579
1580                         netlogon_creds_client_authenticator(creds, &credential);
1581
1582                         r.in.credential = &credential;
1583
1584                         e.serial_number1        = 0;
1585                         e.serial_number2        = 0;
1586                         e.object_rid            = changes[i].rid;
1587                         e.flags                 = changes[i].flags;
1588                         e.db_index              = changes[i].db_index;
1589                         e.delta_type            = changes[i].delta_type;
1590
1591                         switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
1592                         case NETR_CHANGELOG_SID_INCLUDED:
1593                                 e.object.object_sid             = changes[i].sid;
1594                                 break;
1595                         case NETR_CHANGELOG_NAME_INCLUDED:
1596                                 e.object.object_name            = changes[i].name;
1597                                 break;
1598                         default:
1599                                 break;
1600                         }
1601
1602                         r.in.change_log_entry = e;
1603
1604                         torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
1605                                 database, changes[i].comment);
1606
1607                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseRedo_r(b, tctx, &r),
1608                                 "DatabaseRedo failed");
1609                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
1610                                 return true;
1611                         }
1612
1613                         torture_assert_ntstatus_equal(tctx, r.out.result, changes[i].expected_error, changes[i].comment);
1614                         if (delta_enum_array) {
1615                                 torture_assert_int_equal(tctx,
1616                                         delta_enum_array->num_deltas,
1617                                         changes[i].expected_num_results,
1618                                         changes[i].comment);
1619                                 if (delta_enum_array->num_deltas > 0) {
1620                                         torture_assert_int_equal(tctx,
1621                                                 delta_enum_array->delta_enum[0].delta_type,
1622                                                 changes[i].expected_delta_type_1,
1623                                                 changes[i].comment);
1624                                 }
1625                                 if (delta_enum_array->num_deltas > 1) {
1626                                         torture_assert_int_equal(tctx,
1627                                                 delta_enum_array->delta_enum[1].delta_type,
1628                                                 changes[i].expected_delta_type_2,
1629                                                 changes[i].comment);
1630                                 }
1631                         }
1632
1633                         if (!netlogon_creds_client_check(creds, &return_authenticator.cred)) {
1634                                 torture_comment(tctx, "Credential chaining failed\n");
1635                                 if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1636                                         return false;
1637                                 }
1638                         }
1639                 }
1640         }
1641         }
1642
1643         return true;
1644 }
1645
1646 /*
1647   try a netlogon AccountDeltas
1648 */
1649 static bool test_AccountDeltas(struct torture_context *tctx, 
1650                                struct dcerpc_pipe *p,
1651                                struct cli_credentials *machine_credentials)
1652 {
1653         struct netr_AccountDeltas r;
1654         struct netlogon_creds_CredentialState *creds;
1655
1656         struct netr_AccountBuffer buffer;
1657         uint32_t count_returned = 0;
1658         uint32_t total_entries = 0;
1659         struct netr_UAS_INFO_0 recordid;
1660         struct netr_Authenticator return_authenticator;
1661         struct dcerpc_binding_handle *b = p->binding_handle;
1662
1663         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1664                 return false;
1665         }
1666
1667         ZERO_STRUCT(return_authenticator);
1668
1669         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1670         r.in.computername = TEST_MACHINE_NAME;
1671         r.in.return_authenticator = &return_authenticator;
1672         netlogon_creds_client_authenticator(creds, &r.in.credential);
1673         ZERO_STRUCT(r.in.uas);
1674         r.in.count=10;
1675         r.in.level=0;
1676         r.in.buffersize=100;
1677         r.out.buffer = &buffer;
1678         r.out.count_returned = &count_returned;
1679         r.out.total_entries = &total_entries;
1680         r.out.recordid = &recordid;
1681         r.out.return_authenticator = &return_authenticator;
1682
1683         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1684         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountDeltas_r(b, tctx, &r),
1685                 "AccountDeltas failed");
1686         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountDeltas");
1687
1688         return true;
1689 }
1690
1691 /*
1692   try a netlogon AccountSync
1693 */
1694 static bool test_AccountSync(struct torture_context *tctx, struct dcerpc_pipe *p, 
1695                              struct cli_credentials *machine_credentials)
1696 {
1697         struct netr_AccountSync r;
1698         struct netlogon_creds_CredentialState *creds;
1699
1700         struct netr_AccountBuffer buffer;
1701         uint32_t count_returned = 0;
1702         uint32_t total_entries = 0;
1703         uint32_t next_reference = 0;
1704         struct netr_UAS_INFO_0 recordid;
1705         struct netr_Authenticator return_authenticator;
1706         struct dcerpc_binding_handle *b = p->binding_handle;
1707
1708         ZERO_STRUCT(recordid);
1709         ZERO_STRUCT(return_authenticator);
1710
1711         if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
1712                 return false;
1713         }
1714
1715         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1716         r.in.computername = TEST_MACHINE_NAME;
1717         r.in.return_authenticator = &return_authenticator;
1718         netlogon_creds_client_authenticator(creds, &r.in.credential);
1719         r.in.recordid = &recordid;
1720         r.in.reference=0;
1721         r.in.level=0;
1722         r.in.buffersize=100;
1723         r.out.buffer = &buffer;
1724         r.out.count_returned = &count_returned;
1725         r.out.total_entries = &total_entries;
1726         r.out.next_reference = &next_reference;
1727         r.out.recordid = &recordid;
1728         r.out.return_authenticator = &return_authenticator;
1729
1730         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1731         torture_assert_ntstatus_ok(tctx, dcerpc_netr_AccountSync_r(b, tctx, &r),
1732                 "AccountSync failed");
1733         torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_NOT_IMPLEMENTED, "AccountSync");
1734
1735         return true;
1736 }
1737
1738 /*
1739   try a netlogon GetDcName
1740 */
1741 static bool test_GetDcName(struct torture_context *tctx, 
1742                            struct dcerpc_pipe *p)
1743 {
1744         struct netr_GetDcName r;
1745         const char *dcname = NULL;
1746         struct dcerpc_binding_handle *b = p->binding_handle;
1747
1748         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1749         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1750         r.out.dcname = &dcname;
1751
1752         torture_assert_ntstatus_ok(tctx, dcerpc_netr_GetDcName_r(b, tctx, &r),
1753                 "GetDcName failed");
1754         torture_assert_werr_ok(tctx, r.out.result, "GetDcName failed");
1755
1756         torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1757
1758         return true;
1759 }
1760
1761 static const char *function_code_str(TALLOC_CTX *mem_ctx,
1762                                      enum netr_LogonControlCode function_code)
1763 {
1764         switch (function_code) {
1765         case NETLOGON_CONTROL_QUERY:
1766                 return "NETLOGON_CONTROL_QUERY";
1767         case NETLOGON_CONTROL_REPLICATE:
1768                 return "NETLOGON_CONTROL_REPLICATE";
1769         case NETLOGON_CONTROL_SYNCHRONIZE:
1770                 return "NETLOGON_CONTROL_SYNCHRONIZE";
1771         case NETLOGON_CONTROL_PDC_REPLICATE:
1772                 return "NETLOGON_CONTROL_PDC_REPLICATE";
1773         case NETLOGON_CONTROL_REDISCOVER:
1774                 return "NETLOGON_CONTROL_REDISCOVER";
1775         case NETLOGON_CONTROL_TC_QUERY:
1776                 return "NETLOGON_CONTROL_TC_QUERY";
1777         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1778                 return "NETLOGON_CONTROL_TRANSPORT_NOTIFY";
1779         case NETLOGON_CONTROL_FIND_USER:
1780                 return "NETLOGON_CONTROL_FIND_USER";
1781         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1782                 return "NETLOGON_CONTROL_CHANGE_PASSWORD";
1783         case NETLOGON_CONTROL_TC_VERIFY:
1784                 return "NETLOGON_CONTROL_TC_VERIFY";
1785         case NETLOGON_CONTROL_FORCE_DNS_REG:
1786                 return "NETLOGON_CONTROL_FORCE_DNS_REG";
1787         case NETLOGON_CONTROL_QUERY_DNS_REG:
1788                 return "NETLOGON_CONTROL_QUERY_DNS_REG";
1789         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1790                 return "NETLOGON_CONTROL_BACKUP_CHANGE_LOG";
1791         case NETLOGON_CONTROL_TRUNCATE_LOG:
1792                 return "NETLOGON_CONTROL_TRUNCATE_LOG";
1793         case NETLOGON_CONTROL_SET_DBFLAG:
1794                 return "NETLOGON_CONTROL_SET_DBFLAG";
1795         case NETLOGON_CONTROL_BREAKPOINT:
1796                 return "NETLOGON_CONTROL_BREAKPOINT";
1797         default:
1798                 return talloc_asprintf(mem_ctx, "unknown function code: %d",
1799                                        function_code);
1800         }
1801 }
1802
1803
1804 /*
1805   try a netlogon LogonControl 
1806 */
1807 static bool test_LogonControl(struct torture_context *tctx, 
1808                               struct dcerpc_pipe *p,
1809                               struct cli_credentials *machine_credentials)
1810
1811 {
1812         NTSTATUS status;
1813         struct netr_LogonControl r;
1814         union netr_CONTROL_QUERY_INFORMATION query;
1815         int i,f;
1816         enum netr_SchannelType secure_channel_type = SEC_CHAN_NULL;
1817         struct dcerpc_binding_handle *b = p->binding_handle;
1818
1819         uint32_t function_codes[] = {
1820                 NETLOGON_CONTROL_QUERY,
1821                 NETLOGON_CONTROL_REPLICATE,
1822                 NETLOGON_CONTROL_SYNCHRONIZE,
1823                 NETLOGON_CONTROL_PDC_REPLICATE,
1824                 NETLOGON_CONTROL_REDISCOVER,
1825                 NETLOGON_CONTROL_TC_QUERY,
1826                 NETLOGON_CONTROL_TRANSPORT_NOTIFY,
1827                 NETLOGON_CONTROL_FIND_USER,
1828                 NETLOGON_CONTROL_CHANGE_PASSWORD,
1829                 NETLOGON_CONTROL_TC_VERIFY,
1830                 NETLOGON_CONTROL_FORCE_DNS_REG,
1831                 NETLOGON_CONTROL_QUERY_DNS_REG,
1832                 NETLOGON_CONTROL_BACKUP_CHANGE_LOG,
1833                 NETLOGON_CONTROL_TRUNCATE_LOG,
1834                 NETLOGON_CONTROL_SET_DBFLAG,
1835                 NETLOGON_CONTROL_BREAKPOINT
1836         };
1837
1838         if (machine_credentials) {
1839                 secure_channel_type = cli_credentials_get_secure_channel_type(machine_credentials);
1840         }
1841
1842         torture_comment(tctx, "Testing LogonControl with secure channel type: %d\n",
1843                 secure_channel_type);
1844
1845         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1846         r.in.function_code = 1;
1847         r.out.query = &query;
1848
1849         for (f=0;f<ARRAY_SIZE(function_codes); f++) {
1850         for (i=1;i<5;i++) {
1851
1852                 r.in.function_code = function_codes[f];
1853                 r.in.level = i;
1854
1855                 torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1856                                 function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1857
1858                 status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1859                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1860
1861                 switch (r.in.level) {
1862                 case 1:
1863                         switch (r.in.function_code) {
1864                         case NETLOGON_CONTROL_REPLICATE:
1865                         case NETLOGON_CONTROL_SYNCHRONIZE:
1866                         case NETLOGON_CONTROL_PDC_REPLICATE:
1867                         case NETLOGON_CONTROL_BREAKPOINT:
1868                         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1869                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1870                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1871                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1872                                                 "LogonControl returned unexpected error code");
1873                                 } else {
1874                                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1875                                                 "LogonControl returned unexpected error code");
1876                                 }
1877                                 break;
1878
1879                         case NETLOGON_CONTROL_REDISCOVER:
1880                         case NETLOGON_CONTROL_TC_QUERY:
1881                         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
1882                         case NETLOGON_CONTROL_FIND_USER:
1883                         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1884                         case NETLOGON_CONTROL_TC_VERIFY:
1885                         case NETLOGON_CONTROL_FORCE_DNS_REG:
1886                         case NETLOGON_CONTROL_QUERY_DNS_REG:
1887                         case NETLOGON_CONTROL_SET_DBFLAG:
1888                                 torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1889                                         "LogonControl returned unexpected error code");
1890                                 break;
1891                         case NETLOGON_CONTROL_TRUNCATE_LOG:
1892                                 if ((secure_channel_type == SEC_CHAN_BDC) ||
1893                                     (secure_channel_type == SEC_CHAN_WKSTA)) {
1894                                         torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
1895                                                 "LogonControl returned unexpected error code");
1896                                 } else {
1897                                         torture_assert_werr_ok(tctx, r.out.result,
1898                                                 "LogonControl returned unexpected result");
1899                                 }
1900                                 break;
1901                         default:
1902                                 torture_assert_werr_ok(tctx, r.out.result,
1903                                         "LogonControl returned unexpected result");
1904                                 break;
1905                         }
1906                         break;
1907                 case 2:
1908                         torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
1909                                 "LogonControl returned unexpected error code");
1910                         break;
1911                 default:
1912                         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
1913                                 "LogonControl returned unexpected error code");
1914                         break;
1915                 }
1916         }
1917         }
1918
1919         r.in.level = 52;
1920         torture_comment(tctx, "Testing LogonControl function code %s (%d) level %d\n",
1921                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
1922         status = dcerpc_netr_LogonControl_r(b, tctx, &r);
1923         torture_assert_ntstatus_ok(tctx, status, "LogonControl");
1924         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_LEVEL, "LogonControl");
1925
1926         return true;
1927 }
1928
1929
1930 /*
1931   try a netlogon GetAnyDCName
1932 */
1933 static bool test_GetAnyDCName(struct torture_context *tctx, 
1934                               struct dcerpc_pipe *p)
1935 {
1936         NTSTATUS status;
1937         struct netr_GetAnyDCName r;
1938         const char *dcname = NULL;
1939         struct dcerpc_binding_handle *b = p->binding_handle;
1940
1941         r.in.domainname = lpcfg_workgroup(tctx->lp_ctx);
1942         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1943         r.out.dcname = &dcname;
1944
1945         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1946         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1947         if ((!W_ERROR_IS_OK(r.out.result)) &&
1948             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1949                 return false;
1950         }
1951
1952         if (dcname) {
1953             torture_comment(tctx, "\tDC is at '%s'\n", dcname);
1954         }
1955
1956         r.in.domainname = NULL;
1957
1958         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1959         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1960         if ((!W_ERROR_IS_OK(r.out.result)) &&
1961             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1962                 return false;
1963         }
1964
1965         r.in.domainname = "";
1966
1967         status = dcerpc_netr_GetAnyDCName_r(b, tctx, &r);
1968         torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
1969         if ((!W_ERROR_IS_OK(r.out.result)) &&
1970             (!W_ERROR_EQUAL(r.out.result, WERR_NO_SUCH_DOMAIN))) {
1971                 return false;
1972         }
1973
1974         return true;
1975 }
1976
1977
1978 /*
1979   try a netlogon LogonControl2
1980 */
1981 static bool test_LogonControl2(struct torture_context *tctx, 
1982                                struct dcerpc_pipe *p,
1983                                struct cli_credentials *machine_credentials)
1984
1985 {
1986         NTSTATUS status;
1987         struct netr_LogonControl2 r;
1988         union netr_CONTROL_DATA_INFORMATION data;
1989         union netr_CONTROL_QUERY_INFORMATION query;
1990         int i;
1991         struct dcerpc_binding_handle *b = p->binding_handle;
1992
1993         data.domain = lpcfg_workgroup(tctx->lp_ctx);
1994
1995         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
1996
1997         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
1998         r.in.data = &data;
1999         r.out.query = &query;
2000
2001         for (i=1;i<4;i++) {
2002                 r.in.level = i;
2003
2004                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2005                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2006
2007                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2008                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2009         }
2010
2011         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2012
2013         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2014         r.in.data = &data;
2015
2016         for (i=1;i<4;i++) {
2017                 r.in.level = i;
2018
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         }
2025
2026         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2027
2028         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2029         r.in.data = &data;
2030
2031         for (i=1;i<4;i++) {
2032                 r.in.level = i;
2033
2034                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2035                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2036
2037                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2038                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2039         }
2040
2041         data.debug_level = ~0;
2042
2043         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2044         r.in.data = &data;
2045
2046         for (i=1;i<4;i++) {
2047                 r.in.level = i;
2048
2049                 torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2050                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2051
2052                 status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2053                 torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2054         }
2055
2056         ZERO_STRUCT(data);
2057         r.in.function_code = 52;
2058         r.in.data = &data;
2059
2060         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2061                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2062
2063         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2064         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2065         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2066
2067         data.debug_level = ~0;
2068
2069         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2070         r.in.data = &data;
2071
2072         r.in.level = 52;
2073         torture_comment(tctx, "Testing LogonControl2 function code %s (%d) level %d\n",
2074                         function_code_str(tctx, r.in.function_code), r.in.function_code, r.in.level);
2075
2076         status = dcerpc_netr_LogonControl2_r(b, tctx, &r);
2077         torture_assert_ntstatus_ok(tctx, status, "LogonControl2");
2078         torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "LogonControl2");
2079
2080         return true;
2081 }
2082
2083 /*
2084   try a netlogon DatabaseSync2
2085 */
2086 static bool test_DatabaseSync2(struct torture_context *tctx, 
2087                                struct dcerpc_pipe *p,
2088                                struct cli_credentials *machine_credentials)
2089 {
2090         struct netr_DatabaseSync2 r;
2091         struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
2092         struct netr_Authenticator return_authenticator, credential;
2093
2094         struct netlogon_creds_CredentialState *creds;
2095         const uint32_t database_ids[] = {0, 1, 2}; 
2096         int i;
2097         struct dcerpc_binding_handle *b = p->binding_handle;
2098
2099         if (!test_SetupCredentials2(p, tctx, NETLOGON_NEG_AUTH2_FLAGS, 
2100                                     machine_credentials,
2101                                     cli_credentials_get_secure_channel_type(machine_credentials),
2102                                     &creds)) {
2103                 return false;
2104         }
2105
2106         ZERO_STRUCT(return_authenticator);
2107
2108         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2109         r.in.computername = TEST_MACHINE_NAME;
2110         r.in.preferredmaximumlength = (uint32_t)-1;
2111         r.in.return_authenticator = &return_authenticator;
2112         r.out.return_authenticator = &return_authenticator;
2113         r.out.delta_enum_array = &delta_enum_array;
2114
2115         for (i=0;i<ARRAY_SIZE(database_ids);i++) {
2116
2117                 uint32_t sync_context = 0;
2118
2119                 r.in.database_id = database_ids[i];
2120                 r.in.sync_context = &sync_context;
2121                 r.out.sync_context = &sync_context;
2122                 r.in.restart_state = 0;
2123
2124                 torture_comment(tctx, "Testing DatabaseSync2 of id %d\n", r.in.database_id);
2125
2126                 do {
2127                         netlogon_creds_client_authenticator(creds, &credential);
2128
2129                         r.in.credential = &credential;
2130
2131                         torture_assert_ntstatus_ok(tctx, dcerpc_netr_DatabaseSync2_r(b, tctx, &r),
2132                                 "DatabaseSync2 failed");
2133                         if (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES))
2134                             break;
2135
2136                         /* Native mode servers don't do this */
2137                         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_SUPPORTED)) {
2138                                 return true;
2139                         }
2140
2141                         torture_assert_ntstatus_ok(tctx, r.out.result, "DatabaseSync2");
2142
2143                         if (!netlogon_creds_client_check(creds, &r.out.return_authenticator->cred)) {
2144                                 torture_comment(tctx, "Credential chaining failed\n");
2145                         }
2146
2147                 } while (NT_STATUS_EQUAL(r.out.result, STATUS_MORE_ENTRIES));
2148         }
2149
2150         return true;
2151 }
2152
2153
2154 /*
2155   try a netlogon LogonControl2Ex
2156 */
2157 static bool test_LogonControl2Ex(struct torture_context *tctx, 
2158                                  struct dcerpc_pipe *p,
2159                                  struct cli_credentials *machine_credentials)
2160
2161 {
2162         NTSTATUS status;
2163         struct netr_LogonControl2Ex r;
2164         union netr_CONTROL_DATA_INFORMATION data;
2165         union netr_CONTROL_QUERY_INFORMATION query;
2166         int i;
2167         struct dcerpc_binding_handle *b = p->binding_handle;
2168
2169         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2170
2171         r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2172
2173         r.in.function_code = NETLOGON_CONTROL_REDISCOVER;
2174         r.in.data = &data;
2175         r.out.query = &query;
2176
2177         for (i=1;i<4;i++) {
2178                 r.in.level = i;
2179
2180                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2181                        i, r.in.function_code);
2182
2183                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2184                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2185         }
2186
2187         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2188
2189         r.in.function_code = NETLOGON_CONTROL_TC_QUERY;
2190         r.in.data = &data;
2191
2192         for (i=1;i<4;i++) {
2193                 r.in.level = i;
2194
2195                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2196                        i, r.in.function_code);
2197
2198                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2199                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2200         }
2201
2202         data.domain = lpcfg_workgroup(tctx->lp_ctx);
2203
2204         r.in.function_code = NETLOGON_CONTROL_TRANSPORT_NOTIFY;
2205         r.in.data = &data;
2206
2207         for (i=1;i<4;i++) {
2208                 r.in.level = i;
2209
2210                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2211                        i, r.in.function_code);
2212
2213                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2214                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2215         }
2216
2217         data.debug_level = ~0;
2218
2219         r.in.function_code = NETLOGON_CONTROL_SET_DBFLAG;
2220         r.in.data = &data;
2221
2222         for (i=1;i<4;i++) {
2223                 r.in.level = i;
2224
2225                 torture_comment(tctx, "Testing LogonControl2Ex level %d function %d\n", 
2226                        i, r.in.function_code);
2227
2228                 status = dcerpc_netr_LogonControl2Ex_r(b, tctx, &r);
2229                 torture_assert_ntstatus_ok(tctx, status, "LogonControl");
2230         }
2231
2232         return true;
2233 }
2234
2235 static bool test_netr_GetForestTrustInformation(struct torture_context *tctx,
2236                                                 struct dcerpc_pipe *p,
2237                                                 struct cli_credentials *machine_credentials)
2238 {
2239         struct netr_GetForestTrustInformation r;
2240         struct netlogon_creds_CredentialState *creds;
2241         struct netr_Authenticator a;
2242         struct netr_Authenticator return_authenticator;
2243         struct lsa_ForestTrustInformation *forest_trust_info;
2244         struct dcerpc_binding_handle *b = p->binding_handle;
2245
2246         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
2247                                     machine_credentials, &creds)) {
2248                 return false;
2249         }
2250
2251         netlogon_creds_client_authenticator(creds, &a);
2252
2253         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2254         r.in.computer_name = TEST_MACHINE_NAME;
2255         r.in.credential = &a;
2256         r.in.flags = 0;
2257         r.out.return_authenticator = &return_authenticator;
2258         r.out.forest_trust_info = &forest_trust_info;
2259
2260         torture_assert_ntstatus_ok(tctx,
2261                 dcerpc_netr_GetForestTrustInformation_r(b, tctx, &r),
2262                 "netr_GetForestTrustInformation failed");
2263         if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_NOT_IMPLEMENTED)) {
2264                 torture_comment(tctx, "not considering NT_STATUS_NOT_IMPLEMENTED as an error\n");
2265         } else {
2266                 torture_assert_ntstatus_ok(tctx, r.out.result,
2267                         "netr_GetForestTrustInformation failed");
2268         }
2269
2270         torture_assert(tctx,
2271                 netlogon_creds_client_check(creds, &return_authenticator.cred),
2272                 "Credential chaining failed");
2273
2274         return true;
2275 }
2276
2277 static bool test_netr_DsRGetForestTrustInformation(struct torture_context *tctx, 
2278                                                    struct dcerpc_pipe *p, const char *trusted_domain_name) 
2279 {
2280         NTSTATUS status;
2281         struct netr_DsRGetForestTrustInformation r;
2282         struct lsa_ForestTrustInformation info, *info_ptr;
2283         struct dcerpc_binding_handle *b = p->binding_handle;
2284
2285         info_ptr = &info;
2286
2287         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2288         r.in.trusted_domain_name = trusted_domain_name;
2289         r.in.flags = 0;
2290         r.out.forest_trust_info = &info_ptr;
2291
2292         torture_comment(tctx ,"Testing netr_DsRGetForestTrustInformation\n");
2293
2294         status = dcerpc_netr_DsRGetForestTrustInformation_r(b, tctx, &r);
2295         torture_assert_ntstatus_ok(tctx, status, "DsRGetForestTrustInformation");
2296         torture_assert_werr_ok(tctx, r.out.result, "DsRGetForestTrustInformation");
2297
2298         return true;
2299 }
2300
2301 /*
2302   try a netlogon netr_DsrEnumerateDomainTrusts
2303 */
2304 static bool test_DsrEnumerateDomainTrusts(struct torture_context *tctx, 
2305                                           struct dcerpc_pipe *p)
2306 {
2307         NTSTATUS status;
2308         struct netr_DsrEnumerateDomainTrusts r;
2309         struct netr_DomainTrustList trusts;
2310         int i;
2311         struct dcerpc_binding_handle *b = p->binding_handle;
2312
2313         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2314         r.in.trust_flags = 0x3f;
2315         r.out.trusts = &trusts;
2316
2317         status = dcerpc_netr_DsrEnumerateDomainTrusts_r(b, tctx, &r);
2318         torture_assert_ntstatus_ok(tctx, status, "DsrEnumerateDomaintrusts");
2319         torture_assert_werr_ok(tctx, r.out.result, "DsrEnumerateDomaintrusts");
2320
2321         /* when trusted_domain_name is NULL, netr_DsRGetForestTrustInformation
2322          * will show non-forest trusts and all UPN suffixes of the own forest
2323          * as LSA_FOREST_TRUST_TOP_LEVEL_NAME types */
2324
2325         if (r.out.trusts->count) {
2326                 if (!test_netr_DsRGetForestTrustInformation(tctx, p, NULL)) {
2327                         return false;
2328                 }
2329         }
2330
2331         for (i=0; i<r.out.trusts->count; i++) {
2332
2333                 /* get info for transitive forest trusts */
2334
2335                 if (r.out.trusts->array[i].trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2336                         if (!test_netr_DsRGetForestTrustInformation(tctx, p, 
2337                                                                     r.out.trusts->array[i].dns_name)) {
2338                                 return false;
2339                         }
2340                 }
2341         }
2342
2343         return true;
2344 }
2345
2346 static bool test_netr_NetrEnumerateTrustedDomains(struct torture_context *tctx,
2347                                                   struct dcerpc_pipe *p)
2348 {
2349         NTSTATUS status;
2350         struct netr_NetrEnumerateTrustedDomains r;
2351         struct netr_Blob trusted_domains_blob;
2352         struct dcerpc_binding_handle *b = p->binding_handle;
2353
2354         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2355         r.out.trusted_domains_blob = &trusted_domains_blob;
2356
2357         status = dcerpc_netr_NetrEnumerateTrustedDomains_r(b, tctx, &r);
2358         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomains");
2359         torture_assert_ntstatus_ok(tctx, r.out.result, "NetrEnumerateTrustedDomains");
2360
2361         return true;
2362 }
2363
2364 static bool test_netr_NetrEnumerateTrustedDomainsEx(struct torture_context *tctx,
2365                                                     struct dcerpc_pipe *p)
2366 {
2367         NTSTATUS status;
2368         struct netr_NetrEnumerateTrustedDomainsEx r;
2369         struct netr_DomainTrustList dom_trust_list;
2370         struct dcerpc_binding_handle *b = p->binding_handle;
2371
2372         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2373         r.out.dom_trust_list = &dom_trust_list;
2374
2375         status = dcerpc_netr_NetrEnumerateTrustedDomainsEx_r(b, tctx, &r);
2376         torture_assert_ntstatus_ok(tctx, status, "netr_NetrEnumerateTrustedDomainsEx");
2377         torture_assert_werr_ok(tctx, r.out.result, "NetrEnumerateTrustedDomainsEx");
2378
2379         return true;
2380 }
2381
2382
2383 static bool test_netr_DsRGetSiteName(struct dcerpc_pipe *p, struct torture_context *tctx,
2384                                      const char *computer_name, 
2385                                      const char *expected_site) 
2386 {
2387         NTSTATUS status;
2388         struct netr_DsRGetSiteName r;
2389         const char *site = NULL;
2390         struct dcerpc_binding_handle *b = p->binding_handle;
2391
2392         r.in.computer_name              = computer_name;
2393         r.out.site                      = &site;
2394         torture_comment(tctx, "Testing netr_DsRGetSiteName\n");
2395
2396         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2397         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2398         torture_assert_werr_ok(tctx, r.out.result, "DsRGetSiteName");
2399         torture_assert_str_equal(tctx, expected_site, site, "netr_DsRGetSiteName");
2400
2401         if (torture_setting_bool(tctx, "samba4", false))
2402                 torture_skip(tctx, "skipping computer name check against Samba4");
2403
2404         r.in.computer_name              = talloc_asprintf(tctx, "\\\\%s", computer_name);
2405         torture_comment(tctx, 
2406                         "Testing netr_DsRGetSiteName with broken computer name: %s\n", r.in.computer_name);
2407
2408         status = dcerpc_netr_DsRGetSiteName_r(b, tctx, &r);
2409         torture_assert_ntstatus_ok(tctx, status, "DsRGetSiteName");
2410         torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_COMPUTERNAME, "netr_DsRGetSiteName");
2411
2412         return true;
2413 }
2414
2415 /*
2416   try a netlogon netr_DsRGetDCName
2417 */
2418 static bool test_netr_DsRGetDCName(struct torture_context *tctx, 
2419                                    struct dcerpc_pipe *p)
2420 {
2421         NTSTATUS status;
2422         struct netr_DsRGetDCName r;
2423         struct netr_DsRGetDCNameInfo *info = NULL;
2424         struct dcerpc_binding_handle *b = p->binding_handle;
2425
2426         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2427         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2428         r.in.domain_guid        = NULL;
2429         r.in.site_guid          = NULL;
2430         r.in.flags              = DS_RETURN_DNS_NAME;
2431         r.out.info              = &info;
2432
2433         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2434         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2435         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2436
2437         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2438
2439         status = dcerpc_netr_DsRGetDCName_r(b, tctx, &r);
2440         torture_assert_ntstatus_ok(tctx, status, "DsRGetDCName");
2441         torture_assert_werr_ok(tctx, r.out.result, "DsRGetDCName");
2442
2443         return test_netr_DsRGetSiteName(p, tctx, 
2444                                        info->dc_unc,
2445                                        info->dc_site_name);
2446 }
2447
2448 /*
2449   try a netlogon netr_DsRGetDCNameEx
2450 */
2451 static bool test_netr_DsRGetDCNameEx(struct torture_context *tctx, 
2452                                      struct dcerpc_pipe *p)
2453 {
2454         NTSTATUS status;
2455         struct netr_DsRGetDCNameEx r;
2456         struct netr_DsRGetDCNameInfo *info = NULL;
2457         struct dcerpc_binding_handle *b = p->binding_handle;
2458
2459         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2460         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2461         r.in.domain_guid        = NULL;
2462         r.in.site_name          = NULL;
2463         r.in.flags              = DS_RETURN_DNS_NAME;
2464         r.out.info              = &info;
2465
2466         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2467         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2468         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2469
2470         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2471
2472         status = dcerpc_netr_DsRGetDCNameEx_r(b, tctx, &r);
2473         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx");
2474         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx");
2475
2476         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2477                                         info->dc_site_name);
2478 }
2479
2480 /*
2481   try a netlogon netr_DsRGetDCNameEx2
2482 */
2483 static bool test_netr_DsRGetDCNameEx2(struct torture_context *tctx, 
2484                                       struct dcerpc_pipe *p)
2485 {
2486         NTSTATUS status;
2487         struct netr_DsRGetDCNameEx2 r;
2488         struct netr_DsRGetDCNameInfo *info = NULL;
2489         struct dcerpc_binding_handle *b = p->binding_handle;
2490
2491         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with no inputs\n");
2492         ZERO_STRUCT(r.in);
2493         r.in.flags              = DS_RETURN_DNS_NAME;
2494         r.out.info              = &info;
2495
2496         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2497         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2498         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2499
2500         r.in.server_unc         = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2501         r.in.client_account     = NULL;
2502         r.in.mask               = 0x00000000;
2503         r.in.domain_name        = lpcfg_dnsdomain(tctx->lp_ctx);
2504         r.in.domain_guid        = NULL;
2505         r.in.site_name          = NULL;
2506         r.in.flags              = DS_RETURN_DNS_NAME;
2507         r.out.info              = &info;
2508
2509         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 without client account\n");
2510
2511         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2512         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2513         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2514
2515         r.in.domain_name        = lpcfg_workgroup(tctx->lp_ctx);
2516
2517         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2518         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2519         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2520
2521         torture_comment(tctx, "Testing netr_DsRGetDCNameEx2 with client account\n");
2522         r.in.client_account     = TEST_MACHINE_NAME"$";
2523         r.in.mask               = ACB_SVRTRUST;
2524         r.in.flags              = DS_RETURN_FLAT_NAME;
2525         r.out.info              = &info;
2526
2527         status = dcerpc_netr_DsRGetDCNameEx2_r(b, tctx, &r);
2528         torture_assert_ntstatus_ok(tctx, status, "netr_DsRGetDCNameEx2");
2529         torture_assert_werr_ok(tctx, r.out.result, "netr_DsRGetDCNameEx2");
2530
2531         return test_netr_DsRGetSiteName(p, tctx, info->dc_unc,
2532                                         info->dc_site_name);
2533 }
2534
2535 /* This is a substitution for "samdb_server_site_name" which relies on the
2536  * correct "lp_ctx" and therefore can't be used here. */
2537 static const char *server_site_name(struct torture_context *tctx,
2538                                     struct ldb_context *ldb)
2539 {
2540         TALLOC_CTX *tmp_ctx;
2541         struct ldb_dn *dn, *server_dn;
2542         const struct ldb_val *site_name_val;
2543         const char *server_dn_str, *site_name;
2544
2545         tmp_ctx = talloc_new(ldb);
2546         if (tmp_ctx == NULL) {
2547                 goto failed;
2548         }
2549
2550         dn = ldb_dn_new(tmp_ctx, ldb, "");
2551         if (dn == NULL) {
2552                 goto failed;
2553         }
2554
2555         server_dn_str = samdb_search_string(ldb, tmp_ctx, dn, "serverName",
2556                                             NULL);
2557         if (server_dn_str == NULL) {
2558                 goto failed;
2559         }
2560
2561         server_dn = ldb_dn_new(tmp_ctx, ldb, server_dn_str);
2562         if (server_dn == NULL) {
2563                 goto failed;
2564         }
2565
2566         /* CN=<Server name>, CN=Servers, CN=<Site name>, CN=Sites, ... */
2567         site_name_val = ldb_dn_get_component_val(server_dn, 2);
2568         if (site_name_val == NULL) {
2569                 goto failed;
2570         }
2571
2572         site_name = (const char *) site_name_val->data;
2573
2574         talloc_steal(tctx, site_name);
2575         talloc_free(tmp_ctx);
2576
2577         return site_name;
2578
2579 failed:
2580         talloc_free(tmp_ctx);
2581         return NULL;
2582 }
2583
2584 static bool test_netr_DsrGetDcSiteCoverageW(struct torture_context *tctx, 
2585                                             struct dcerpc_pipe *p)
2586 {
2587         char *url;
2588         struct ldb_context *sam_ctx = NULL;
2589         NTSTATUS status;
2590         struct netr_DsrGetDcSiteCoverageW r;
2591         struct DcSitesCtr *ctr = NULL;
2592         struct dcerpc_binding_handle *b = p->binding_handle;
2593
2594         torture_comment(tctx, "This does only pass with the default site\n");
2595
2596         /* We won't double-check this when we are over 'local' transports */
2597         if (dcerpc_server_name(p)) {
2598                 /* Set up connection to SAMDB on DC */
2599                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2600                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2601                                            NULL,
2602                                            cmdline_credentials,
2603                                            0);
2604
2605                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2606         }
2607
2608         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2609         r.out.ctr = &ctr;
2610
2611         status = dcerpc_netr_DsrGetDcSiteCoverageW_r(b, tctx, &r);
2612         torture_assert_ntstatus_ok(tctx, status, "failed");
2613         torture_assert_werr_ok(tctx, r.out.result, "failed");
2614
2615         torture_assert(tctx, ctr->num_sites == 1,
2616                        "we should per default only get the default site");
2617         if (sam_ctx != NULL) {
2618                 torture_assert_casestr_equal(tctx, ctr->sites[0].string,
2619                                              server_site_name(tctx, sam_ctx),
2620                                              "didn't return default site");
2621         }
2622
2623         return true;
2624 }
2625
2626 static bool test_netr_DsRAddressToSitenamesW(struct torture_context *tctx,
2627                                              struct dcerpc_pipe *p)
2628 {
2629         char *url;
2630         struct ldb_context *sam_ctx = NULL;
2631         NTSTATUS status;
2632         struct netr_DsRAddressToSitenamesW r;
2633         struct netr_DsRAddress addrs[6];
2634         struct sockaddr_in *addr;
2635 #ifdef HAVE_IPV6
2636         struct sockaddr_in6 *addr6;
2637 #endif
2638         struct netr_DsRAddressToSitenamesWCtr *ctr;
2639         struct dcerpc_binding_handle *b = p->binding_handle;
2640         uint32_t i;
2641         int ret;
2642
2643         torture_comment(tctx, "This does only pass with the default site\n");
2644
2645         /* We won't double-check this when we are over 'local' transports */
2646         if (dcerpc_server_name(p)) {
2647                 /* Set up connection to SAMDB on DC */
2648                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2649                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2650                                            NULL,
2651                                            cmdline_credentials,
2652                                            0);
2653
2654                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2655         }
2656
2657         /* First try valid IP addresses */
2658
2659         addrs[0].size = sizeof(struct sockaddr_in);
2660         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2661         addr = (struct sockaddr_in *) addrs[0].buffer;
2662         addrs[0].buffer[0] = AF_INET;
2663         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2664         torture_assert(tctx, ret > 0, "inet_pton failed");
2665
2666         addrs[1].size = sizeof(struct sockaddr_in);
2667         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2668         addr = (struct sockaddr_in *) addrs[1].buffer;
2669         addrs[1].buffer[0] = AF_INET;
2670         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2671         torture_assert(tctx, ret > 0, "inet_pton failed");
2672
2673         addrs[2].size = sizeof(struct sockaddr_in);
2674         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2675         addr = (struct sockaddr_in *) addrs[2].buffer;
2676         addrs[2].buffer[0] = AF_INET;
2677         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2678         torture_assert(tctx, ret > 0, "inet_pton failed");
2679
2680 #ifdef HAVE_IPV6
2681         addrs[3].size = sizeof(struct sockaddr_in6);
2682         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2683         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2684         addrs[3].buffer[0] = AF_INET6;
2685         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2686         torture_assert(tctx, ret > 0, "inet_pton failed");
2687
2688         addrs[4].size = sizeof(struct sockaddr_in6);
2689         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2690         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2691         addrs[4].buffer[0] = AF_INET6;
2692         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2693         torture_assert(tctx, ret > 0, "inet_pton failed");
2694
2695         addrs[5].size = sizeof(struct sockaddr_in6);
2696         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2697         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2698         addrs[5].buffer[0] = AF_INET6;
2699         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2700         torture_assert(tctx, ret > 0, "inet_pton failed");
2701 #else
2702         /* the test cases are repeated to have exactly 6. This is for
2703          * compatibility with IPv4-only machines */
2704         addrs[3].size = sizeof(struct sockaddr_in);
2705         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2706         addr = (struct sockaddr_in *) addrs[3].buffer;
2707         addrs[3].buffer[0] = AF_INET;
2708         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2709         torture_assert(tctx, ret > 0, "inet_pton failed");
2710
2711         addrs[4].size = sizeof(struct sockaddr_in);
2712         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2713         addr = (struct sockaddr_in *) addrs[4].buffer;
2714         addrs[4].buffer[0] = AF_INET;
2715         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2716         torture_assert(tctx, ret > 0, "inet_pton failed");
2717
2718         addrs[5].size = sizeof(struct sockaddr_in);
2719         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2720         addr = (struct sockaddr_in *) addrs[5].buffer;
2721         addrs[5].buffer[0] = AF_INET;
2722         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2723         torture_assert(tctx, ret > 0, "inet_pton failed");
2724 #endif
2725
2726         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesWCtr);
2727
2728         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2729         r.in.count = 6;
2730         r.in.addresses = addrs;
2731         r.out.ctr = &ctr;
2732
2733         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2734         torture_assert_ntstatus_ok(tctx, status, "failed");
2735         torture_assert_werr_ok(tctx, r.out.result, "failed");
2736
2737         if (sam_ctx != NULL) {
2738                 for (i = 0; i < 3; i++) {
2739                         torture_assert_casestr_equal(tctx,
2740                                                      ctr->sitename[i].string,
2741                                                      server_site_name(tctx, sam_ctx),
2742                                                      "didn't return default site");
2743                 }
2744                 for (i = 3; i < 6; i++) {
2745                         /* Windows returns "NULL" for the sitename if it isn't
2746                          * IPv6 configured */
2747                         if (torture_setting_bool(tctx, "samba4", false)) {
2748                                 torture_assert_casestr_equal(tctx,
2749                                                              ctr->sitename[i].string,
2750                                                              server_site_name(tctx, sam_ctx),
2751                                                              "didn't return default site");
2752                         }
2753                 }
2754         }
2755
2756         /* Now try invalid ones (too short buffers) */
2757
2758         addrs[0].size = 0;
2759         addrs[1].size = 1;
2760         addrs[2].size = 4;
2761
2762         addrs[3].size = 0;
2763         addrs[4].size = 1;
2764         addrs[5].size = 4;
2765
2766         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2767         torture_assert_ntstatus_ok(tctx, status, "failed");
2768         torture_assert_werr_ok(tctx, r.out.result, "failed");
2769
2770         for (i = 0; i < 6; i++) {
2771                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2772                                "sitename should be null");
2773         }
2774
2775         /* Now try invalid ones (wrong address types) */
2776
2777         addrs[0].size = 10;
2778         addrs[0].buffer[0] = AF_UNSPEC;
2779         addrs[1].size = 10;
2780         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2781         addrs[2].size = 10;
2782         addrs[2].buffer[0] = AF_UNIX;
2783
2784         addrs[3].size = 10;
2785         addrs[3].buffer[0] = 250;
2786         addrs[4].size = 10;
2787         addrs[4].buffer[0] = 251;
2788         addrs[5].size = 10;
2789         addrs[5].buffer[0] = 252;
2790
2791         status = dcerpc_netr_DsRAddressToSitenamesW_r(b, tctx, &r);
2792         torture_assert_ntstatus_ok(tctx, status, "failed");
2793         torture_assert_werr_ok(tctx, r.out.result, "failed");
2794
2795         for (i = 0; i < 6; i++) {
2796                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2797                                "sitename should be null");
2798         }
2799
2800         return true;
2801 }
2802
2803 static bool test_netr_DsRAddressToSitenamesExW(struct torture_context *tctx,
2804                                                struct dcerpc_pipe *p)
2805 {
2806         char *url;
2807         struct ldb_context *sam_ctx = NULL;
2808         NTSTATUS status;
2809         struct netr_DsRAddressToSitenamesExW r;
2810         struct netr_DsRAddress addrs[6];
2811         struct sockaddr_in *addr;
2812 #ifdef HAVE_IPV6
2813         struct sockaddr_in6 *addr6;
2814 #endif
2815         struct netr_DsRAddressToSitenamesExWCtr *ctr;
2816         struct dcerpc_binding_handle *b = p->binding_handle;
2817         uint32_t i;
2818         int ret;
2819
2820         torture_comment(tctx, "This does pass with the default site\n");
2821
2822         /* We won't double-check this when we are over 'local' transports */
2823         if (dcerpc_server_name(p)) {
2824                 /* Set up connection to SAMDB on DC */
2825                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
2826                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
2827                                            NULL,
2828                                            cmdline_credentials,
2829                                            0);
2830
2831                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
2832         }
2833
2834         /* First try valid IP addresses */
2835
2836         addrs[0].size = sizeof(struct sockaddr_in);
2837         addrs[0].buffer = talloc_zero_array(tctx, uint8_t, addrs[0].size);
2838         addr = (struct sockaddr_in *) addrs[0].buffer;
2839         addrs[0].buffer[0] = AF_INET;
2840         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2841         torture_assert(tctx, ret > 0, "inet_pton failed");
2842
2843         addrs[1].size = sizeof(struct sockaddr_in);
2844         addrs[1].buffer = talloc_zero_array(tctx, uint8_t, addrs[1].size);
2845         addr = (struct sockaddr_in *) addrs[1].buffer;
2846         addrs[1].buffer[0] = AF_INET;
2847         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2848         torture_assert(tctx, ret > 0, "inet_pton failed");
2849
2850         addrs[2].size = sizeof(struct sockaddr_in);
2851         addrs[2].buffer = talloc_zero_array(tctx, uint8_t, addrs[2].size);
2852         addr = (struct sockaddr_in *) addrs[2].buffer;
2853         addrs[2].buffer[0] = AF_INET;
2854         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2855         torture_assert(tctx, ret > 0, "inet_pton failed");
2856
2857 #ifdef HAVE_IPV6
2858         addrs[3].size = sizeof(struct sockaddr_in6);
2859         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2860         addr6 = (struct sockaddr_in6 *) addrs[3].buffer;
2861         addrs[3].buffer[0] = AF_INET6;
2862         ret = inet_pton(AF_INET6, "::1", &addr6->sin6_addr);
2863         torture_assert(tctx, ret > 0, "inet_pton failed");
2864
2865         addrs[4].size = sizeof(struct sockaddr_in6);
2866         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2867         addr6 = (struct sockaddr_in6 *) addrs[4].buffer;
2868         addrs[4].buffer[0] = AF_INET6;
2869         ret = inet_pton(AF_INET6, "::", &addr6->sin6_addr);
2870         torture_assert(tctx, ret > 0, "inet_pton failed");
2871
2872         addrs[5].size = sizeof(struct sockaddr_in6);
2873         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2874         addr6 = (struct sockaddr_in6 *) addrs[5].buffer;
2875         addrs[5].buffer[0] = AF_INET6;
2876         ret = inet_pton(AF_INET6, "ff02::1", &addr6->sin6_addr);
2877         torture_assert(tctx, ret > 0, "inet_pton failed");
2878 #else
2879         /* the test cases are repeated to have exactly 6. This is for
2880          * compatibility with IPv4-only machines */
2881         addrs[3].size = sizeof(struct sockaddr_in);
2882         addrs[3].buffer = talloc_zero_array(tctx, uint8_t, addrs[3].size);
2883         addr = (struct sockaddr_in *) addrs[3].buffer;
2884         addrs[3].buffer[0] = AF_INET;
2885         ret = inet_pton(AF_INET, "127.0.0.1", &addr->sin_addr);
2886         torture_assert(tctx, ret > 0, "inet_pton failed");
2887
2888         addrs[4].size = sizeof(struct sockaddr_in);
2889         addrs[4].buffer = talloc_zero_array(tctx, uint8_t, addrs[4].size);
2890         addr = (struct sockaddr_in *) addrs[4].buffer;
2891         addrs[4].buffer[0] = AF_INET;
2892         ret = inet_pton(AF_INET, "0.0.0.0", &addr->sin_addr);
2893         torture_assert(tctx, ret > 0, "inet_pton failed");
2894
2895         addrs[5].size = sizeof(struct sockaddr_in);
2896         addrs[5].buffer = talloc_zero_array(tctx, uint8_t, addrs[5].size);
2897         addr = (struct sockaddr_in *) addrs[5].buffer;
2898         addrs[5].buffer[0] = AF_INET;
2899         ret = inet_pton(AF_INET, "255.255.255.255", &addr->sin_addr);
2900         torture_assert(tctx, ret > 0, "inet_pton failed");
2901 #endif
2902
2903         ctr = talloc(tctx, struct netr_DsRAddressToSitenamesExWCtr);
2904
2905         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
2906         r.in.count = 6;
2907         r.in.addresses = addrs;
2908         r.out.ctr = &ctr;
2909
2910         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2911         torture_assert_ntstatus_ok(tctx, status, "failed");
2912         torture_assert_werr_ok(tctx, r.out.result, "failed");
2913
2914         if (sam_ctx != NULL) {
2915                 for (i = 0; i < 3; i++) {
2916                         torture_assert_casestr_equal(tctx,
2917                                                      ctr->sitename[i].string,
2918                                                      server_site_name(tctx, sam_ctx),
2919                                                      "didn't return default site");
2920                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2921                                        "subnet should be null");
2922                 }
2923                 for (i = 3; i < 6; i++) {
2924                         /* Windows returns "NULL" for the sitename if it isn't
2925                          * IPv6 configured */
2926                         if (torture_setting_bool(tctx, "samba4", false)) {
2927                                 torture_assert_casestr_equal(tctx,
2928                                                              ctr->sitename[i].string,
2929                                                              server_site_name(tctx, sam_ctx),
2930                                                              "didn't return default site");
2931                         }
2932                         torture_assert(tctx, ctr->subnetname[i].string == NULL,
2933                                        "subnet should be null");
2934                 }
2935         }
2936
2937         /* Now try invalid ones (too short buffers) */
2938
2939         addrs[0].size = 0;
2940         addrs[1].size = 1;
2941         addrs[2].size = 4;
2942
2943         addrs[3].size = 0;
2944         addrs[4].size = 1;
2945         addrs[5].size = 4;
2946
2947         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2948         torture_assert_ntstatus_ok(tctx, status, "failed");
2949         torture_assert_werr_ok(tctx, r.out.result, "failed");
2950
2951         for (i = 0; i < 6; i++) {
2952                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2953                                "sitename should be null");
2954                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2955                                "subnet should be null");
2956         }
2957
2958         addrs[0].size = 10;
2959         addrs[0].buffer[0] = AF_UNSPEC;
2960         addrs[1].size = 10;
2961         addrs[1].buffer[0] = AF_UNIX; /* AF_LOCAL = AF_UNIX */
2962         addrs[2].size = 10;
2963         addrs[2].buffer[0] = AF_UNIX;
2964
2965         addrs[3].size = 10;
2966         addrs[3].buffer[0] = 250;
2967         addrs[4].size = 10;
2968         addrs[4].buffer[0] = 251;
2969         addrs[5].size = 10;
2970         addrs[5].buffer[0] = 252;
2971
2972         status = dcerpc_netr_DsRAddressToSitenamesExW_r(b, tctx, &r);
2973         torture_assert_ntstatus_ok(tctx, status, "failed");
2974         torture_assert_werr_ok(tctx, r.out.result, "failed");
2975
2976         for (i = 0; i < 6; i++) {
2977                 torture_assert(tctx, ctr->sitename[i].string == NULL,
2978                                "sitename should be null");
2979                 torture_assert(tctx, ctr->subnetname[i].string == NULL,
2980                                "subnet should be null");
2981         }
2982
2983         return true;
2984 }
2985
2986 static bool test_netr_ServerGetTrustInfo(struct torture_context *tctx,
2987                                          struct dcerpc_pipe *p,
2988                                          struct cli_credentials *machine_credentials)
2989 {
2990         struct netr_ServerGetTrustInfo r;
2991
2992         struct netr_Authenticator a;
2993         struct netr_Authenticator return_authenticator;
2994         struct samr_Password new_owf_password;
2995         struct samr_Password old_owf_password;
2996         struct netr_TrustInfo *trust_info;
2997
2998         struct netlogon_creds_CredentialState *creds;
2999         struct dcerpc_binding_handle *b = p->binding_handle;
3000
3001         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
3002                                     machine_credentials, &creds)) {
3003                 return false;
3004         }
3005
3006         netlogon_creds_client_authenticator(creds, &a);
3007
3008         r.in.server_name                = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3009         r.in.account_name               = talloc_asprintf(tctx, "%s$", TEST_MACHINE_NAME);
3010         r.in.secure_channel_type        = cli_credentials_get_secure_channel_type(machine_credentials);
3011         r.in.computer_name              = TEST_MACHINE_NAME;
3012         r.in.credential                 = &a;
3013
3014         r.out.return_authenticator      = &return_authenticator;
3015         r.out.new_owf_password          = &new_owf_password;
3016         r.out.old_owf_password          = &old_owf_password;
3017         r.out.trust_info                = &trust_info;
3018
3019         torture_assert_ntstatus_ok(tctx, dcerpc_netr_ServerGetTrustInfo_r(b, tctx, &r),
3020                 "ServerGetTrustInfo failed");
3021         torture_assert_ntstatus_ok(tctx, r.out.result, "ServerGetTrustInfo failed");
3022         torture_assert(tctx, netlogon_creds_client_check(creds, &return_authenticator.cred), "Credential chaining failed");
3023
3024         return true;
3025 }
3026
3027
3028 static bool test_GetDomainInfo(struct torture_context *tctx, 
3029                                struct dcerpc_pipe *p,
3030                                struct cli_credentials *machine_credentials)
3031 {
3032         struct netr_LogonGetDomainInfo r;
3033         struct netr_WorkstationInformation q1;
3034         struct netr_Authenticator a;
3035         struct netlogon_creds_CredentialState *creds;
3036         struct netr_OsVersion os;
3037         union netr_WorkstationInfo query;
3038         union netr_DomainInfo info;
3039         const char* const attrs[] = { "dNSHostName", "operatingSystem",
3040                 "operatingSystemServicePack", "operatingSystemVersion",
3041                 "servicePrincipalName", NULL };
3042         char *url;
3043         struct ldb_context *sam_ctx = NULL;
3044         struct ldb_message **res;
3045         struct ldb_message_element *spn_el;
3046         int ret, i;
3047         char *version_str;
3048         const char *old_dnsname = NULL;
3049         char **spns = NULL;
3050         int num_spns = 0;
3051         char *temp_str;
3052         struct dcerpc_binding_handle *b = p->binding_handle;
3053
3054         torture_comment(tctx, "Testing netr_LogonGetDomainInfo\n");
3055
3056         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3057                                     machine_credentials, &creds)) {
3058                 return false;
3059         }
3060
3061         /* We won't double-check this when we are over 'local' transports */
3062         if (dcerpc_server_name(p)) {
3063                 /* Set up connection to SAMDB on DC */
3064                 url = talloc_asprintf(tctx, "ldap://%s", dcerpc_server_name(p));
3065                 sam_ctx = ldb_wrap_connect(tctx, tctx->ev, tctx->lp_ctx, url,
3066                                            NULL,
3067                                            cmdline_credentials,
3068                                            0);
3069                 
3070                 torture_assert(tctx, sam_ctx, "Connection to the SAMDB on DC failed!");
3071         }
3072
3073         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 1st call (no variation of DNS hostname)\n");
3074         netlogon_creds_client_authenticator(creds, &a);
3075
3076         ZERO_STRUCT(r);
3077         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3078         r.in.computer_name = TEST_MACHINE_NAME;
3079         r.in.credential = &a;
3080         r.in.level = 1;
3081         r.in.return_authenticator = &a;
3082         r.in.query = &query;
3083         r.out.return_authenticator = &a;
3084         r.out.info = &info;
3085
3086         ZERO_STRUCT(os);
3087         os.os.MajorVersion = 123;
3088         os.os.MinorVersion = 456;
3089         os.os.BuildNumber = 789;
3090         os.os.CSDVersion = "Service Pack 10";
3091         os.os.ServicePackMajor = 10;
3092         os.os.ServicePackMinor = 1;
3093         os.os.SuiteMask = NETR_VER_SUITE_SINGLEUSERTS;
3094         os.os.ProductType = NETR_VER_NT_SERVER;
3095         os.os.Reserved = 0;
3096
3097         version_str = talloc_asprintf(tctx, "%d.%d (%d)", os.os.MajorVersion,
3098                 os.os.MinorVersion, os.os.BuildNumber);
3099
3100         ZERO_STRUCT(q1);
3101         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3102                 lpcfg_dnsdomain(tctx->lp_ctx));
3103         q1.sitename = "Default-First-Site-Name";
3104         q1.os_version.os = &os;
3105         q1.os_name.string = talloc_asprintf(tctx,
3106                                             "Tortured by Samba4 RPC-NETLOGON: %s",
3107                                             timestring(tctx, time(NULL)));
3108
3109         /* The workstation handles the "servicePrincipalName" and DNS hostname
3110            updates */
3111         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3112
3113         query.workstation_info = &q1;
3114
3115         if (sam_ctx) {
3116                 /* Gets back the old DNS hostname in AD */
3117                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3118                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3119                 old_dnsname =
3120                         ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL);
3121                 
3122                 /* Gets back the "servicePrincipalName"s in AD */
3123                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3124                 if (spn_el != NULL) {
3125                         for (i=0; i < spn_el->num_values; i++) {
3126                                 spns = talloc_realloc(tctx, spns, char *, i + 1);
3127                                 spns[i] = (char *) spn_el->values[i].data;
3128                         }
3129                         num_spns = i;
3130                 }
3131         }
3132
3133         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3134                 "LogonGetDomainInfo failed");
3135         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3136         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3137
3138         smb_msleep(250);
3139
3140         if (sam_ctx) {
3141                 /* AD workstation infos entry check */
3142                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3143                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3144                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3145                 torture_assert_str_equal(tctx,
3146                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3147                                          q1.os_name.string, "'operatingSystem' wrong!");
3148                 torture_assert_str_equal(tctx,
3149                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL),
3150                                          os.os.CSDVersion, "'operatingSystemServicePack' wrong!");
3151                 torture_assert_str_equal(tctx,
3152                                          ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL),
3153                                          version_str, "'operatingSystemVersion' wrong!");
3154
3155                 if (old_dnsname != NULL) {
3156                         /* If before a DNS hostname was set then it should remain
3157                            the same in combination with the "servicePrincipalName"s.
3158                            The DNS hostname should also be returned by our
3159                            "LogonGetDomainInfo" call (in the domain info structure). */
3160                         
3161                         torture_assert_str_equal(tctx,
3162                                                  ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3163                                                  old_dnsname, "'DNS hostname' was not set!");
3164                         
3165                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3166                         torture_assert(tctx, ((spns != NULL) && (spn_el != NULL)),
3167                                        "'servicePrincipalName's not set!");
3168                         torture_assert(tctx, spn_el->num_values == num_spns,
3169                                        "'servicePrincipalName's incorrect!");
3170                         for (i=0; (i < spn_el->num_values) && (i < num_spns); i++)
3171                                 torture_assert_str_equal(tctx,
3172                                                          (char *) spn_el->values[i].data,
3173                                 spns[i], "'servicePrincipalName's incorrect!");
3174
3175                         torture_assert_str_equal(tctx,
3176                                                  info.domain_info->dns_hostname.string,
3177                                                  old_dnsname,
3178                                                  "Out 'DNS hostname' doesn't match the old one!");
3179                 } else {
3180                         /* If no DNS hostname was set then also now none should be set,
3181                            the "servicePrincipalName"s should remain empty and no DNS
3182                            hostname should be returned by our "LogonGetDomainInfo"
3183                            call (in the domain info structure). */
3184                         
3185                         torture_assert(tctx,
3186                                        ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL) == NULL,
3187                                        "'DNS hostname' was set!");
3188                         
3189                         spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3190                         torture_assert(tctx, ((spns == NULL) && (spn_el == NULL)),
3191                                        "'servicePrincipalName's were set!");
3192                         
3193                         torture_assert(tctx,
3194                                        info.domain_info->dns_hostname.string == NULL,
3195                                        "Out 'DNS host name' was set!");
3196                 }
3197         }
3198
3199         /* Checks "workstation flags" */
3200         torture_assert(tctx,
3201                 info.domain_info->workstation_flags
3202                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3203                 "Out 'workstation flags' don't match!");
3204
3205
3206         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 2nd call (variation of DNS hostname doesn't work)\n");
3207         netlogon_creds_client_authenticator(creds, &a);
3208
3209         /* Wipe out the osVersion, and prove which values still 'stick' */
3210         q1.os_version.os = NULL;
3211
3212         /* Change also the DNS hostname to test differences in behaviour */
3213         talloc_free(discard_const_p(char, q1.dns_hostname));
3214         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3215                 lpcfg_dnsdomain(tctx->lp_ctx));
3216
3217         /* The workstation handles the "servicePrincipalName" and DNS hostname
3218            updates */
3219         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3220
3221         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3222                 "LogonGetDomainInfo failed");
3223         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3224
3225         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3226
3227         smb_msleep(250);
3228
3229         if (sam_ctx) {
3230                 /* AD workstation infos entry check */
3231                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3232                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3233                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3234
3235                 torture_assert_str_equal(tctx,
3236                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3237                                          q1.os_name.string, "'operatingSystem' should stick!");
3238                 torture_assert(tctx,
3239                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3240                                "'operatingSystemServicePack' shouldn't stick!");
3241                 torture_assert(tctx,
3242                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3243                                "'operatingSystemVersion' shouldn't stick!");
3244
3245                 /* The DNS host name shouldn't have been updated by the server */
3246
3247                 torture_assert_str_equal(tctx,
3248                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3249                                          old_dnsname, "'DNS host name' did change!");
3250                 
3251                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3252                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3253                    3.5.4.3.9 */
3254                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3255                 torture_assert(tctx, spn_el != NULL,
3256                                "There should exist 'servicePrincipalName's in AD!");
3257                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3258                 for (i=0; i < spn_el->num_values; i++)
3259                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3260                                 break;
3261                 torture_assert(tctx, i != spn_el->num_values,
3262                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3263                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3264                 for (i=0; i < spn_el->num_values; i++)
3265                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3266                                 break;
3267                 torture_assert(tctx, i != spn_el->num_values,
3268                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3269                 
3270                 /* Check that the out DNS hostname was set properly */
3271                 torture_assert_str_equal(tctx, info.domain_info->dns_hostname.string,
3272                                          old_dnsname, "Out 'DNS hostname' doesn't match the old one!");
3273         }
3274
3275         /* Checks "workstation flags" */
3276         torture_assert(tctx,
3277                 info.domain_info->workstation_flags == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3278                 "Out 'workstation flags' don't match!");
3279
3280
3281         /* Now try the same but the workstation flags set to 0 */
3282
3283         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 3rd call (variation of DNS hostname doesn't work)\n");
3284         netlogon_creds_client_authenticator(creds, &a);
3285
3286         /* Change also the DNS hostname to test differences in behaviour */
3287         talloc_free(discard_const_p(char, q1.dns_hostname));
3288         q1.dns_hostname = talloc_asprintf(tctx, "%s2.%s", TEST_MACHINE_NAME,
3289                 lpcfg_dnsdomain(tctx->lp_ctx));
3290
3291         /* Wipe out the osVersion, and prove which values still 'stick' */
3292         q1.os_version.os = NULL;
3293
3294         /* Let the DC handle the "servicePrincipalName" and DNS hostname
3295            updates */
3296         q1.workstation_flags = 0;
3297
3298         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3299                 "LogonGetDomainInfo failed");
3300         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3301         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3302
3303         smb_msleep(250);
3304
3305         if (sam_ctx) {
3306                 /* AD workstation infos entry check */
3307                 ret = gendb_search(sam_ctx, tctx, NULL, &res, attrs,
3308                                    "(sAMAccountName=%s$)", TEST_MACHINE_NAME);
3309                 torture_assert(tctx, ret == 1, "Test machine account not found in SAMDB on DC! Has the workstation been joined?");
3310
3311                 torture_assert_str_equal(tctx,
3312                                          ldb_msg_find_attr_as_string(res[0], "operatingSystem", NULL),
3313                                          q1.os_name.string, "'operatingSystem' should stick!");
3314                 torture_assert(tctx,
3315                                ldb_msg_find_attr_as_string(res[0], "operatingSystemServicePack", NULL) == NULL,
3316                                "'operatingSystemServicePack' shouldn't stick!");
3317                 torture_assert(tctx,
3318                                ldb_msg_find_attr_as_string(res[0], "operatingSystemVersion", NULL) == NULL,
3319                                "'operatingSystemVersion' shouldn't stick!");
3320
3321                 /* The DNS host name shouldn't have been updated by the server */
3322
3323                 torture_assert_str_equal(tctx,
3324                                          ldb_msg_find_attr_as_string(res[0], "dNSHostName", NULL),
3325                                          old_dnsname, "'DNS host name' did change!");
3326
3327                 /* Find the two "servicePrincipalName"s which the DC shouldn't have been
3328                    updated (HOST/<Netbios name> and HOST/<FQDN name>) - see MS-NRPC
3329                    3.5.4.3.9 */
3330                 spn_el = ldb_msg_find_element(res[0], "servicePrincipalName");
3331                 torture_assert(tctx, spn_el != NULL,
3332                                "There should exist 'servicePrincipalName's in AD!");
3333                 temp_str = talloc_asprintf(tctx, "HOST/%s", TEST_MACHINE_NAME);
3334                 for (i=0; i < spn_el->num_values; i++)
3335                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3336                                 break;
3337                 torture_assert(tctx, i != spn_el->num_values,
3338                                "'servicePrincipalName' HOST/<Netbios name> not found!");
3339                 temp_str = talloc_asprintf(tctx, "HOST/%s", old_dnsname);
3340                 for (i=0; i < spn_el->num_values; i++)
3341                         if (strcasecmp((char *) spn_el->values[i].data, temp_str) == 0)
3342                                 break;
3343                 torture_assert(tctx, i != spn_el->num_values,
3344                                "'servicePrincipalName' HOST/<FQDN name> not found!");
3345
3346                 /* Here the server gives us NULL as the out DNS hostname */
3347                 torture_assert(tctx, info.domain_info->dns_hostname.string == NULL,
3348                                "Out 'DNS hostname' should be NULL!");
3349         }
3350
3351         /* Checks "workstation flags" */
3352         torture_assert(tctx,
3353                 info.domain_info->workstation_flags == 0,
3354                 "Out 'workstation flags' don't match!");
3355
3356
3357         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 4th call (verification of DNS hostname and check for trusted domains)\n");
3358         netlogon_creds_client_authenticator(creds, &a);
3359
3360         /* Put the DNS hostname back */
3361         talloc_free(discard_const_p(char, q1.dns_hostname));
3362         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3363                 lpcfg_dnsdomain(tctx->lp_ctx));
3364
3365         /* The workstation handles the "servicePrincipalName" and DNS hostname
3366            updates */
3367         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE;
3368
3369         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3370                 "LogonGetDomainInfo failed");
3371         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3372         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3373
3374         smb_msleep(250);
3375
3376         /* Now the in/out DNS hostnames should be the same */
3377         torture_assert_str_equal(tctx,
3378                 info.domain_info->dns_hostname.string,
3379                 query.workstation_info->dns_hostname,
3380                 "In/Out 'DNS hostnames' don't match!");
3381         old_dnsname = info.domain_info->dns_hostname.string;
3382
3383         /* Checks "workstation flags" */
3384         torture_assert(tctx,
3385                 info.domain_info->workstation_flags
3386                 == NETR_WS_FLAG_HANDLES_SPN_UPDATE,
3387                 "Out 'workstation flags' don't match!");
3388
3389         /* Checks for trusted domains */
3390         torture_assert(tctx,
3391                 (info.domain_info->trusted_domain_count != 0)
3392                 && (info.domain_info->trusted_domains != NULL),
3393                 "Trusted domains have been requested!");
3394
3395
3396         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 5th call (check for trusted domains)\n");
3397         netlogon_creds_client_authenticator(creds, &a);
3398
3399         /* The workstation handles the "servicePrincipalName" and DNS hostname
3400            updates and requests inbound trusts */
3401         q1.workstation_flags = NETR_WS_FLAG_HANDLES_SPN_UPDATE
3402                 | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS;
3403
3404         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3405                 "LogonGetDomainInfo failed");
3406         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3407         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3408
3409         smb_msleep(250);
3410
3411         /* Checks "workstation flags" */
3412         torture_assert(tctx,
3413                 info.domain_info->workstation_flags
3414                 == (NETR_WS_FLAG_HANDLES_SPN_UPDATE
3415                         | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS),
3416                 "Out 'workstation flags' don't match!");
3417
3418         /* Checks for trusted domains */
3419         torture_assert(tctx,
3420                 (info.domain_info->trusted_domain_count != 0)
3421                 && (info.domain_info->trusted_domains != NULL),
3422                 "Trusted domains have been requested!");
3423
3424
3425         torture_comment(tctx, "Testing netr_LogonGetDomainInfo 6th call (no DNS hostname)\n");
3426         netlogon_creds_client_authenticator(creds, &a);
3427
3428         query.workstation_info->dns_hostname = NULL;
3429
3430         torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3431                 "LogonGetDomainInfo failed");
3432         torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3433         torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3434
3435         /* The old DNS hostname should stick */
3436         torture_assert_str_equal(tctx,
3437                 info.domain_info->dns_hostname.string,
3438                 old_dnsname,
3439                 "'DNS hostname' changed!");
3440
3441
3442         if (!torture_setting_bool(tctx, "dangerous", false)) {
3443                 torture_comment(tctx, "Not testing netr_LogonGetDomainInfo 7th call (no workstation info) - enable dangerous tests in order to do so\n");
3444         } else {
3445                 /* Try a call without the workstation information structure */
3446
3447                 torture_comment(tctx, "Testing netr_LogonGetDomainInfo 7th call (no workstation info)\n");
3448                 netlogon_creds_client_authenticator(creds, &a);
3449
3450                 query.workstation_info = NULL;
3451
3452                 torture_assert_ntstatus_ok(tctx, dcerpc_netr_LogonGetDomainInfo_r(b, tctx, &r),
3453                         "LogonGetDomainInfo failed");
3454                 torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed");
3455                 torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed");
3456         }
3457
3458         return true;
3459 }
3460
3461 static bool test_GetDomainInfo_async(struct torture_context *tctx, 
3462                                      struct dcerpc_pipe *p,
3463                                      struct cli_credentials *machine_credentials)
3464 {
3465         NTSTATUS status;
3466         struct netr_LogonGetDomainInfo r;
3467         struct netr_WorkstationInformation q1;
3468         struct netr_Authenticator a;
3469 #define ASYNC_COUNT 100
3470         struct netlogon_creds_CredentialState *creds;
3471         struct netlogon_creds_CredentialState *creds_async[ASYNC_COUNT];
3472         struct tevent_req *req[ASYNC_COUNT];
3473         int i;
3474         union netr_WorkstationInfo query;
3475         union netr_DomainInfo info;
3476
3477         torture_comment(tctx, "Testing netr_LogonGetDomainInfo - async count %d\n", ASYNC_COUNT);
3478
3479         if (!test_SetupCredentials3(p, tctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, 
3480                                     machine_credentials, &creds)) {
3481                 return false;
3482         }
3483
3484         ZERO_STRUCT(r);
3485         r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
3486         r.in.computer_name = TEST_MACHINE_NAME;
3487         r.in.credential = &a;
3488         r.in.level = 1;
3489         r.in.return_authenticator = &a;
3490         r.in.query = &query;
3491         r.out.return_authenticator = &a;
3492         r.out.info = &info;
3493
3494         ZERO_STRUCT(q1);
3495         q1.dns_hostname = talloc_asprintf(tctx, "%s.%s", TEST_MACHINE_NAME,
3496                 lpcfg_dnsdomain(tctx->lp_ctx));
3497         q1.sitename = "Default-First-Site-Name";
3498         q1.os_name.string = "UNIX/Linux or similar";
3499
3500         query.workstation_info = &q1;
3501
3502         for (i=0;i<ASYNC_COUNT;i++) {
3503                 netlogon_creds_client_authenticator(creds, &a);
3504
3505                 creds_async[i] = (struct netlogon_creds_CredentialState *)talloc_memdup(creds, creds, sizeof(*creds));
3506                 req[i] = dcerpc_netr_LogonGetDomainInfo_r_send(tctx, tctx->ev, p->binding_handle, &r);
3507
3508                 /* even with this flush per request a w2k3 server seems to 
3509                    clag with multiple outstanding requests. bleergh. */
3510                 torture_assert_int_equal(tctx, tevent_loop_once(dcerpc_event_context(p)), 0, 
3511                                          "tevent_loop_once failed");
3512         }
3513
3514         for (i=0;i<ASYNC_COUNT;i++) {
3515                 torture_assert_int_equal(tctx, tevent_req_poll(req[i], tctx->ev), true,
3516                                          "tevent_req_poll() failed");
3517
3518                 status = dcerpc_netr_LogonGetDomainInfo_r_recv(req[i], tctx);
3519
3520                 torture_assert_ntstatus_ok(tctx, status, "netr_LogonGetDomainInfo_async");
3521                 torture_assert_ntstatus_ok(tctx, r.out.result, "netr_LogonGetDomainInfo_async"); 
3522
3523                 torture_assert(tctx, netlogon_creds_client_check(creds_async[i], &a.cred), 
3524                         "Credential chaining failed at async");
3525         }
3526
3527         torture_comment(tctx, 
3528                         "Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
3529
3530         return true;
3531 }
3532
3533 static bool test_ManyGetDCName(struct torture_context *tctx, 
3534                                struct dcerpc_pipe *p)
3535 {
3536         NTSTATUS status;
3537         struct dcerpc_pipe *p2;
3538         struct lsa_ObjectAttribute attr;
3539         struct lsa_QosInfo qos;
3540         struct lsa_OpenPolicy2 o;
3541         struct policy_handle lsa_handle;
3542         struct lsa_DomainList domains;
3543
3544         struct lsa_EnumTrustDom t;
3545         uint32_t resume_handle = 0;
3546         struct netr_GetAnyDCName d;
3547         const char *dcname = NULL;
3548         struct dcerpc_binding_handle *b = p->binding_handle;
3549         struct dcerpc_binding_handle *b2;
3550
3551         int i;
3552
3553         if (p->conn->transport.transport != NCACN_NP) {
3554                 return true;
3555         }
3556
3557         torture_comment(tctx, "Torturing GetDCName\n");
3558
3559         status = dcerpc_secondary_connection(p, &p2, p->binding);
3560         torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection");
3561
3562         status = dcerpc_bind_auth_none(p2, &ndr_table_lsarpc);
3563         torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection");
3564         b2 = p2->binding_handle;
3565
3566         qos.len = 0;
3567         qos.impersonation_level = 2;
3568         qos.context_mode = 1;
3569         qos.effective_only = 0;
3570
3571         attr.len = 0;
3572         attr.root_dir = NULL;
3573         attr.object_name = NULL;
3574         attr.attributes = 0;
3575         attr.sec_desc = NULL;
3576         attr.sec_qos = &qos;
3577
3578         o.in.system_name = "\\";
3579         o.in.attr = &attr;
3580         o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3581         o.out.handle = &lsa_handle;
3582
3583         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_OpenPolicy2_r(b2, tctx, &o),
3584                 "OpenPolicy2 failed");
3585         torture_assert_ntstatus_ok(tctx, o.out.result, "OpenPolicy2 failed");
3586
3587         t.in.handle = &lsa_handle;
3588         t.in.resume_handle = &resume_handle;
3589         t.in.max_size = 1000;
3590         t.out.domains = &domains;
3591         t.out.resume_handle = &resume_handle;
3592
3593         torture_assert_ntstatus_ok(tctx, dcerpc_lsa_EnumTrustDom_r(b2, tctx, &t),
3594                 "EnumTrustDom failed");
3595
3596         if ((!NT_STATUS_IS_OK(t.out.result) &&
3597              (!NT_STATUS_EQUAL(t.out.result, NT_STATUS_NO_MORE_ENTRIES))))
3598                 torture_fail(tctx, "Could not list domains");
3599
3600         talloc_free(p2);
3601
3602         d.in.logon_server = talloc_asprintf(tctx, "\\\\%s",
3603                                             dcerpc_server_name(p));
3604         d.out.dcname = &dcname;
3605
3606         for (i=0; i<domains.count * 4; i++) {
3607                 struct lsa_DomainInfo *info =
3608                         &domains.domains[rand()%domains.count];
3609
3610                 d.in.domainname = info->name.string;
3611
3612                 status = dcerpc_netr_GetAnyDCName_r(b, tctx, &d);
3613                 torture_assert_ntstatus_ok(tctx, status, "GetAnyDCName");
3614
3615                 torture_comment(tctx, "\tDC for domain %s is %s\n", info->name.string,
3616                        dcname ? dcname : "unknown");
3617         }
3618
3619         return true;
3620 }
3621
3622 static bool test_SetPassword_with_flags(struct torture_context *tctx,
3623                                         struct dcerpc_pipe *p,
3624                                         struct cli_credentials *machine_credentials)
3625 {
3626         uint32_t flags[] = { 0, NETLOGON_NEG_STRONG_KEYS };
3627         struct netlogon_creds_CredentialState *creds;
3628         int i;
3629
3630         if (!test_SetupCredentials2(p, tctx, 0,
3631                                     machine_credentials,
3632                                     cli_credentials_get_secure_channel_type(machine_credentials),
3633                                     &creds)) {
3634                 torture_skip(tctx, "DC does not support negotiation of 64bit session keys");
3635         }
3636
3637         for (i=0; i < ARRAY_SIZE(flags); i++) {
3638                 torture_assert(tctx,
3639                         test_SetPassword_flags(tctx, p, machine_credentials, flags[i]),
3640                         talloc_asprintf(tctx, "failed to test SetPassword negotiating with 0x%08x flags", flags[i]));
3641         }
3642
3643         return true;
3644 }
3645
3646 struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
3647 {
3648         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon");
3649         struct torture_rpc_tcase *tcase;
3650         struct torture_test *test;
3651
3652         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3653                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3654
3655         torture_rpc_tcase_add_test(tcase, "LogonUasLogon", test_LogonUasLogon);
3656         torture_rpc_tcase_add_test(tcase, "LogonUasLogoff", test_LogonUasLogoff);
3657         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3658         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3659         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3660         torture_rpc_tcase_add_test_creds(tcase, "GetPassword", test_GetPassword);
3661         torture_rpc_tcase_add_test_creds(tcase, "GetTrustPasswords", test_GetTrustPasswords);
3662         torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
3663         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
3664         torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
3665         torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
3666         torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
3667         torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
3668         torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
3669         torture_rpc_tcase_add_test(tcase, "ManyGetDCName", test_ManyGetDCName);
3670         torture_rpc_tcase_add_test(tcase, "GetAnyDCName", test_GetAnyDCName);
3671         torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync2", test_DatabaseSync2);
3672         torture_rpc_tcase_add_test(tcase, "DsrEnumerateDomainTrusts", test_DsrEnumerateDomainTrusts);
3673         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3674         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomainsEx", test_netr_NetrEnumerateTrustedDomainsEx);
3675         test = torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo_async", test_GetDomainInfo_async);
3676         test->dangerous = true;
3677         torture_rpc_tcase_add_test(tcase, "DsRGetDCName", test_netr_DsRGetDCName);
3678         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx", test_netr_DsRGetDCNameEx);
3679         torture_rpc_tcase_add_test(tcase, "DsRGetDCNameEx2", test_netr_DsRGetDCNameEx2);
3680         torture_rpc_tcase_add_test(tcase, "DsrGetDcSiteCoverageW", test_netr_DsrGetDcSiteCoverageW);
3681         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesW", test_netr_DsRAddressToSitenamesW);
3682         torture_rpc_tcase_add_test(tcase, "DsRAddressToSitenamesExW", test_netr_DsRAddressToSitenamesExW);
3683         torture_rpc_tcase_add_test_creds(tcase, "ServerGetTrustInfo", test_netr_ServerGetTrustInfo);
3684         torture_rpc_tcase_add_test_creds(tcase, "GetForestTrustInformation", test_netr_GetForestTrustInformation);
3685
3686         return suite;
3687 }
3688
3689 struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
3690 {
3691         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon-s3");
3692         struct torture_rpc_tcase *tcase;
3693
3694         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3695                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3696
3697         torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
3698         torture_rpc_tcase_add_test_creds(tcase, "SamLogon_NULL_domain", test_SamLogon_NULL_domain);
3699         torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
3700         torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
3701         torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
3702         torture_rpc_tcase_add_test(tcase, "NetrEnumerateTrustedDomains", test_netr_NetrEnumerateTrustedDomains);
3703
3704         return suite;
3705 }
3706
3707 struct torture_suite *torture_rpc_netlogon_admin(TALLOC_CTX *mem_ctx)
3708 {
3709         struct torture_suite *suite = torture_suite_create(mem_ctx, "netlogon.admin");
3710         struct torture_rpc_tcase *tcase;
3711
3712         tcase = torture_suite_add_machine_bdc_rpc_iface_tcase(suite, "netlogon",
3713                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3714         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3715         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3716         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3717
3718         tcase = torture_suite_add_machine_workstation_rpc_iface_tcase(suite, "netlogon",
3719                                                   &ndr_table_netlogon, TEST_MACHINE_NAME);
3720         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3721         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3722         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3723
3724         tcase = torture_suite_add_rpc_iface_tcase(suite, "netlogon",
3725                                                   &ndr_table_netlogon);
3726         torture_rpc_tcase_add_test_creds(tcase, "LogonControl", test_LogonControl);
3727         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2", test_LogonControl2);
3728         torture_rpc_tcase_add_test_creds(tcase, "LogonControl2Ex", test_LogonControl2Ex);
3729
3730         return suite;
3731 }