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