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