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