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