netlogon.idl: fix the marshalling of netr_trust_extension_container for NDR64
[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",