Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Winbind status program.
5 :
6 : Copyright (C) Tim Potter 2000-2003
7 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
8 : Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000
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 3 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, see <http://www.gnu.org/licenses/>.
22 : */
23 :
24 : #include "includes.h"
25 : #include "utils/ntlm_auth.h"
26 : #include "../libcli/auth/libcli_auth.h"
27 : #include "nsswitch/winbind_client.h"
28 :
29 : #undef DBGC_CLASS
30 : #define DBGC_CLASS DBGC_WINBIND
31 :
32 : enum ntlm_break {
33 : BREAK_NONE,
34 : BREAK_LM,
35 : BREAK_NT,
36 : NO_LM,
37 : NO_NT
38 : };
39 :
40 : /*
41 : Authenticate a user with a challenge/response, checking session key
42 : and valid authentication types
43 : */
44 :
45 : /*
46 : * Test the normal 'LM and NTLM' combination
47 : */
48 :
49 100 : static bool test_lm_ntlm_broken(enum ntlm_break break_which,
50 : bool lanman_support_expected)
51 : {
52 100 : bool pass = True;
53 : NTSTATUS nt_status;
54 100 : uint32_t flags = 0;
55 100 : DATA_BLOB lm_response = data_blob(NULL, 24);
56 100 : DATA_BLOB nt_response = data_blob(NULL, 24);
57 100 : DATA_BLOB session_key = data_blob(NULL, 16);
58 100 : uint8_t authoritative = 1;
59 : uchar lm_key[8];
60 : uchar user_session_key[16];
61 : uchar lm_hash[16];
62 : uchar nt_hash[16];
63 100 : DATA_BLOB chall = get_challenge();
64 : char *error_string;
65 :
66 100 : ZERO_STRUCT(lm_key);
67 100 : ZERO_STRUCT(user_session_key);
68 :
69 100 : flags |= WBFLAG_PAM_LMKEY;
70 100 : flags |= WBFLAG_PAM_USER_SESSION_KEY;
71 :
72 100 : SMBencrypt(opt_password,chall.data,lm_response.data);
73 100 : E_deshash(opt_password, lm_hash);
74 :
75 100 : SMBNTencrypt(opt_password,chall.data,nt_response.data);
76 :
77 100 : E_md4hash(opt_password, nt_hash);
78 100 : SMBsesskeygen_ntv1(nt_hash, session_key.data);
79 :
80 100 : switch (break_which) {
81 20 : case BREAK_NONE:
82 20 : break;
83 20 : case BREAK_LM:
84 20 : lm_response.data[0]++;
85 20 : break;
86 20 : case BREAK_NT:
87 20 : nt_response.data[0]++;
88 20 : break;
89 20 : case NO_LM:
90 20 : data_blob_free(&lm_response);
91 20 : break;
92 20 : case NO_NT:
93 20 : data_blob_free(&nt_response);
94 20 : break;
95 : }
96 :
97 100 : nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
98 : opt_workstation,
99 : &chall,
100 : &lm_response,
101 : &nt_response,
102 : flags, 0,
103 : lm_key,
104 : user_session_key,
105 : &authoritative,
106 : &error_string, NULL);
107 :
108 100 : data_blob_free(&lm_response);
109 :
110 100 : if (!NT_STATUS_IS_OK(nt_status)) {
111 32 : d_printf("%s (0x%x)\n",
112 : error_string,
113 : NT_STATUS_V(nt_status));
114 32 : SAFE_FREE(error_string);
115 32 : return break_which == BREAK_NT;
116 : }
117 :
118 : /* If we are told the DC is Samba4, expect an LM key of zeros */
119 68 : if (!lanman_support_expected) {
120 34 : if (!all_zero(lm_key,
121 : sizeof(lm_key))) {
122 16 : DEBUG(1, ("LM Key does not match expectations!\n"));
123 16 : DEBUG(1, ("lm_key:\n"));
124 16 : dump_data(1, lm_key, 8);
125 16 : DEBUG(1, ("expected: all zeros\n"));
126 16 : pass = False;
127 : }
128 : } else {
129 34 : if (memcmp(lm_hash, lm_key,
130 : sizeof(lm_key)) != 0) {
131 18 : DEBUG(1, ("LM Key does not match expectations!\n"));
132 18 : DEBUG(1, ("lm_key:\n"));
133 18 : dump_data(1, lm_key, 8);
134 18 : DEBUG(1, ("expected:\n"));
135 18 : dump_data(1, lm_hash, 8);
136 18 : pass = False;
137 : }
138 : }
139 :
140 68 : if (break_which == NO_NT) {
141 8 : if (memcmp(lm_hash, user_session_key,
142 : 8) != 0) {
143 0 : DEBUG(1, ("NT Session Key does not match expectations (should be LM hash)!\n"));
144 0 : DEBUG(1, ("user_session_key:\n"));
145 0 : dump_data(1, user_session_key, sizeof(user_session_key));
146 0 : DEBUG(1, ("expected:\n"));
147 0 : dump_data(1, lm_hash, sizeof(lm_hash));
148 0 : pass = False;
149 : }
150 : } else {
151 60 : if (memcmp(session_key.data, user_session_key,
152 : sizeof(user_session_key)) != 0) {
153 0 : DEBUG(1, ("NT Session Key does not match expectations!\n"));
154 0 : DEBUG(1, ("user_session_key:\n"));
155 0 : dump_data(1, user_session_key, 16);
156 0 : DEBUG(1, ("expected:\n"));
157 0 : dump_data(1, session_key.data, session_key.length);
158 0 : pass = False;
159 : }
160 : }
161 68 : return pass;
162 : }
163 :
164 : /*
165 : * Test LM authentication, no NT response supplied
166 : */
167 :
168 20 : static bool test_lm(bool lanman_support_expected)
169 : {
170 :
171 20 : return test_lm_ntlm_broken(NO_NT, lanman_support_expected);
172 : }
173 :
174 : /*
175 : * Test the NTLM response only, no LM.
176 : */
177 :
178 20 : static bool test_ntlm(bool lanman_support_expected)
179 : {
180 20 : return test_lm_ntlm_broken(NO_LM, lanman_support_expected);
181 : }
182 :
183 : /*
184 : * Test the NTLM response only, but in the LM field.
185 : */
186 :
187 20 : static bool test_ntlm_in_lm(bool lanman_support_expected)
188 : {
189 20 : bool pass = True;
190 : NTSTATUS nt_status;
191 20 : uint32_t flags = 0;
192 20 : DATA_BLOB nt_response = data_blob(NULL, 24);
193 20 : uint8_t authoritative = 1;
194 : uchar lm_key[8];
195 : uchar lm_hash[16];
196 : uchar user_session_key[16];
197 20 : DATA_BLOB chall = get_challenge();
198 : char *error_string;
199 :
200 20 : ZERO_STRUCT(user_session_key);
201 :
202 20 : flags |= WBFLAG_PAM_LMKEY;
203 20 : flags |= WBFLAG_PAM_USER_SESSION_KEY;
204 :
205 20 : SMBNTencrypt(opt_password,chall.data,nt_response.data);
206 :
207 20 : E_deshash(opt_password, lm_hash);
208 :
209 20 : nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
210 : opt_workstation,
211 : &chall,
212 : &nt_response,
213 : NULL,
214 : flags, 0,
215 : lm_key,
216 : user_session_key,
217 : &authoritative,
218 : &error_string, NULL);
219 :
220 20 : data_blob_free(&nt_response);
221 :
222 20 : if (!NT_STATUS_IS_OK(nt_status)) {
223 0 : d_printf("%s (0x%x)\n",
224 : error_string,
225 : NT_STATUS_V(nt_status));
226 0 : SAFE_FREE(error_string);
227 0 : return False;
228 : }
229 :
230 : /* If we are told the DC is Samba4, expect an LM key of zeros */
231 20 : if (!lanman_support_expected) {
232 10 : if (!all_zero(lm_key,
233 : sizeof(lm_key))) {
234 4 : DEBUG(1, ("LM Key does not match expectations!\n"));
235 4 : DEBUG(1, ("lm_key:\n"));
236 4 : dump_data(1, lm_key, 8);
237 4 : DEBUG(1, ("expected: all zeros\n"));
238 4 : pass = False;
239 : }
240 10 : if (!all_zero(user_session_key,
241 : sizeof(user_session_key))) {
242 4 : DEBUG(1, ("Session Key (normally first 8 lm hash) does not match expectations!\n"));
243 4 : DEBUG(1, ("user_session_key:\n"));
244 4 : dump_data(1, user_session_key, 16);
245 4 : DEBUG(1, ("expected all zeros:\n"));
246 4 : pass = False;
247 : }
248 : } else {
249 10 : if (memcmp(lm_hash, lm_key,
250 : sizeof(lm_key)) != 0) {
251 6 : DEBUG(1, ("LM Key does not match expectations!\n"));
252 6 : DEBUG(1, ("lm_key:\n"));
253 6 : dump_data(1, lm_key, 8);
254 6 : DEBUG(1, ("expected:\n"));
255 6 : dump_data(1, lm_hash, 8);
256 6 : pass = False;
257 : }
258 10 : if (memcmp(lm_hash, user_session_key, 8) != 0) {
259 6 : DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n"));
260 6 : DEBUG(1, ("user_session_key:\n"));
261 6 : dump_data(1, user_session_key, 16);
262 6 : DEBUG(1, ("expected:\n"));
263 6 : dump_data(1, lm_hash, 8);
264 6 : pass = False;
265 : }
266 : }
267 20 : return pass;
268 : }
269 :
270 : /*
271 : * Test the NTLM response only, but in the both the NT and LM fields.
272 : */
273 :
274 20 : static bool test_ntlm_in_both(bool lanman_support_expected)
275 : {
276 20 : bool pass = True;
277 : NTSTATUS nt_status;
278 20 : uint32_t flags = 0;
279 20 : DATA_BLOB nt_response = data_blob(NULL, 24);
280 20 : DATA_BLOB session_key = data_blob(NULL, 16);
281 20 : uint8_t authoritative = 1;
282 : uint8_t lm_key[8];
283 : uint8_t lm_hash[16];
284 : uint8_t user_session_key[16];
285 : uint8_t nt_hash[16];
286 20 : DATA_BLOB chall = get_challenge();
287 : char *error_string;
288 :
289 20 : ZERO_STRUCT(lm_key);
290 20 : ZERO_STRUCT(user_session_key);
291 :
292 20 : flags |= WBFLAG_PAM_LMKEY;
293 20 : flags |= WBFLAG_PAM_USER_SESSION_KEY;
294 :
295 20 : SMBNTencrypt(opt_password,chall.data,nt_response.data);
296 20 : E_md4hash(opt_password, nt_hash);
297 20 : SMBsesskeygen_ntv1(nt_hash, session_key.data);
298 :
299 20 : E_deshash(opt_password, lm_hash);
300 :
301 20 : nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
302 : opt_workstation,
303 : &chall,
304 : &nt_response,
305 : &nt_response,
306 : flags, 0,
307 : lm_key,
308 : user_session_key,
309 : &authoritative,
310 : &error_string, NULL);
311 :
312 20 : data_blob_free(&nt_response);
313 :
314 20 : if (!NT_STATUS_IS_OK(nt_status)) {
315 0 : d_printf("%s (0x%x)\n",
316 : error_string,
317 : NT_STATUS_V(nt_status));
318 0 : SAFE_FREE(error_string);
319 0 : return False;
320 : }
321 :
322 : /* If we are told the DC is Samba4, expect an LM key of zeros */
323 20 : if (!lanman_support_expected) {
324 10 : if (!all_zero(lm_key,
325 : sizeof(lm_key))) {
326 4 : DEBUG(1, ("LM Key does not match expectations!\n"));
327 4 : DEBUG(1, ("lm_key:\n"));
328 4 : dump_data(1, lm_key, 8);
329 4 : DEBUG(1, ("expected: all zeros\n"));
330 4 : pass = False;
331 : }
332 : } else {
333 10 : if (memcmp(lm_hash, lm_key,
334 : sizeof(lm_key)) != 0) {
335 6 : DEBUG(1, ("LM Key does not match expectations!\n"));
336 6 : DEBUG(1, ("lm_key:\n"));
337 6 : dump_data(1, lm_key, 8);
338 6 : DEBUG(1, ("expected:\n"));
339 6 : dump_data(1, lm_hash, 8);
340 6 : pass = False;
341 : }
342 : }
343 20 : if (memcmp(session_key.data, user_session_key,
344 : sizeof(user_session_key)) != 0) {
345 0 : DEBUG(1, ("NT Session Key does not match expectations!\n"));
346 0 : DEBUG(1, ("user_session_key:\n"));
347 0 : dump_data(1, user_session_key, 16);
348 0 : DEBUG(1, ("expected:\n"));
349 0 : dump_data(1, session_key.data, session_key.length);
350 0 : pass = False;
351 : }
352 :
353 :
354 20 : return pass;
355 : }
356 :
357 : /*
358 : * Test the NTLMv2 and LMv2 responses
359 : */
360 :
361 100 : static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
362 : {
363 100 : bool pass = True;
364 : NTSTATUS nt_status;
365 100 : uint32_t flags = 0;
366 100 : DATA_BLOB ntlmv2_response = data_blob_null;
367 100 : DATA_BLOB lmv2_response = data_blob_null;
368 100 : DATA_BLOB ntlmv2_session_key = data_blob_null;
369 100 : DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain());
370 100 : uint8_t authoritative = 1;
371 : uchar user_session_key[16];
372 100 : DATA_BLOB chall = get_challenge();
373 : char *error_string;
374 :
375 100 : ZERO_STRUCT(user_session_key);
376 :
377 100 : flags |= WBFLAG_PAM_USER_SESSION_KEY;
378 :
379 100 : if (!SMBNTLMv2encrypt(NULL, opt_username, opt_domain, opt_password, &chall,
380 : &names_blob,
381 : &lmv2_response, &ntlmv2_response, NULL,
382 : &ntlmv2_session_key)) {
383 0 : data_blob_free(&names_blob);
384 0 : return False;
385 : }
386 100 : data_blob_free(&names_blob);
387 :
388 100 : switch (break_which) {
389 20 : case BREAK_NONE:
390 20 : break;
391 20 : case BREAK_LM:
392 20 : lmv2_response.data[0]++;
393 20 : break;
394 20 : case BREAK_NT:
395 20 : ntlmv2_response.data[0]++;
396 20 : break;
397 20 : case NO_LM:
398 20 : data_blob_free(&lmv2_response);
399 20 : break;
400 20 : case NO_NT:
401 20 : data_blob_free(&ntlmv2_response);
402 20 : break;
403 : }
404 :
405 100 : nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
406 : opt_workstation,
407 : &chall,
408 : &lmv2_response,
409 : &ntlmv2_response,
410 : flags, 0,
411 : NULL,
412 : user_session_key,
413 : &authoritative,
414 : &error_string, NULL);
415 :
416 100 : data_blob_free(&lmv2_response);
417 100 : data_blob_free(&ntlmv2_response);
418 :
419 100 : if (!NT_STATUS_IS_OK(nt_status)) {
420 0 : d_printf("%s (0x%x)\n",
421 : error_string,
422 : NT_STATUS_V(nt_status));
423 0 : SAFE_FREE(error_string);
424 0 : return break_which == BREAK_NT;
425 : }
426 :
427 100 : if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key,
428 : sizeof(user_session_key)) != 0) {
429 0 : DEBUG(1, ("USER (NTLMv2) Session Key does not match expectations!\n"));
430 0 : DEBUG(1, ("user_session_key:\n"));
431 0 : dump_data(1, user_session_key, 16);
432 0 : DEBUG(1, ("expected:\n"));
433 0 : dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
434 0 : pass = False;
435 : }
436 100 : return pass;
437 : }
438 :
439 : /*
440 : * Test the NTLMv2 and LMv2 responses
441 : */
442 :
443 20 : static bool test_lmv2_ntlmv2(bool lanman_support_expected)
444 : {
445 20 : return test_lmv2_ntlmv2_broken(BREAK_NONE);
446 : }
447 :
448 : /*
449 : * Test the LMv2 response only
450 : */
451 :
452 20 : static bool test_lmv2(bool lanman_support_expected)
453 : {
454 20 : return test_lmv2_ntlmv2_broken(NO_NT);
455 : }
456 :
457 : /*
458 : * Test the NTLMv2 response only
459 : */
460 :
461 20 : static bool test_ntlmv2(bool lanman_support_expected)
462 : {
463 20 : return test_lmv2_ntlmv2_broken(NO_LM);
464 : }
465 :
466 20 : static bool test_lm_ntlm(bool lanman_support_expected)
467 : {
468 20 : return test_lm_ntlm_broken(BREAK_NONE, lanman_support_expected);
469 : }
470 :
471 20 : static bool test_ntlm_lm_broken(bool lanman_support_expected)
472 : {
473 20 : return test_lm_ntlm_broken(BREAK_LM, lanman_support_expected);
474 : }
475 :
476 20 : static bool test_ntlm_ntlm_broken(bool lanman_support_expected)
477 : {
478 20 : return test_lm_ntlm_broken(BREAK_NT, lanman_support_expected);
479 : }
480 :
481 20 : static bool test_ntlmv2_lmv2_broken(bool lanman_support_expected)
482 : {
483 20 : return test_lmv2_ntlmv2_broken(BREAK_LM);
484 : }
485 :
486 20 : static bool test_ntlmv2_ntlmv2_broken(bool lanman_support_expected)
487 : {
488 20 : return test_lmv2_ntlmv2_broken(BREAK_NT);
489 : }
490 :
491 100 : static bool test_plaintext(enum ntlm_break break_which)
492 : {
493 : NTSTATUS nt_status;
494 100 : uint32_t flags = 0;
495 100 : DATA_BLOB nt_response = data_blob_null;
496 100 : DATA_BLOB lm_response = data_blob_null;
497 : char *password;
498 : smb_ucs2_t *nt_response_ucs2;
499 : size_t converted_size;
500 100 : uint8_t authoritative = 1;
501 : uchar user_session_key[16];
502 : uchar lm_key[16];
503 : static const uchar zeros[8] = { 0, };
504 100 : DATA_BLOB chall = data_blob(zeros, sizeof(zeros));
505 : char *error_string;
506 :
507 100 : ZERO_STRUCT(user_session_key);
508 :
509 100 : flags |= WBFLAG_PAM_LMKEY;
510 100 : flags |= WBFLAG_PAM_USER_SESSION_KEY;
511 :
512 100 : if (!push_ucs2_talloc(talloc_tos(), &nt_response_ucs2, opt_password,
513 : &converted_size))
514 : {
515 0 : DEBUG(0, ("push_ucs2_talloc failed!\n"));
516 0 : exit(1);
517 : }
518 :
519 100 : nt_response.data = (unsigned char *)nt_response_ucs2;
520 100 : nt_response.length = strlen_w(nt_response_ucs2)*sizeof(smb_ucs2_t);
521 :
522 100 : if ((password = strupper_talloc(talloc_tos(), opt_password)) == NULL) {
523 0 : DEBUG(0, ("strupper_talloc() failed!\n"));
524 0 : exit(1);
525 : }
526 :
527 100 : if (!convert_string_talloc(talloc_tos(), CH_UNIX,
528 : CH_DOS, password,
529 100 : strlen(password)+1,
530 : &lm_response.data,
531 : &lm_response.length)) {
532 0 : DEBUG(0, ("convert_string_talloc failed!\n"));
533 0 : exit(1);
534 : }
535 :
536 100 : TALLOC_FREE(password);
537 :
538 100 : switch (break_which) {
539 20 : case BREAK_NONE:
540 20 : break;
541 20 : case BREAK_LM:
542 20 : lm_response.data[0]++;
543 20 : break;
544 20 : case BREAK_NT:
545 20 : nt_response.data[0]++;
546 20 : break;
547 20 : case NO_LM:
548 20 : TALLOC_FREE(lm_response.data);
549 20 : lm_response.length = 0;
550 20 : break;
551 20 : case NO_NT:
552 20 : TALLOC_FREE(nt_response.data);
553 20 : nt_response.length = 0;
554 20 : break;
555 : }
556 :
557 100 : nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
558 : opt_workstation,
559 : &chall,
560 : &lm_response,
561 : &nt_response,
562 : flags, MSV1_0_CLEARTEXT_PASSWORD_ALLOWED,
563 : lm_key,
564 : user_session_key,
565 : &authoritative,
566 : &error_string, NULL);
567 :
568 100 : TALLOC_FREE(nt_response.data);
569 100 : TALLOC_FREE(lm_response.data);
570 100 : data_blob_free(&chall);
571 :
572 100 : if (!NT_STATUS_IS_OK(nt_status)) {
573 32 : d_printf("%s (0x%x)\n",
574 : error_string,
575 : NT_STATUS_V(nt_status));
576 32 : SAFE_FREE(error_string);
577 32 : return break_which == BREAK_NT;
578 : }
579 :
580 68 : return break_which != BREAK_NT;
581 : }
582 :
583 20 : static bool test_plaintext_none_broken(bool lanman_support_expected) {
584 20 : return test_plaintext(BREAK_NONE);
585 : }
586 :
587 20 : static bool test_plaintext_lm_broken(bool lanman_support_expected) {
588 20 : return test_plaintext(BREAK_LM);
589 : }
590 :
591 20 : static bool test_plaintext_nt_broken(bool lanman_support_expected) {
592 20 : return test_plaintext(BREAK_NT);
593 : }
594 :
595 20 : static bool test_plaintext_nt_only(bool lanman_support_expected) {
596 20 : return test_plaintext(NO_LM);
597 : }
598 :
599 20 : static bool test_plaintext_lm_only(bool lanman_support_expected) {
600 20 : return test_plaintext(NO_NT);
601 : }
602 :
603 : /*
604 : Tests:
605 :
606 : - LM only
607 : - NT and LM
608 : - NT
609 : - NT in LM field
610 : - NT in both fields
611 : - NTLMv2
612 : - NTLMv2 and LMv2
613 : - LMv2
614 : - plaintext tests (in challenge-response fields)
615 :
616 : check we get the correct session key in each case
617 : check what values we get for the LM session key
618 :
619 : */
620 :
621 : static const struct ntlm_tests {
622 : bool (*fn)(bool lanman_support_expected);
623 : const char *name;
624 : bool lanman;
625 : } test_table[] = {
626 : {
627 : .fn = test_lm,
628 : .name = "LM",
629 : .lanman = true
630 : },
631 : {
632 : .fn = test_lm_ntlm,
633 : .name = "LM and NTLM"
634 : },
635 : {
636 : .fn = test_ntlm,
637 : .name = "NTLM"
638 : },
639 : {
640 : .fn = test_ntlm_in_lm,
641 : .name = "NTLM in LM"
642 : },
643 : {
644 : .fn = test_ntlm_in_both,
645 : .name = "NTLM in both"
646 : },
647 : {
648 : .fn = test_ntlmv2,
649 : .name = "NTLMv2"
650 : },
651 : {
652 : .fn = test_lmv2_ntlmv2,
653 : .name = "NTLMv2 and LMv2"
654 : },
655 : {
656 : .fn = test_lmv2,
657 : .name = "LMv2"
658 : },
659 : {
660 : .fn = test_ntlmv2_lmv2_broken,
661 : .name = "NTLMv2 and LMv2, LMv2 broken"
662 : },
663 : {
664 : .fn = test_ntlmv2_ntlmv2_broken,
665 : .name = "NTLMv2 and LMv2, NTLMv2 broken"
666 : },
667 : {
668 : .fn = test_ntlm_lm_broken,
669 : .name = "NTLM and LM, LM broken"
670 : },
671 : {
672 : .fn = test_ntlm_ntlm_broken,
673 : .name = "NTLM and LM, NTLM broken"
674 : },
675 : {
676 : .fn = test_plaintext_none_broken,
677 : .name = "Plaintext"
678 : },
679 : {
680 : .fn = test_plaintext_lm_broken,
681 : .name = "Plaintext LM broken"
682 : },
683 : {
684 : .fn = test_plaintext_nt_broken,
685 : .name = "Plaintext NT broken"
686 : },
687 : {
688 : .fn = test_plaintext_nt_only,
689 : .name = "Plaintext NT only"
690 : },
691 : {
692 : .fn = test_plaintext_lm_only,
693 : .name = "Plaintext LM only",
694 : .lanman = true
695 : },
696 : {
697 : .fn = NULL
698 : }
699 : };
700 :
701 20 : bool diagnose_ntlm_auth(bool lanman_support_expected)
702 : {
703 : unsigned int i;
704 20 : bool pass = True;
705 :
706 360 : for (i=0; test_table[i].fn; i++) {
707 340 : bool test_pass = test_table[i].fn(lanman_support_expected);
708 340 : if (!lanman_support_expected
709 170 : && test_table[i].lanman) {
710 20 : if (test_pass) {
711 4 : DBG_ERR("Test %s unexpectedly passed "
712 : "(server should have rejected LM)!\n",
713 : test_table[i].name);
714 4 : pass = false;
715 : }
716 320 : } else if (!test_pass) {
717 62 : DBG_ERR("Test %s failed!\n", test_table[i].name);
718 62 : pass = False;
719 : }
720 : }
721 :
722 20 : return pass;
723 : }
724 :
|