LCOV - code coverage report
Current view: top level - libcli/auth - ntlm_check.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 194 268 72.4 %
Date: 2024-02-28 12:06:22 Functions: 5 5 100.0 %

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

Generated by: LCOV version 1.14