libcli:auth: Only use the required md4 header
[vlendec/samba-autobuild/.git] / libcli / auth / ntlm_check.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004
5    Copyright (C) Gerald Carter                             2003
6    Copyright (C) Luke Kenneth Casson Leighton         1996-2000
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "lib/crypto/md4.h"
24 #include "librpc/gen_ndr/netlogon.h"
25 #include "libcli/auth/libcli_auth.h"
26
27 /****************************************************************************
28  Core of smb password checking routine.
29 ****************************************************************************/
30
31 static bool smb_pwd_check_ntlmv1(TALLOC_CTX *mem_ctx,
32                                  const DATA_BLOB *nt_response,
33                                  const uint8_t *part_passwd,
34                                  const DATA_BLOB *sec_blob,
35                                  DATA_BLOB *user_sess_key)
36 {
37         /* Finish the encryption of part_passwd. */
38         uint8_t p24[24];
39
40         if (part_passwd == NULL) {
41                 DEBUG(10,("No password set - DISALLOWING access\n"));
42                 /* No password set - always false ! */
43                 return false;
44         }
45
46         if (sec_blob->length != 8) {
47                 DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", 
48                           (unsigned long)sec_blob->length));
49                 return false;
50         }
51
52         if (nt_response->length != 24) {
53                 DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", 
54                           (unsigned long)nt_response->length));
55                 return false;
56         }
57
58         SMBOWFencrypt(part_passwd, sec_blob->data, p24);
59
60 #if DEBUG_PASSWORD
61         DEBUG(100,("Part password (P16) was |\n"));
62         dump_data(100, part_passwd, 16);
63         DEBUGADD(100,("Password from client was |\n"));
64         dump_data(100, nt_response->data, nt_response->length);
65         DEBUGADD(100,("Given challenge was |\n"));
66         dump_data(100, sec_blob->data, sec_blob->length);
67         DEBUGADD(100,("Value from encryption was |\n"));
68         dump_data(100, p24, 24);
69 #endif
70         if (memcmp(p24, nt_response->data, 24) == 0) {
71                 if (user_sess_key != NULL) {
72                         *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
73                         SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
74                 }
75                 return true;
76         } 
77         return false;
78 }
79
80 /****************************************************************************
81  Core of smb password checking routine. (NTLMv2, LMv2)
82  Note:  The same code works with both NTLMv2 and LMv2.
83 ****************************************************************************/
84
85 static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx,
86                                  const DATA_BLOB *ntv2_response,
87                                  const uint8_t *part_passwd,
88                                  const DATA_BLOB *sec_blob,
89                                  const char *user, const char *domain,
90                                  DATA_BLOB *user_sess_key)
91 {
92         /* Finish the encryption of part_passwd. */
93         uint8_t kr[16];
94         uint8_t value_from_encryption[16];
95         DATA_BLOB client_key_data;
96
97         if (part_passwd == NULL) {
98                 DEBUG(10,("No password set - DISALLOWING access\n"));
99                 /* No password set - always false */
100                 return false;
101         }
102
103         if (sec_blob->length != 8) {
104                 DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", 
105                           (unsigned long)sec_blob->length));
106                 return false;
107         }
108
109         if (ntv2_response->length < 24) {
110                 /* We MUST have more than 16 bytes, or the stuff below will go
111                    crazy.  No known implementation sends less than the 24 bytes
112                    for LMv2, let alone NTLMv2. */
113                 DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", 
114                           (unsigned long)ntv2_response->length));
115                 return false;
116         }
117
118         client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
119         /* 
120            todo:  should we be checking this for anything?  We can't for LMv2, 
121            but for NTLMv2 it is meant to contain the current time etc.
122         */
123
124         if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
125                 return false;
126         }
127
128         SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
129
130 #if DEBUG_PASSWORD
131         DEBUG(100,("Part password (P16) was |\n"));
132         dump_data(100, part_passwd, 16);
133         DEBUGADD(100,("Password from client was |\n"));
134         dump_data(100, ntv2_response->data, ntv2_response->length);
135         DEBUGADD(100,("Variable data from client was |\n"));
136         dump_data(100, client_key_data.data, client_key_data.length);
137         DEBUGADD(100,("Given challenge was |\n"));
138         dump_data(100, sec_blob->data, sec_blob->length);
139         DEBUGADD(100,("Value from encryption was |\n"));
140         dump_data(100, value_from_encryption, 16);
141 #endif
142         data_blob_clear_free(&client_key_data);
143         if (memcmp(value_from_encryption, ntv2_response->data, 16) == 0) { 
144                 if (user_sess_key != NULL) {
145                         *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
146                         SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
147                 }
148                 return true;
149         }
150         return false;
151 }
152
153 /****************************************************************************
154  Core of smb password checking routine. (NTLMv2, LMv2)
155  Note:  The same code works with both NTLMv2 and LMv2.
156 ****************************************************************************/
157
158 static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx,
159                                 const DATA_BLOB *ntv2_response,
160                                 const uint8_t *part_passwd,
161                                 const DATA_BLOB *sec_blob,
162                                 const char *user, const char *domain,
163                                 DATA_BLOB *user_sess_key)
164 {
165         /* Finish the encryption of part_passwd. */
166         uint8_t kr[16];
167         uint8_t value_from_encryption[16];
168         DATA_BLOB client_key_data;
169
170         if (part_passwd == NULL) {
171                 DEBUG(10,("No password set - DISALLOWING access\n"));
172                 /* No password set - always false */
173                 return false;
174         }
175
176         if (sec_blob->length != 8) {
177                 DEBUG(0, ("smb_sess_key_ntlmv2: incorrect challenge size (%lu)\n", 
178                           (unsigned long)sec_blob->length));
179                 return false;
180         }
181
182         if (ntv2_response->length < 24) {
183                 /* We MUST have more than 16 bytes, or the stuff below will go
184                    crazy.  No known implementation sends less than the 24 bytes
185                    for LMv2, let alone NTLMv2. */
186                 DEBUG(0, ("smb_sess_key_ntlmv2: incorrect password length (%lu)\n", 
187                           (unsigned long)ntv2_response->length));
188                 return false;
189         }
190
191         client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16);
192
193         if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
194                 return false;
195         }
196
197         SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
198         *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
199         SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
200         return true;
201 }
202
203 /**
204  * Compare password hashes against those from the SAM
205  *
206  * @param mem_ctx talloc context
207  * @param client_lanman LANMAN password hash, as supplied by the client
208  * @param client_nt NT (MD4) password hash, as supplied by the client
209  * @param username internal Samba username, for log messages
210  * @param client_username username the client used
211  * @param client_domain domain name the client used (may be mapped)
212  * @param stored_lanman LANMAN password hash, as stored on the SAM
213  * @param stored_nt NT (MD4) password hash, as stored on the SAM
214  * @param user_sess_key User session key
215  * @param lm_sess_key LM session key (first 8 bytes of the LM hash)
216  */
217
218 NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
219                              bool lanman_auth,
220                              const struct samr_Password *client_lanman,
221                              const struct samr_Password *client_nt,
222                              const char *username, 
223                              const struct samr_Password *stored_lanman, 
224                              const struct samr_Password *stored_nt)
225 {
226         if (stored_nt == NULL) {
227                 DEBUG(3,("hash_password_check: NO NT password stored for user %s.\n",
228                          username));
229         }
230
231         if (client_nt && stored_nt) {
232                 if (memcmp(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash)) == 0) {
233                         return NT_STATUS_OK;
234                 } else {
235                         DEBUG(3,("hash_password_check: Interactive logon: NT password check failed for user %s\n",
236                                  username));
237                         return NT_STATUS_WRONG_PASSWORD;
238                 }
239
240         } else if (client_lanman && stored_lanman) {
241                 if (!lanman_auth) {
242                         DEBUG(3,("hash_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
243                                  username));
244                         return NT_STATUS_WRONG_PASSWORD;
245                 }
246                 if (strchr_m(username, '@')) {
247                         return NT_STATUS_NOT_FOUND;
248                 }
249
250                 if (memcmp(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash)) == 0) {
251                         return NT_STATUS_OK;
252                 } else {
253                         DEBUG(3,("hash_password_check: Interactive logon: LANMAN password check failed for user %s\n",
254                                  username));
255                         return NT_STATUS_WRONG_PASSWORD;
256                 }
257         }
258         if (strchr_m(username, '@')) {
259                 return NT_STATUS_NOT_FOUND;
260         }
261         return NT_STATUS_WRONG_PASSWORD;
262 }
263
264 /**
265  * Check a challenge-response password against the value of the NT or
266  * LM password hash.
267  *
268  * @param mem_ctx talloc context
269  * @param challenge 8-byte challenge.  If all zero, forces plaintext comparison
270  * @param nt_response 'unicode' NT response to the challenge, or unicode password
271  * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page
272  * @param username internal Samba username, for log messages
273  * @param client_username username the client used
274  * @param client_domain domain name the client used (may be mapped)
275  * @param stored_lanman LANMAN ASCII password from our passdb or similar
276  * @param stored_nt MD4 unicode password from our passdb or similar
277  * @param user_sess_key User session key
278  * @param lm_sess_key LM session key (first 8 bytes of the LM hash)
279  */
280
281 NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
282                              bool lanman_auth,
283                              enum ntlm_auth_level ntlm_auth,
284                              uint32_t logon_parameters,
285                              const DATA_BLOB *challenge,
286                              const DATA_BLOB *lm_response,
287                              const DATA_BLOB *nt_response,
288                              const char *username, 
289                              const char *client_username, 
290                              const char *client_domain,
291                              const struct samr_Password *stored_lanman, 
292                              const struct samr_Password *stored_nt, 
293                              DATA_BLOB *user_sess_key, 
294                              DATA_BLOB *lm_sess_key)
295 {
296         DATA_BLOB tmp_sess_key;
297         const char *upper_client_domain = NULL;
298
299         if (ntlm_auth == NTLM_AUTH_DISABLED) {
300                 DBG_WARNING("ntlm_password_check: NTLM authentication not "
301                             "permitted by configuration.\n");
302                 return NT_STATUS_NTLM_BLOCKED;
303         }
304
305         if (client_domain != NULL) {
306                 upper_client_domain = talloc_strdup_upper(mem_ctx, client_domain);
307                 if (upper_client_domain == NULL) {
308                         return NT_STATUS_NO_MEMORY;
309                 }
310         }
311
312         if (stored_nt == NULL) {
313                 DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", 
314                          username));
315         }
316
317         *lm_sess_key = data_blob(NULL, 0);
318         *user_sess_key = data_blob(NULL, 0);
319
320         /* Check for cleartext netlogon. Used by Exchange 5.5. */
321         if ((logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_ALLOWED)
322             && challenge->length == 8
323             && (all_zero(challenge->data, challenge->length))) {
324                 struct samr_Password client_nt;
325                 struct samr_Password client_lm;
326                 char *unix_pw = NULL;
327                 bool lm_ok;
328                 size_t converted_size = 0;
329
330                 DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n",
331                          username));
332                 mdfour(client_nt.hash, nt_response->data, nt_response->length);
333
334                 if (lm_response->length && 
335                     (convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, 
336                                           lm_response->data, lm_response->length, 
337                                            (void *)&unix_pw, &converted_size))) {
338                         if (E_deshash(unix_pw, client_lm.hash)) {
339                                 lm_ok = true;
340                         } else {
341                                 lm_ok = false;
342                         }
343                 } else {
344                         lm_ok = false;
345                 }
346                 return hash_password_check(mem_ctx, 
347                                            lanman_auth,
348                                            lm_ok ? &client_lm : NULL, 
349                                            nt_response->length ? &client_nt : NULL, 
350                                            username,  
351                                            stored_lanman, stored_nt);
352         }
353
354         if (nt_response->length != 0 && nt_response->length < 24) {
355                 DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", 
356                          (unsigned long)nt_response->length, username));                
357         }
358
359         if (nt_response->length > 24 && stored_nt) {
360                 /* We have the NT MD4 hash challenge available - see if we can
361                    use it 
362                 */
363                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n",
364                         client_domain ? client_domain : "<NULL>"));
365                 if (smb_pwd_check_ntlmv2(mem_ctx,
366                                          nt_response, 
367                                          stored_nt->hash, challenge, 
368                                          client_username, 
369                                          client_domain,
370                                          user_sess_key)) {
371                         if (user_sess_key->length) {
372                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
373                         }
374                         return NT_STATUS_OK;
375                 }
376
377                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n",
378                         upper_client_domain ? upper_client_domain : "<NULL>"));
379                 if (smb_pwd_check_ntlmv2(mem_ctx,
380                                          nt_response, 
381                                          stored_nt->hash, challenge, 
382                                          client_username, 
383                                          upper_client_domain,
384                                          user_sess_key)) {
385                         if (user_sess_key->length) {
386                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
387                         }
388                         return NT_STATUS_OK;
389                 }
390
391                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n"));
392                 if (smb_pwd_check_ntlmv2(mem_ctx,
393                                          nt_response, 
394                                          stored_nt->hash, challenge, 
395                                          client_username, 
396                                          "",
397                                          user_sess_key)) {
398                         if (user_sess_key->length) {
399                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
400                         }
401                         return NT_STATUS_OK;
402                 } else {
403                         DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n"));
404                 }
405         } else if (nt_response->length == 24 && stored_nt) {
406                 if (ntlm_auth == NTLM_AUTH_ON
407                     || (ntlm_auth == NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY && (logon_parameters & MSV1_0_ALLOW_MSVCHAPV2))) {
408                         /* We have the NT MD4 hash challenge available - see if we can
409                            use it (ie. does it exist in the smbpasswd file).
410                         */
411                         DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n"));
412                         if (smb_pwd_check_ntlmv1(mem_ctx, 
413                                                  nt_response, 
414                                                  stored_nt->hash, challenge,
415                                                  user_sess_key)) {
416                                 /* The LM session key for this response is not very secure, 
417                                    so use it only if we otherwise allow LM authentication */
418
419                                 if (lanman_auth && stored_lanman) {
420                                         *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, MIN(8, user_sess_key->length));
421                                 }
422                                 return NT_STATUS_OK;
423                         } else {
424                                 DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n",
425                                          username));
426                                 return NT_STATUS_WRONG_PASSWORD;
427                         }
428                 } else {
429                         DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n",
430                                  username));                    
431                         /* no return, because we might pick up LMv2 in the LM field */
432                 }
433         }
434
435         if (lm_response->length == 0) {
436                 DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n",
437                          username));
438                 return NT_STATUS_WRONG_PASSWORD;
439         }
440
441         if (lm_response->length < 24) {
442                 DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", 
443                          (unsigned long)nt_response->length, username));                
444                 return NT_STATUS_WRONG_PASSWORD;
445         }
446
447         if (!lanman_auth) {
448                 DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n",
449                          username));
450         } else if (!stored_lanman) {
451                 DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n",
452                          username));
453         } else if (strchr_m(username, '@')) {
454                 DEBUG(3,("ntlm_password_check: NO LanMan password allowed for username@realm logins (user: %s)\n",
455                          username));
456         } else {
457                 DEBUG(4,("ntlm_password_check: Checking LM password\n"));
458                 if (smb_pwd_check_ntlmv1(mem_ctx,
459                                          lm_response, 
460                                          stored_lanman->hash, challenge,
461                                          NULL)) {
462                         /* The session key for this response is still very odd.  
463                            It not very secure, so use it only if we otherwise 
464                            allow LM authentication */
465
466                         if (lanman_auth && stored_lanman) {
467                                 uint8_t first_8_lm_hash[16];
468                                 memcpy(first_8_lm_hash, stored_lanman->hash, 8);
469                                 memset(first_8_lm_hash + 8, '\0', 8);
470                                 *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
471                                 *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
472                         }
473                         return NT_STATUS_OK;
474                 }
475         }
476
477         if (!stored_nt) {
478                 DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username));
479                 return NT_STATUS_WRONG_PASSWORD;
480         }
481
482         /* This is for 'LMv2' authentication.  almost NTLMv2 but limited to 24 bytes.
483            - related to Win9X, legacy NAS pass-though authentication
484         */
485         DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n",
486                 client_domain ? client_domain : "<NULL>"));
487         if (smb_pwd_check_ntlmv2(mem_ctx,
488                                  lm_response, 
489                                  stored_nt->hash, challenge, 
490                                  client_username,
491                                  client_domain,
492                                  &tmp_sess_key)) {
493                 if (nt_response->length > 24) {
494                         /* If NTLMv2 authentication has preceded us
495                          * (even if it failed), then use the session
496                          * key from that.  See the RPC-SAMLOGON
497                          * torture test */
498                         smb_sess_key_ntlmv2(mem_ctx,
499                                             nt_response, 
500                                             stored_nt->hash, challenge, 
501                                             client_username,
502                                             client_domain,
503                                             user_sess_key);
504                 } else {
505                         /* Otherwise, use the LMv2 session key */
506                         *user_sess_key = tmp_sess_key;
507                 }
508                 if (user_sess_key->length) {
509                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
510                 }
511                 return NT_STATUS_OK;
512         }
513
514         DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n",
515                 upper_client_domain ? upper_client_domain : "<NULL>"));
516         if (smb_pwd_check_ntlmv2(mem_ctx,
517                                  lm_response, 
518                                  stored_nt->hash, challenge, 
519                                  client_username,
520                                  upper_client_domain,
521                                  &tmp_sess_key)) {
522                 if (nt_response->length > 24) {
523                         /* If NTLMv2 authentication has preceded us
524                          * (even if it failed), then use the session
525                          * key from that.  See the RPC-SAMLOGON
526                          * torture test */
527                         smb_sess_key_ntlmv2(mem_ctx,
528                                             nt_response, 
529                                             stored_nt->hash, challenge, 
530                                             client_username,
531                                             upper_client_domain,
532                                             user_sess_key);
533                 } else {
534                         /* Otherwise, use the LMv2 session key */
535                         *user_sess_key = tmp_sess_key;
536                 }
537                 if (user_sess_key->length) {
538                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
539                 }
540                 return NT_STATUS_OK;
541         }
542
543         DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n"));
544         if (smb_pwd_check_ntlmv2(mem_ctx,
545                                  lm_response, 
546                                  stored_nt->hash, challenge, 
547                                  client_username,
548                                  "",
549                                  &tmp_sess_key)) {
550                 if (nt_response->length > 24) {
551                         /* If NTLMv2 authentication has preceded us
552                          * (even if it failed), then use the session
553                          * key from that.  See the RPC-SAMLOGON
554                          * torture test */
555                         smb_sess_key_ntlmv2(mem_ctx,
556                                             nt_response, 
557                                             stored_nt->hash, challenge, 
558                                             client_username,
559                                             "",
560                                             user_sess_key);
561                 } else {
562                         /* Otherwise, use the LMv2 session key */
563                         *user_sess_key = tmp_sess_key;
564                 }
565                 if (user_sess_key->length) {
566                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
567                 }
568                 return NT_STATUS_OK;
569         }
570
571         /* Apparently NT accepts NT responses in the LM field
572            - I think this is related to Win9X pass-though authentication
573         */
574         DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n"));
575         if (ntlm_auth == NTLM_AUTH_ON) {
576                 if (smb_pwd_check_ntlmv1(mem_ctx, 
577                                          lm_response, 
578                                          stored_nt->hash, challenge,
579                                          NULL)) {
580                         /* The session key for this response is still very odd.  
581                            It not very secure, so use it only if we otherwise 
582                            allow LM authentication */
583
584                         if (lanman_auth && stored_lanman) {
585                                 uint8_t first_8_lm_hash[16];
586                                 memcpy(first_8_lm_hash, stored_lanman->hash, 8);
587                                 memset(first_8_lm_hash + 8, '\0', 8);
588                                 *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
589                                 *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
590                         }
591                         return NT_STATUS_OK;
592                 }
593                 DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username));
594         } else {
595                 DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username));
596         }
597
598         /* Try and match error codes */
599         if (strchr_m(username, '@')) {
600                 return NT_STATUS_NOT_FOUND;
601         }
602         return NT_STATUS_WRONG_PASSWORD;
603 }
604