root/source4/auth/ntlm/ntlm_check.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smb_pwd_check_ntlmv1
  2. smb_pwd_check_ntlmv2
  3. smb_sess_key_ntlmv2
  4. hash_password_check
  5. ntlm_password_check

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

/* [<][>][^][v][top][bottom][index][help] */