r4560: - fixed crash bugs in the RPC-SCHANNEL and RPC-NETLOGON tests
[samba.git] / source4 / torture / rpc / samlogon.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    test suite for netlogon SamLogon 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    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26 #include "librpc/gen_ndr/ndr_netlogon.h"
27 #include "auth/auth.h"
28 #include "lib/crypto/crypto.h"
29
30 #define TEST_MACHINE_NAME "samlogontest"
31
32 enum ntlm_break {
33         BREAK_BOTH,
34         BREAK_NONE,
35         BREAK_LM,
36         BREAK_NT,
37         NO_LM,
38         NO_NT
39 };
40
41 struct samlogon_state {
42         TALLOC_CTX *mem_ctx;
43         const char *account_name;
44         const char *account_domain;
45         const char *password;
46         struct dcerpc_pipe *p;
47         int function_level;
48         struct netr_LogonSamLogon r;
49         struct netr_LogonSamLogonEx r_ex;
50         struct netr_LogonSamLogonWithFlags r_flags;
51         struct netr_Authenticator auth, auth2;
52         struct creds_CredentialState *creds;
53
54         DATA_BLOB chall;
55 };
56
57 /* 
58    Authenticate a user with a challenge/response, checking session key
59    and valid authentication types
60 */
61 static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state, 
62                                enum ntlm_break break_which,
63                                DATA_BLOB *chall, 
64                                DATA_BLOB *lm_response, 
65                                DATA_BLOB *nt_response, 
66                                uint8_t lm_key[8], 
67                                uint8_t user_session_key[16], 
68                                char **error_string)
69 {
70         NTSTATUS status;
71         struct netr_LogonSamLogon *r = &samlogon_state->r;
72         struct netr_LogonSamLogonEx *r_ex = &samlogon_state->r_ex;
73         struct netr_LogonSamLogonWithFlags *r_flags = &samlogon_state->r_flags;
74         struct netr_NetworkInfo ninfo;
75         struct netr_SamBaseInfo *base = NULL;
76         uint16 validation_level = 0;
77         
78         samlogon_state->r.in.logon.network = &ninfo;
79         samlogon_state->r_ex.in.logon.network = &ninfo;
80         samlogon_state->r_flags.in.logon.network = &ninfo;
81         
82         ninfo.identity_info.domain_name.string = samlogon_state->account_domain;
83         ninfo.identity_info.parameter_control = 0;
84         ninfo.identity_info.logon_id_low = 0;
85         ninfo.identity_info.logon_id_high = 0;
86         ninfo.identity_info.account_name.string = samlogon_state->account_name;
87         ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
88                 
89         memcpy(ninfo.challenge, chall->data, 8);
90                 
91         switch (break_which) {
92         case BREAK_NONE:
93                 break;
94         case BREAK_LM:
95                 if (lm_response && lm_response->data) {
96                         lm_response->data[0]++;
97                 }
98                 break;
99         case BREAK_NT:
100                 if (nt_response && nt_response->data) {
101                         nt_response->data[0]++;
102                 }
103                 break;
104         case BREAK_BOTH:
105                 if (lm_response && lm_response->data) {
106                         lm_response->data[0]++;
107                 }
108                 if (nt_response && nt_response->data) {
109                         nt_response->data[0]++;
110                 }
111                 break;
112         case NO_LM:
113                 data_blob_free(lm_response);
114                 break;
115         case NO_NT:
116                 data_blob_free(nt_response);
117                 break;
118         }
119                 
120         if (nt_response) {
121                 ninfo.nt.data = nt_response->data;
122                 ninfo.nt.length = nt_response->length;
123         } else {
124                 ninfo.nt.data = NULL;
125                 ninfo.nt.length = 0;
126         }
127                 
128         if (lm_response) {
129                 ninfo.lm.data = lm_response->data;
130                 ninfo.lm.length = lm_response->length;
131         } else {
132                 ninfo.lm.data = NULL;
133                 ninfo.lm.length = 0;
134         }
135         
136         switch (samlogon_state->function_level) {
137         case DCERPC_NETR_LOGONSAMLOGON: 
138                 ZERO_STRUCT(samlogon_state->auth2);
139                 creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth);
140
141                 r->out.return_authenticator = NULL;
142                 status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r);
143                 if (!r->out.return_authenticator || 
144                     !creds_client_check(samlogon_state->creds, &r->out.return_authenticator->cred)) {
145                         printf("Credential chaining failed\n");
146                 }
147                 if (!NT_STATUS_IS_OK(status)) {
148                         if (error_string) {
149                                 *error_string = strdup(nt_errstr(status));
150                         }
151                 }
152
153                 validation_level = r->in.validation_level;
154                 switch (validation_level) {
155                 case 2:
156                         base = &r->out.validation.sam2->base;
157                         break;
158                 case 3:
159                         base = &r->out.validation.sam3->base;
160                         break;
161                 case 6:
162                         base = &r->out.validation.sam6->base;
163                         break;
164                 }
165                 break;
166         case DCERPC_NETR_LOGONSAMLOGONEX: 
167                 status = dcerpc_netr_LogonSamLogonEx(samlogon_state->p, samlogon_state->mem_ctx, r_ex);
168                 if (!NT_STATUS_IS_OK(status)) {
169                         if (error_string) {
170                                 *error_string = strdup(nt_errstr(status));
171                         }
172                 }
173
174                 validation_level = r_ex->in.validation_level;
175                 switch (validation_level) {
176                 case 2:
177                         base = &r_ex->out.validation.sam2->base;
178                         break;
179                 case 3:
180                         base = &r_ex->out.validation.sam3->base;
181                         break;
182                 case 6:
183                         base = &r_ex->out.validation.sam6->base;
184                         break;
185                 }
186                 break;
187         case DCERPC_NETR_LOGONSAMLOGONWITHFLAGS: 
188                 ZERO_STRUCT(samlogon_state->auth2);
189                 creds_client_authenticator(samlogon_state->creds, &samlogon_state->auth);
190
191                 r_flags->out.return_authenticator = NULL;
192                 status = dcerpc_netr_LogonSamLogonWithFlags(samlogon_state->p, samlogon_state->mem_ctx, r_flags);
193                 if (!r_flags->out.return_authenticator || 
194                     !creds_client_check(samlogon_state->creds, &r_flags->out.return_authenticator->cred)) {
195                         printf("Credential chaining failed\n");
196                 }
197                 if (!NT_STATUS_IS_OK(status)) {
198                         if (error_string) {
199                                 *error_string = strdup(nt_errstr(status));
200                         }
201                 }
202
203                 validation_level = r_flags->in.validation_level;
204                 switch (validation_level) {
205                 case 2:
206                         base = &r_flags->out.validation.sam2->base;
207                         break;
208                 case 3:
209                         base = &r_flags->out.validation.sam3->base;
210                         break;
211                 case 6:
212                         base = &r_flags->out.validation.sam6->base;
213                         break;
214                 }
215                 break;
216         }
217                 
218
219         if (!NT_STATUS_IS_OK(status)) {
220                 /* we cannot check the session key, if the logon failed... */
221                 return status;
222         }
223
224         if (!base) {
225                 printf("No user info returned from 'successful' SamLogon*() call!\n");
226                 return NT_STATUS_INVALID_PARAMETER;
227         }
228
229         /* find and decyrpt the session keys, return in parameters above */
230         if (validation_level == 6) {
231                 /* they aren't encrypted! */
232                 if (user_session_key) {
233                         memcpy(user_session_key, base->key.key, 16);
234                 }
235                 if (lm_key) {
236                         memcpy(lm_key, base->LMSessKey.key, 8);
237                 }
238         } else if (samlogon_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
239                 static const char zeros[16];
240                         
241                 if (memcmp(base->key.key, zeros,  
242                            sizeof(base->key.key)) != 0) {
243                         creds_arcfour_crypt(samlogon_state->creds, 
244                                             base->key.key, 
245                                             sizeof(base->key.key));
246                 }
247                         
248                 if (user_session_key) {
249                         memcpy(user_session_key, base->key.key, 16);
250                 }
251                         
252                 if (memcmp(base->LMSessKey.key, zeros,  
253                            sizeof(base->LMSessKey.key)) != 0) {
254                         creds_arcfour_crypt(samlogon_state->creds, 
255                                             base->LMSessKey.key, 
256                                             sizeof(base->LMSessKey.key));
257                 }
258                         
259                 if (lm_key) {
260                         memcpy(lm_key, base->LMSessKey.key, 8);
261                 }
262         } else {
263                 static const char zeros[16];
264                         
265                 if (user_session_key) {
266                         memcpy(user_session_key, base->key.key, 16);
267                 }
268
269                 if (memcmp(base->LMSessKey.key, zeros,  
270                            sizeof(base->LMSessKey.key)) != 0) {
271                         creds_des_decrypt_LMKey(samlogon_state->creds, 
272                                                 &base->LMSessKey);
273                 }
274                         
275                 if (lm_key) {
276                         memcpy(lm_key, base->LMSessKey.key, 8);
277                 }
278         }
279         
280         return status;
281
282
283
284 /* 
285  * Test the normal 'LM and NTLM' combination
286  */
287
288 static BOOL test_lm_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string) 
289 {
290         BOOL pass = True;
291         BOOL lm_good;
292         NTSTATUS nt_status;
293         DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
294         DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
295         DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
296
297         uint8_t lm_key[8];
298         uint8_t user_session_key[16];
299         uint8_t lm_hash[16];
300         uint8_t nt_hash[16];
301         
302         ZERO_STRUCT(lm_key);
303         ZERO_STRUCT(user_session_key);
304
305         lm_good = SMBencrypt(samlogon_state->password, samlogon_state->chall.data, lm_response.data);
306         if (!lm_good) {
307                 ZERO_STRUCT(lm_hash);
308         } else {
309                 E_deshash(samlogon_state->password, lm_hash); 
310         }
311                 
312         SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
313
314         E_md4hash(samlogon_state->password, nt_hash);
315         SMBsesskeygen_ntv1(nt_hash, session_key.data);
316
317         nt_status = check_samlogon(samlogon_state,
318                                    break_which,
319                                    &samlogon_state->chall,
320                                    &lm_response,
321                                    &nt_response,
322                                    lm_key, 
323                                    user_session_key,
324                                    error_string);
325         
326         data_blob_free(&lm_response);
327
328         if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
329                 /* for 'long' passwords, the LM password is invalid */
330                 if (break_which == NO_NT && !lm_good) {
331                         return True;
332                 }
333                 return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
334         }
335
336         if (!NT_STATUS_IS_OK(nt_status)) {
337                 return False;
338         }
339
340         if (break_which == NO_NT && !lm_good) {
341                 printf("LM password is 'long' (> 14 chars and therefore invalid) but login did not fail!");
342                 return False;
343         }
344
345         if (memcmp(lm_hash, lm_key, 
346                    sizeof(lm_key)) != 0) {
347                 printf("LM Key does not match expectations!\n");
348                 printf("lm_key:\n");
349                 dump_data(1, lm_key, 8);
350                 printf("expected:\n");
351                 dump_data(1, lm_hash, 8);
352                 pass = False;
353         }
354
355         switch (break_which) {
356         case NO_NT:
357         {
358                 uint8_t lm_key_expected[16];
359                 memcpy(lm_key_expected, lm_hash, 8);
360                 memset(lm_key_expected+8, '\0', 8);
361                 if (memcmp(lm_key_expected, user_session_key, 
362                            16) != 0) {
363                         printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
364                         printf("user_session_key:\n");
365                         dump_data(1, user_session_key, sizeof(user_session_key));
366                         printf("expected:\n");
367                         dump_data(1, lm_key_expected, sizeof(lm_key_expected));
368                         pass = False;
369                 }
370                 break;
371         }
372         default:
373                 if (memcmp(session_key.data, user_session_key, 
374                            sizeof(user_session_key)) != 0) {
375                         printf("NT Session Key does not match expectations!\n");
376                         printf("user_session_key:\n");
377                         dump_data(1, user_session_key, 16);
378                         printf("expected:\n");
379                         dump_data(1, session_key.data, session_key.length);
380                         pass = False;
381                 }
382         }
383         return pass;
384 }
385
386 /* 
387  * Test LM authentication, no NT response supplied
388  */
389
390 static BOOL test_lm(struct samlogon_state *samlogon_state, char **error_string) 
391 {
392
393         return test_lm_ntlm_broken(samlogon_state, NO_NT, error_string);
394 }
395
396 /* 
397  * Test the NTLM response only, no LM.
398  */
399
400 static BOOL test_ntlm(struct samlogon_state *samlogon_state, char **error_string) 
401 {
402         return test_lm_ntlm_broken(samlogon_state, NO_LM, error_string);
403 }
404
405 /* 
406  * Test the NTLM response only, but in the LM field.
407  */
408
409 static BOOL test_ntlm_in_lm(struct samlogon_state *samlogon_state, char **error_string) 
410 {
411         BOOL pass = True;
412         NTSTATUS nt_status;
413         DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
414
415         uint8_t lm_key[8];
416         uint8_t lm_hash[16];
417         uint8_t user_session_key[16];
418         
419         ZERO_STRUCT(user_session_key);
420
421         SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
422
423         E_deshash(samlogon_state->password, lm_hash); 
424
425         nt_status = check_samlogon(samlogon_state,
426                                    BREAK_NONE,
427                                    &samlogon_state->chall,
428                                    &nt_response,
429                                    NULL,
430                                    lm_key, 
431                                    user_session_key,
432                                    error_string);
433         
434         if (!NT_STATUS_IS_OK(nt_status)) {
435                 return False;
436         }
437
438         if (memcmp(lm_hash, lm_key, 
439                    sizeof(lm_key)) != 0) {
440                 printf("LM Key does not match expectations!\n");
441                 printf("lm_key:\n");
442                 dump_data(1, lm_key, 8);
443                 printf("expected:\n");
444                 dump_data(1, lm_hash, 8);
445                 pass = False;
446         }
447         if (memcmp(lm_hash, user_session_key, 8) != 0) {
448                 uint8_t lm_key_expected[16];
449                 memcpy(lm_key_expected, lm_hash, 8);
450                 memset(lm_key_expected+8, '\0', 8);
451                 if (memcmp(lm_key_expected, user_session_key, 
452                            16) != 0) {
453                         printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
454                         printf("user_session_key:\n");
455                         dump_data(1, user_session_key, sizeof(user_session_key));
456                         printf("expected:\n");
457                         dump_data(1, lm_key_expected, sizeof(lm_key_expected));
458                         pass = False;
459                 }
460         }
461         return pass;
462 }
463
464 /* 
465  * Test the NTLM response only, but in the both the NT and LM fields.
466  */
467
468 static BOOL test_ntlm_in_both(struct samlogon_state *samlogon_state, char **error_string) 
469 {
470         BOOL pass = True;
471         BOOL lm_good;
472         NTSTATUS nt_status;
473         DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
474         DATA_BLOB session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
475
476         uint8_t lm_key[8];
477         uint8_t lm_hash[16];
478         uint8_t user_session_key[16];
479         uint8_t nt_hash[16];
480         
481         ZERO_STRUCT(lm_key);
482         ZERO_STRUCT(user_session_key);
483
484         SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, 
485                      nt_response.data);
486         E_md4hash(samlogon_state->password, nt_hash);
487         SMBsesskeygen_ntv1(nt_hash, 
488                            session_key.data);
489
490         lm_good = E_deshash(samlogon_state->password, lm_hash); 
491         if (!lm_good) {
492                 ZERO_STRUCT(lm_hash);
493         }
494
495         nt_status = check_samlogon(samlogon_state,
496                                    BREAK_NONE,
497                                    &samlogon_state->chall,
498                                    NULL, 
499                                    &nt_response,
500                                    lm_key, 
501                                    user_session_key,
502                                    error_string);
503         
504         if (!NT_STATUS_IS_OK(nt_status)) {
505                 return False;
506         }
507
508         if (memcmp(lm_hash, lm_key, 
509                    sizeof(lm_key)) != 0) {
510                 printf("LM Key does not match expectations!\n");
511                 printf("lm_key:\n");
512                 dump_data(1, lm_key, 8);
513                 printf("expected:\n");
514                 dump_data(1, lm_hash, 8);
515                 pass = False;
516         }
517         if (memcmp(session_key.data, user_session_key, 
518                    sizeof(user_session_key)) != 0) {
519                 printf("NT Session Key does not match expectations!\n");
520                 printf("user_session_key:\n");
521                 dump_data(1, user_session_key, 16);
522                 printf("expected:\n");
523                 dump_data(1, session_key.data, session_key.length);
524                 pass = False;
525         }
526
527
528         return pass;
529 }
530
531 /* 
532  * Test the NTLMv2 and LMv2 responses
533  */
534
535 static BOOL test_lmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string) 
536 {
537         BOOL pass = True;
538         NTSTATUS nt_status;
539         DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
540         DATA_BLOB lmv2_response = data_blob(NULL, 0);
541         DATA_BLOB lmv2_session_key = data_blob(NULL, 0);
542         DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
543         DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, lp_netbios_name(), lp_workgroup());
544
545         uint8_t lm_session_key[8];
546         uint8_t user_session_key[16];
547
548         ZERO_STRUCT(lm_session_key);
549         ZERO_STRUCT(user_session_key);
550         
551         /* TODO - test with various domain cases, and without domain */
552         if (!SMBNTLMv2encrypt(samlogon_state->account_name, samlogon_state->account_domain, 
553                               samlogon_state->password, &samlogon_state->chall,
554                               &names_blob,
555                               &lmv2_response, &ntlmv2_response, 
556                               &lmv2_session_key, &ntlmv2_session_key)) {
557                 data_blob_free(&names_blob);
558                 return False;
559         }
560         data_blob_free(&names_blob);
561
562         nt_status = check_samlogon(samlogon_state,
563                                    break_which,
564                                    &samlogon_state->chall,
565                                    &lmv2_response,
566                                    &ntlmv2_response,
567                                    lm_session_key, 
568                                    user_session_key,
569                                    error_string);
570         
571         data_blob_free(&lmv2_response);
572         data_blob_free(&ntlmv2_response);
573
574
575         if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
576                 return break_which == BREAK_BOTH;
577         }
578
579         if (!NT_STATUS_IS_OK(nt_status)) {
580                 return False;
581         }
582
583         switch (break_which) {
584         case NO_NT:
585                 if (memcmp(lmv2_session_key.data, user_session_key, 
586                            sizeof(user_session_key)) != 0) {
587                         printf("USER (LMv2) Session Key does not match expectations!\n");
588                         printf("user_session_key:\n");
589                         dump_data(1, user_session_key, 16);
590                         printf("expected:\n");
591                         dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);
592                         pass = False;
593                 }
594                 if (memcmp(lmv2_session_key.data, lm_session_key, 
595                            sizeof(lm_session_key)) != 0) {
596                         printf("LM (LMv2) Session Key does not match expectations!\n");
597                         printf("lm_session_key:\n");
598                         dump_data(1, lm_session_key, 8);
599                         printf("expected:\n");
600                         dump_data(1, lmv2_session_key.data, 8);
601                         pass = False;
602                 }
603                 break;
604         default:
605                 if (memcmp(ntlmv2_session_key.data, user_session_key, 
606                            sizeof(user_session_key)) != 0) {
607                         printf("USER (NTLMv2) Session Key does not match expectations!\n");
608                         printf("user_session_key:\n");
609                         dump_data(1, user_session_key, 16);
610                         printf("expected:\n");
611                         dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
612                         pass = False;
613                 }
614                 if (memcmp(ntlmv2_session_key.data, lm_session_key, 
615                            sizeof(lm_session_key)) != 0) {
616                         printf("LM (NTLMv2) Session Key does not match expectations!\n");
617                         printf("lm_session_key:\n");
618                         dump_data(1, lm_session_key, 8);
619                         printf("expected:\n");
620                         dump_data(1, ntlmv2_session_key.data, 8);
621                         pass = False;
622                 }
623         }
624
625         return pass;
626 }
627
628 /* 
629  * Test the NTLM and LMv2 responses
630  */
631
632 static BOOL test_lmv2_ntlm_broken(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string) 
633 {
634         BOOL pass = True;
635         NTSTATUS nt_status;
636         DATA_BLOB ntlmv2_response = data_blob(NULL, 0);
637         DATA_BLOB lmv2_response = data_blob(NULL, 0);
638         DATA_BLOB lmv2_session_key = data_blob(NULL, 0);
639         DATA_BLOB ntlmv2_session_key = data_blob(NULL, 0);
640         DATA_BLOB names_blob = NTLMv2_generate_names_blob(samlogon_state->mem_ctx, lp_netbios_name(), lp_workgroup());
641
642         DATA_BLOB ntlm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
643         DATA_BLOB ntlm_session_key = data_blob_talloc(samlogon_state->mem_ctx, NULL, 16);
644
645         uint8_t lm_hash[16];
646         uint8_t lm_session_key[8];
647         uint8_t user_session_key[16];
648         uint8_t nt_hash[16];
649
650         SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, 
651                      ntlm_response.data);
652         E_md4hash(samlogon_state->password, nt_hash);
653         SMBsesskeygen_ntv1(nt_hash, 
654                            ntlm_session_key.data);
655         E_deshash(samlogon_state->password, lm_hash); 
656
657         ZERO_STRUCT(lm_session_key);
658         ZERO_STRUCT(user_session_key);
659         
660         /* TODO - test with various domain cases, and without domain */
661         if (!SMBNTLMv2encrypt(samlogon_state->account_name, samlogon_state->account_domain, 
662                               samlogon_state->password, &samlogon_state->chall,
663                               &names_blob,
664                               &lmv2_response, &ntlmv2_response, 
665                               &lmv2_session_key, &ntlmv2_session_key)) {
666                 data_blob_free(&names_blob);
667                 return False;
668         }
669         data_blob_free(&names_blob);
670
671         nt_status = check_samlogon(samlogon_state,
672                                    break_which,
673                                    &samlogon_state->chall,
674                                    &lmv2_response,
675                                    &ntlm_response,
676                                    lm_session_key, 
677                                    user_session_key,
678                                    error_string);
679         
680         data_blob_free(&lmv2_response);
681         data_blob_free(&ntlmv2_response);
682
683
684         if (NT_STATUS_EQUAL(NT_STATUS_WRONG_PASSWORD, nt_status)) {
685                 return ((break_which == BREAK_NT) || (break_which == BREAK_BOTH));
686         }
687
688         if (!NT_STATUS_IS_OK(nt_status)) {
689                 return False;
690         }
691
692         switch (break_which) {
693         case NO_NT:
694                 if (memcmp(lmv2_session_key.data, user_session_key, 
695                            sizeof(user_session_key)) != 0) {
696                         printf("USER (LMv2) Session Key does not match expectations!\n");
697                         printf("user_session_key:\n");
698                         dump_data(1, user_session_key, 16);
699                         printf("expected:\n");
700                         dump_data(1, lmv2_session_key.data, ntlmv2_session_key.length);
701                         pass = False;
702                 }
703                 if (memcmp(lmv2_session_key.data, lm_session_key, 
704                            sizeof(lm_session_key)) != 0) {
705                         printf("LM (LMv2) Session Key does not match expectations!\n");
706                         printf("lm_session_key:\n");
707                         dump_data(1, lm_session_key, 8);
708                         printf("expected:\n");
709                         dump_data(1, lmv2_session_key.data, 8);
710                         pass = False;
711                 }
712                 break;
713         case BREAK_LM:
714                 if (memcmp(ntlm_session_key.data, user_session_key, 
715                            sizeof(user_session_key)) != 0) {
716                         printf("USER (NTLMv2) Session Key does not match expectations!\n");
717                         printf("user_session_key:\n");
718                         dump_data(1, user_session_key, 16);
719                         printf("expected:\n");
720                         dump_data(1, ntlm_session_key.data, ntlm_session_key.length);
721                         pass = False;
722                 }
723                 if (memcmp(lm_hash, lm_session_key, 
724                            sizeof(lm_session_key)) != 0) {
725                         printf("LM Session Key does not match expectations!\n");
726                         printf("lm_session_key:\n");
727                         dump_data(1, lm_session_key, 8);
728                         printf("expected:\n");
729                         dump_data(1, lm_hash, 8);
730                         pass = False;
731                 }
732                 break;
733         default:
734                 if (memcmp(ntlm_session_key.data, user_session_key, 
735                            sizeof(user_session_key)) != 0) {
736                         printf("USER (NTLMv2) Session Key does not match expectations!\n");
737                         printf("user_session_key:\n");
738                         dump_data(1, user_session_key, 16);
739                         printf("expected:\n");
740                         dump_data(1, ntlm_session_key.data, ntlm_session_key.length);
741                         pass = False;
742                 }
743                 if (memcmp(ntlm_session_key.data, lm_session_key, 
744                            sizeof(lm_session_key)) != 0) {
745                         printf("LM (NTLMv2) Session Key does not match expectations!\n");
746                         printf("lm_session_key:\n");
747                         dump_data(1, lm_session_key, 8);
748                         printf("expected:\n");
749                         dump_data(1, ntlm_session_key.data, 8);
750                         pass = False;
751                 }
752         }
753
754         return pass;
755 }
756
757 /* 
758  * Test the NTLMv2 and LMv2 responses
759  */
760
761 static BOOL test_lmv2_ntlmv2(struct samlogon_state *samlogon_state, char **error_string) 
762 {
763         return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NONE, error_string);
764 }
765
766 /* 
767  * Test the LMv2 response only
768  */
769
770 static BOOL test_lmv2(struct samlogon_state *samlogon_state, char **error_string) 
771 {
772         return test_lmv2_ntlmv2_broken(samlogon_state, NO_NT, error_string);
773 }
774
775 /* 
776  * Test the NTLMv2 response only
777  */
778
779 static BOOL test_ntlmv2(struct samlogon_state *samlogon_state, char **error_string) 
780 {
781         return test_lmv2_ntlmv2_broken(samlogon_state, NO_LM, error_string);
782 }
783
784 static BOOL test_lm_ntlm(struct samlogon_state *samlogon_state, char **error_string) 
785 {
786         return test_lm_ntlm_broken(samlogon_state, BREAK_NONE, error_string);
787 }
788
789 static BOOL test_ntlm_lm_broken(struct samlogon_state *samlogon_state, char **error_string) 
790 {
791         return test_lm_ntlm_broken(samlogon_state, BREAK_LM, error_string);
792 }
793
794 static BOOL test_ntlm_ntlm_broken(struct samlogon_state *samlogon_state, char **error_string) 
795 {
796         return test_lm_ntlm_broken(samlogon_state, BREAK_NT, error_string);
797 }
798
799 static BOOL test_lm_ntlm_both_broken(struct samlogon_state *samlogon_state, char **error_string) 
800 {
801         return test_lm_ntlm_broken(samlogon_state, BREAK_BOTH, error_string);
802 }
803 static BOOL test_ntlmv2_lmv2_broken(struct samlogon_state *samlogon_state, char **error_string) 
804 {
805         return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_LM, error_string);
806 }
807
808 static BOOL test_ntlmv2_ntlmv2_broken(struct samlogon_state *samlogon_state, char **error_string) 
809 {
810         return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_NT, error_string);
811 }
812
813 static BOOL test_ntlmv2_both_broken(struct samlogon_state *samlogon_state, char **error_string) 
814 {
815         return test_lmv2_ntlmv2_broken(samlogon_state, BREAK_BOTH, error_string);
816 }
817
818 static BOOL test_lmv2_ntlm_both_broken(struct samlogon_state *samlogon_state, char **error_string) 
819 {
820         return test_lmv2_ntlm_broken(samlogon_state, BREAK_BOTH, error_string);
821 }
822
823 static BOOL test_lmv2_ntlm_break_ntlm(struct samlogon_state *samlogon_state, char **error_string) 
824 {
825         return test_lmv2_ntlm_broken(samlogon_state, BREAK_NT, error_string);
826 }
827
828 static BOOL test_lmv2_ntlm_break_lm(struct samlogon_state *samlogon_state, char **error_string) 
829 {
830         return test_lmv2_ntlm_broken(samlogon_state, BREAK_LM, error_string);
831 }
832
833 /* 
834  * Test the NTLM2 response (extra challenge in LM feild)
835  *
836  * This test is the same as the 'break LM' test, but checks that the
837  * server implements NTLM2 session security in the right place
838  * (NETLOGON is the wrong place).
839  */
840
841 static BOOL test_ntlm2(struct samlogon_state *samlogon_state, char **error_string) 
842 {
843         BOOL pass = True;
844         NTSTATUS nt_status;
845         DATA_BLOB lm_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
846         DATA_BLOB nt_response = data_blob_talloc(samlogon_state->mem_ctx, NULL, 24);
847
848         uint8_t lm_key[8];
849         uint8_t nt_hash[16];
850         uint8_t lm_hash[16];
851         uint8_t nt_key[16];
852         uint8_t user_session_key[16];
853         uint8_t expected_user_session_key[16];
854         uint8_t session_nonce_hash[16];
855         uint8_t client_chall[8];
856         
857         struct MD5Context md5_session_nonce_ctx;
858         HMACMD5Context hmac_ctx;
859                         
860         ZERO_STRUCT(user_session_key);
861         ZERO_STRUCT(lm_key);
862         generate_random_buffer(client_chall, 8);
863         
864         MD5Init(&md5_session_nonce_ctx);
865         MD5Update(&md5_session_nonce_ctx, samlogon_state->chall.data, 8);
866         MD5Update(&md5_session_nonce_ctx, client_chall, 8);
867         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
868         
869         E_md4hash(samlogon_state->password, (uint8_t *)nt_hash);
870         E_deshash(samlogon_state->password, (uint8_t *)lm_hash);
871         SMBsesskeygen_ntv1((const uint8_t *)nt_hash, 
872                            nt_key);
873
874         SMBNTencrypt(samlogon_state->password, samlogon_state->chall.data, nt_response.data);
875
876         memcpy(lm_response.data, session_nonce_hash, 8);
877         memset(lm_response.data + 8, 0, 16);
878
879         hmac_md5_init_rfc2104(nt_key, 16, &hmac_ctx);
880         hmac_md5_update(samlogon_state->chall.data, 8, &hmac_ctx);
881         hmac_md5_update(client_chall, 8, &hmac_ctx);
882         hmac_md5_final(expected_user_session_key, &hmac_ctx);
883
884         nt_status = check_samlogon(samlogon_state,
885                                    BREAK_NONE,
886                                    &samlogon_state->chall,
887                                    &lm_response,
888                                    &nt_response,
889                                    lm_key, 
890                                    user_session_key,
891                                    error_string);
892         
893         if (!NT_STATUS_IS_OK(nt_status)) {
894                 return False;
895         }
896
897         if (memcmp(lm_hash, lm_key, 
898                    sizeof(lm_key)) != 0) {
899                 printf("LM Key does not match expectations!\n");
900                 printf("lm_key:\n");
901                 dump_data(1, lm_key, 8);
902                 printf("expected:\n");
903                 dump_data(1, lm_hash, 8);
904                 pass = False;
905         }
906         if (memcmp(nt_key, user_session_key, 16) != 0) {
907                 printf("NT Session Key does not match expectations (should be first-8 LM hash)!\n");
908                 printf("user_session_key:\n");
909                 dump_data(1, user_session_key, sizeof(user_session_key));
910                 printf("expected:\n");
911                 dump_data(1, nt_key, sizeof(nt_key));
912                 pass = False;
913         }
914         return pass;
915 }
916
917 static BOOL test_plaintext(struct samlogon_state *samlogon_state, enum ntlm_break break_which, char **error_string)
918 {
919         NTSTATUS nt_status;
920         DATA_BLOB nt_response = data_blob(NULL, 0);
921         DATA_BLOB lm_response = data_blob(NULL, 0);
922         char *password;
923         char *dospw;
924         void *unicodepw;
925
926         uint8_t user_session_key[16];
927         uint8_t lm_key[16];
928         static const uint8_t zeros[8];
929         DATA_BLOB chall = data_blob_talloc(samlogon_state->mem_ctx, zeros, sizeof(zeros));
930
931         ZERO_STRUCT(user_session_key);
932         
933         if ((push_ucs2_talloc(samlogon_state->mem_ctx, &unicodepw, 
934                               samlogon_state->password)) == -1) {
935                 DEBUG(0, ("push_ucs2_allocate failed!\n"));
936                 exit(1);
937         }
938
939         nt_response = data_blob_talloc(samlogon_state->mem_ctx, unicodepw, strlen_m(samlogon_state->password)*2);
940
941         password = strupper_talloc(samlogon_state->mem_ctx, samlogon_state->password);
942
943         if ((convert_string_talloc(samlogon_state->mem_ctx, CH_UNIX, 
944                                    CH_DOS, password,
945                                    strlen(password)+1, 
946                                    (void**)&dospw)) == -1) {
947                 DEBUG(0, ("convert_string_talloc failed!\n"));
948                 exit(1);
949         }
950
951         lm_response = data_blob_talloc(samlogon_state->mem_ctx, dospw, strlen(dospw));
952
953         nt_status = check_samlogon(samlogon_state,
954                                    break_which,
955                                    &chall,
956                                    &lm_response,
957                                    &nt_response,
958                                    lm_key, 
959                                    user_session_key,
960                                    error_string);
961         
962         if (!NT_STATUS_IS_OK(nt_status)) {
963                 return break_which == BREAK_NT;
964         }
965
966         return True;
967 }
968
969 static BOOL test_plaintext_none_broken(struct samlogon_state *samlogon_state, 
970                                        char **error_string) {
971         return test_plaintext(samlogon_state, BREAK_NONE, error_string);
972 }
973
974 static BOOL test_plaintext_lm_broken(struct samlogon_state *samlogon_state, 
975                                      char **error_string) {
976         return test_plaintext(samlogon_state, BREAK_LM, error_string);
977 }
978
979 static BOOL test_plaintext_nt_broken(struct samlogon_state *samlogon_state, 
980                                      char **error_string) {
981         return test_plaintext(samlogon_state, BREAK_NT, error_string);
982 }
983
984 static BOOL test_plaintext_nt_only(struct samlogon_state *samlogon_state, 
985                                    char **error_string) {
986         return test_plaintext(samlogon_state, NO_LM, error_string);
987 }
988
989 static BOOL test_plaintext_lm_only(struct samlogon_state *samlogon_state, 
990                                    char **error_string) {
991         return test_plaintext(samlogon_state, NO_NT, error_string);
992 }
993
994 /* 
995    Tests:
996    
997    - LM only
998    - NT and LM             
999    - NT
1000    - NT in LM field
1001    - NT in both fields
1002    - NTLMv2
1003    - NTLMv2 and LMv2
1004    - LMv2
1005    - plaintext tests (in challenge-response fields)
1006   
1007    check we get the correct session key in each case
1008    check what values we get for the LM session key
1009    
1010 */
1011
1012 static const struct ntlm_tests {
1013         BOOL (*fn)(struct samlogon_state *, char **);
1014         const char *name;
1015         BOOL expect_fail;
1016 } test_table[] = {
1017         {test_lm, "LM", False},
1018         {test_lm_ntlm, "LM and NTLM", False},
1019         {test_lm_ntlm_both_broken, "LM and NTLM, both broken", False},
1020         {test_ntlm, "NTLM", False},
1021         {test_ntlm_in_lm, "NTLM in LM", False},
1022         {test_ntlm_in_both, "NTLM in both", False},
1023         {test_ntlmv2, "NTLMv2", False},
1024         {test_lmv2_ntlmv2, "NTLMv2 and LMv2", False},
1025         {test_lmv2, "LMv2", False},
1026         {test_ntlmv2_lmv2_broken, "NTLMv2 and LMv2, LMv2 broken", False},
1027         {test_ntlmv2_ntlmv2_broken, "NTLMv2 and LMv2, NTLMv2 broken", False},
1028         {test_ntlmv2_both_broken, "NTLMv2 and LMv2, both broken", False},
1029         {test_ntlm_lm_broken, "NTLM and LM, LM broken", False},
1030         {test_ntlm_ntlm_broken, "NTLM and LM, NTLM broken", False},
1031         {test_ntlm2, "NTLM2 (NTLMv2 session security)", False},
1032         {test_lmv2_ntlm_both_broken, "LMv2 and NTLM, both broken", False},
1033         {test_lmv2_ntlm_break_ntlm, "LMv2 and NTLM, NTLM broken", False},
1034         {test_lmv2_ntlm_break_lm, "LMv2 and NTLM, LMv2 broken", False},
1035         {test_plaintext_none_broken, "Plaintext", True},
1036         {test_plaintext_lm_broken, "Plaintext LM broken", True},
1037         {test_plaintext_nt_broken, "Plaintext NT broken", True},
1038         {test_plaintext_nt_only, "Plaintext NT only", True},
1039         {test_plaintext_lm_only, "Plaintext LM only", True},
1040         {NULL, NULL}
1041 };
1042
1043 /*
1044   try a netlogon SamLogon
1045 */
1046 static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
1047                           struct creds_CredentialState *creds)
1048 {
1049         int i, v, l, f;
1050         BOOL ret = True;
1051         int validation_levels[] = {2,3,6};
1052         int logon_levels[] = { 2, 6 };
1053         int function_levels[] = { 
1054                 DCERPC_NETR_LOGONSAMLOGON,
1055                 DCERPC_NETR_LOGONSAMLOGONEX,
1056                 DCERPC_NETR_LOGONSAMLOGONWITHFLAGS };
1057         struct samlogon_state samlogon_state;
1058         
1059         printf("testing netr_LogonSamLogon and netr_LogonSamLogonWithFlags\n");
1060         
1061         samlogon_state.mem_ctx = mem_ctx;
1062         samlogon_state.account_name = lp_parm_string(-1, "torture", "username");
1063         samlogon_state.account_domain = lp_parm_string(-1, "torture", "userdomain");
1064         samlogon_state.password = lp_parm_string(-1, "torture", "password");
1065         samlogon_state.p = p;
1066         samlogon_state.creds = creds;
1067
1068         samlogon_state.chall = data_blob_talloc(mem_ctx, NULL, 8);
1069
1070         generate_random_buffer(samlogon_state.chall.data, 8);
1071         samlogon_state.r_flags.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1072         samlogon_state.r_flags.in.workstation = TEST_MACHINE_NAME;
1073         samlogon_state.r_flags.in.credential = &samlogon_state.auth;
1074         samlogon_state.r_flags.in.return_authenticator = &samlogon_state.auth2;
1075         samlogon_state.r_flags.in.flags = 0;
1076
1077         samlogon_state.r_ex.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1078         samlogon_state.r_ex.in.workstation = TEST_MACHINE_NAME;
1079         samlogon_state.r_ex.in.flags = 0;
1080
1081         samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1082         samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
1083         samlogon_state.r.in.credential = &samlogon_state.auth;
1084         samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
1085
1086         for (f=0;f<ARRAY_SIZE(function_levels);f++) {
1087                 for (i=0; test_table[i].fn; i++) {
1088                         for (v=0;v<ARRAY_SIZE(validation_levels);v++) {
1089                                 for (l=0;l<ARRAY_SIZE(logon_levels);l++) {
1090                                         char *error_string = NULL;
1091                                         samlogon_state.function_level = function_levels[f];
1092                                         samlogon_state.r.in.validation_level = validation_levels[v];
1093                                         samlogon_state.r.in.logon_level = logon_levels[l];
1094                                         samlogon_state.r_ex.in.validation_level = validation_levels[v];
1095                                         samlogon_state.r_ex.in.logon_level = logon_levels[l];
1096                                         samlogon_state.r_flags.in.validation_level = validation_levels[v];
1097                                         samlogon_state.r_flags.in.logon_level = logon_levels[l];
1098                                         if (!test_table[i].fn(&samlogon_state, &error_string)) {
1099                                                 printf("Testing '%s' at validation level %d, logon level %d, function %d: \n", 
1100                                                        test_table[i].name, validation_levels[v], 
1101                                                        logon_levels[l], function_levels[f]);
1102                                                 
1103                                                 if (test_table[i].expect_fail) {
1104                                                         printf(" failed (expected, test incomplete): %s\n", error_string);
1105                                                 } else {
1106                                                         printf(" failed: %s\n", error_string);
1107                                                         ret = False;
1108                                                 }
1109                                                 SAFE_FREE(error_string);
1110                                         }
1111                                 }
1112                         }
1113                 }
1114         }
1115
1116         return ret;
1117 }
1118
1119 /*
1120   test an ADS style interactive domain logon
1121 */
1122 static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
1123                                   struct creds_CredentialState *creds)
1124 {
1125         NTSTATUS status;
1126         struct netr_LogonSamLogonWithFlags r;
1127         struct netr_Authenticator a, ra;
1128         struct netr_PasswordInfo pinfo;
1129         const char *plain_pass;
1130
1131         ZERO_STRUCT(a);
1132         ZERO_STRUCT(r);
1133         ZERO_STRUCT(ra);
1134
1135         creds_client_authenticator(creds, &a);
1136
1137         r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
1138         r.in.workstation = TEST_MACHINE_NAME;
1139         r.in.credential = &a;
1140         r.in.return_authenticator = &ra;
1141         r.in.logon_level = 5;
1142         r.in.logon.password = &pinfo;
1143         r.in.validation_level = 6;
1144         r.in.flags = 0;
1145
1146         pinfo.identity_info.domain_name.string = lp_parm_string(-1, "torture", "userdomain");
1147         pinfo.identity_info.parameter_control = 0;
1148         pinfo.identity_info.logon_id_low = 0;
1149         pinfo.identity_info.logon_id_high = 0;
1150         pinfo.identity_info.account_name.string = lp_parm_string(-1, "torture", "username");
1151         pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
1152
1153         plain_pass = lp_parm_string(-1, "torture", "password");
1154
1155         E_deshash(plain_pass, pinfo.lmpassword.hash);
1156         E_md4hash(plain_pass, pinfo.ntpassword.hash);
1157
1158         if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
1159                 creds_arcfour_crypt(creds, pinfo.lmpassword.hash, 16);
1160                 creds_arcfour_crypt(creds, pinfo.ntpassword.hash, 16);
1161         } else {
1162                 creds_des_encrypt(creds, &pinfo.lmpassword);
1163                 creds_des_encrypt(creds, &pinfo.ntpassword);
1164         }
1165
1166         printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n");
1167
1168         status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
1169         if (!NT_STATUS_IS_OK(status)) {
1170                 printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
1171                 return False;
1172         }
1173
1174         if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
1175                 printf("Credential chaining failed\n");
1176                 return False;
1177         }
1178
1179         return True;
1180 }
1181
1182
1183
1184 BOOL torture_rpc_samlogon(void)
1185 {
1186         NTSTATUS status;
1187         struct dcerpc_pipe *p;
1188         struct dcerpc_binding b;
1189         TALLOC_CTX *mem_ctx;
1190         BOOL ret = True;
1191         void *join_ctx;
1192         const char *machine_password;
1193         const char *binding = lp_parm_string(-1, "torture", "binding");
1194         int i;
1195         
1196         unsigned int credential_flags[] = {
1197                 NETLOGON_NEG_AUTH2_FLAGS,
1198                 NETLOGON_NEG_ARCFOUR,
1199                 NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT,
1200                 NETLOGON_NEG_AUTH2_ADS_FLAGS, 
1201                 0 /* yes, this is a valid flag, causes the use of DES */ 
1202         };
1203
1204         struct creds_CredentialState *creds;
1205
1206         mem_ctx = talloc_init("torture_rpc_netlogon");
1207
1208         join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST, 
1209                                        &machine_password);
1210         if (!join_ctx) {
1211                 printf("Failed to join as BDC\n");
1212                 return False;
1213         }
1214
1215         status = dcerpc_parse_binding(mem_ctx, binding, &b);
1216         if (!NT_STATUS_IS_OK(status)) {
1217                 printf("Bad binding string %s\n", binding);
1218                 ret = False;
1219                 goto failed;
1220         }
1221
1222         /* We have to use schannel, otherwise the SamLogonEx fails
1223          * with INTERNAL_ERROR */
1224
1225         b.flags &= ~DCERPC_AUTH_OPTIONS;
1226         b.flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN | DCERPC_SCHANNEL_128;
1227
1228         status = dcerpc_pipe_connect_b(&p, &b, 
1229                                        DCERPC_NETLOGON_UUID,
1230                                        DCERPC_NETLOGON_VERSION,
1231                                        lp_workgroup(), 
1232                                        TEST_MACHINE_NAME,
1233                                        machine_password);
1234
1235         if (!NT_STATUS_IS_OK(status)) {
1236                 ret = False;
1237                 goto failed;
1238         }
1239
1240         status = dcerpc_schannel_creds(p->security_state.generic_state, mem_ctx, &creds);
1241         if (!NT_STATUS_IS_OK(status)) {
1242                 ret = False;
1243                 goto failed;
1244         }
1245
1246         if (!test_InteractiveLogon(p, mem_ctx, creds)) {
1247                 ret = False;
1248         }
1249
1250         if (!test_SamLogon(p, mem_ctx, creds)) {
1251                 ret = False;
1252         }
1253
1254         for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
1255                 
1256                 if (!test_SetupCredentials2(p, mem_ctx, credential_flags[i],
1257                                             TEST_MACHINE_NAME, machine_password, creds)) {
1258                         return False;
1259                 }
1260                 
1261                 if (!test_InteractiveLogon(p, mem_ctx, creds)) {
1262                         ret = False;
1263                 }
1264                 
1265                 if (!test_SamLogon(p, mem_ctx, creds)) {
1266                         ret = False;
1267                 }
1268         }
1269
1270         for (i=0; i < 32; i++) {
1271                 if (!test_SetupCredentials2(p, mem_ctx, 1 << i,
1272                                             TEST_MACHINE_NAME, machine_password, creds)) {
1273                         return False;
1274                 }
1275                 
1276                 if (!test_InteractiveLogon(p, mem_ctx, creds)) {
1277                         ret = False;
1278                 }
1279                 
1280                 if (!test_SamLogon(p, mem_ctx, creds)) {
1281                         ret = False;
1282                 }
1283         }
1284
1285 failed:
1286         talloc_destroy(mem_ctx);
1287
1288         torture_rpc_close(p);
1289
1290         torture_leave_domain(join_ctx);
1291
1292         return ret;
1293 }