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