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