LCOV - code coverage report
Current view: top level - libcli/auth - ntlm_check.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 173 247 70.0 %
Date: 2024-06-13 04:01:37 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        4997 : 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             :         int rc;
      40             :         bool ok;
      41             : 
      42        4997 :         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        4997 :         if (sec_blob->length != 8) {
      49           0 :                 DBG_ERR("incorrect challenge size (%zu)\n", sec_blob->length);
      50           0 :                 return false;
      51             :         }
      52             : 
      53        4997 :         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        4997 :         rc = SMBOWFencrypt(part_passwd, sec_blob->data, p24);
      60        4997 :         if (rc != 0) {
      61           0 :                 return false;
      62             :         }
      63             : 
      64             : #if DEBUG_PASSWORD
      65        4997 :         DEBUG(100,("Part password (P16) was |\n"));
      66        4997 :         dump_data(100, part_passwd, 16);
      67        4997 :         DEBUGADD(100,("Password from client was |\n"));
      68        4997 :         dump_data(100, nt_response->data, nt_response->length);
      69        4997 :         DEBUGADD(100,("Given challenge was |\n"));
      70        4997 :         dump_data(100, sec_blob->data, sec_blob->length);
      71        4997 :         DEBUGADD(100,("Value from encryption was |\n"));
      72        4997 :         dump_data(100, p24, 24);
      73             : #endif
      74        4997 :         ok = mem_equal_const_time(p24, nt_response->data, 24);
      75        4997 :         if (!ok) {
      76        3124 :                 return false;
      77             :         }
      78        1873 :         if (user_sess_key != NULL) {
      79        1669 :                 *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
      80        1669 :                 if (user_sess_key->data == NULL) {
      81           0 :                         DBG_ERR("data_blob_talloc failed\n");
      82           0 :                         return false;
      83             :                 }
      84        1669 :                 SMBsesskeygen_ntv1(part_passwd, user_sess_key->data);
      85             :         }
      86        1873 :         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       23946 : 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             :         uint8_t kr[16];
     103             :         uint8_t value_from_encryption[16];
     104             :         DATA_BLOB client_key_data;
     105             :         NTSTATUS status;
     106             :         bool ok;
     107             : 
     108       23946 :         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       23946 :         if (sec_blob->length != 8) {
     115           0 :                 DBG_ERR("incorrect challenge size (%zu)\n", sec_blob->length);
     116           0 :                 return false;
     117             :         }
     118             : 
     119       23946 :         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       23946 :         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       23946 :         if (!ntv2_owf_gen(part_passwd, user, domain, kr)) {
     135           0 :                 return false;
     136             :         }
     137             : 
     138       23946 :         status = SMBOWFencrypt_ntv2(kr,
     139             :                                     sec_blob,
     140             :                                     &client_key_data,
     141             :                                     value_from_encryption);
     142       23946 :         if (!NT_STATUS_IS_OK(status)) {
     143           0 :                 return false;
     144             :         }
     145             : 
     146             : #if DEBUG_PASSWORD
     147       23946 :         DEBUG(100,("Part password (P16) was |\n"));
     148       23946 :         dump_data(100, part_passwd, 16);
     149       23946 :         DEBUGADD(100,("Password from client was |\n"));
     150       23946 :         dump_data(100, ntv2_response->data, ntv2_response->length);
     151       23946 :         DEBUGADD(100,("Variable data from client was |\n"));
     152       23946 :         dump_data(100, client_key_data.data, client_key_data.length);
     153       23946 :         DEBUGADD(100,("Given challenge was |\n"));
     154       23946 :         dump_data(100, sec_blob->data, sec_blob->length);
     155       23946 :         DEBUGADD(100,("Value from encryption was |\n"));
     156       23946 :         dump_data(100, value_from_encryption, 16);
     157             : #endif
     158       23946 :         data_blob_clear_free(&client_key_data);
     159             : 
     160       23946 :         ok = mem_equal_const_time(value_from_encryption, ntv2_response->data, 16);
     161       23946 :         if (!ok) {
     162        9900 :                 return false;
     163             :         }
     164       14046 :         if (user_sess_key != NULL) {
     165       14046 :                 *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
     166       14046 :                 if (user_sess_key->data == NULL) {
     167           0 :                         DBG_ERR("data_blob_talloc failed\n");
     168           0 :                         return false;
     169             :                 }
     170             : 
     171       14046 :                 status = SMBsesskeygen_ntv2(
     172             :                         kr, value_from_encryption, user_sess_key->data);
     173       14046 :                 if (!NT_STATUS_IS_OK(status)) {
     174           0 :                         return false;
     175             :                 }
     176             :         }
     177       14046 :         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             :         uint8_t kr[16];
     194             :         uint8_t value_from_encryption[16];
     195             :         DATA_BLOB client_key_data;
     196             :         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        2065 : NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx,
     261             :                              bool lanman_auth,
     262             :                              const struct samr_Password *client_lanman,
     263             :                              const struct samr_Password *client_nt,
     264             :                              const char *username, 
     265             :                              const struct samr_Password *stored_lanman, 
     266             :                              const struct samr_Password *stored_nt)
     267             : {
     268        2065 :         if (stored_nt == NULL) {
     269           0 :                 DEBUG(3,("hash_password_check: NO NT password stored for user %s.\n",
     270             :                          username));
     271             :         }
     272             : 
     273        2065 :         if (client_nt && stored_nt) {
     274        1825 :                 if (mem_equal_const_time(client_nt->hash, stored_nt->hash, sizeof(stored_nt->hash))) {
     275        1197 :                         return NT_STATUS_OK;
     276             :                 } else {
     277         628 :                         DEBUG(3,("hash_password_check: Interactive logon: NT password check failed for user %s\n",
     278             :                                  username));
     279         628 :                         return NT_STATUS_WRONG_PASSWORD;
     280             :                 }
     281             : 
     282         240 :         } else if (client_lanman && stored_lanman) {
     283           0 :                 if (!lanman_auth) {
     284           0 :                         DEBUG(3,("hash_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n",
     285             :                                  username));
     286           0 :                         return NT_STATUS_WRONG_PASSWORD;
     287             :                 }
     288           0 :                 if (strchr_m(username, '@')) {
     289           0 :                         return NT_STATUS_NOT_FOUND;
     290             :                 }
     291             : 
     292           0 :                 if (mem_equal_const_time(client_lanman->hash, stored_lanman->hash, sizeof(stored_lanman->hash))) {
     293           0 :                         return NT_STATUS_OK;
     294             :                 } else {
     295           0 :                         DEBUG(3,("hash_password_check: Interactive logon: LANMAN password check failed for user %s\n",
     296             :                                  username));
     297           0 :                         return NT_STATUS_WRONG_PASSWORD;
     298             :                 }
     299             :         }
     300         240 :         if (strchr_m(username, '@')) {
     301          54 :                 return NT_STATUS_NOT_FOUND;
     302             :         }
     303         186 :         return NT_STATUS_WRONG_PASSWORD;
     304             : }
     305             : 
     306             : /**
     307             :  * Check a challenge-response password against the value of the NT or
     308             :  * LM password hash.
     309             :  *
     310             :  * @param mem_ctx talloc context
     311             :  * @param challenge 8-byte challenge.  If all zero, forces plaintext comparison
     312             :  * @param nt_response 'unicode' NT response to the challenge, or unicode password
     313             :  * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page
     314             :  * @param username internal Samba username, for log messages
     315             :  * @param client_username username the client used
     316             :  * @param client_domain domain name the client used (may be mapped)
     317             :  * @param stored_lanman LANMAN ASCII password from our passdb or similar
     318             :  * @param stored_nt MD4 unicode password from our passdb or similar
     319             :  * @param user_sess_key User session key
     320             :  * @param lm_sess_key LM session key (first 8 bytes of the LM hash)
     321             :  */
     322             : 
     323       20286 : NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
     324             :                              bool lanman_auth,
     325             :                              enum ntlm_auth_level ntlm_auth,
     326             :                              uint32_t logon_parameters,
     327             :                              const DATA_BLOB *challenge,
     328             :                              const DATA_BLOB *lm_response,
     329             :                              const DATA_BLOB *nt_response,
     330             :                              const char *username, 
     331             :                              const char *client_username, 
     332             :                              const char *client_domain,
     333             :                              const struct samr_Password *stored_lanman, 
     334             :                              const struct samr_Password *stored_nt, 
     335             :                              DATA_BLOB *user_sess_key, 
     336             :                              DATA_BLOB *lm_sess_key)
     337             : {
     338             :         DATA_BLOB tmp_sess_key;
     339       20286 :         const char *upper_client_domain = NULL;
     340             : 
     341       20286 :         if (ntlm_auth == NTLM_AUTH_DISABLED) {
     342           2 :                 DBG_WARNING("ntlm_password_check: NTLM authentication not "
     343             :                             "permitted by configuration.\n");
     344           2 :                 return NT_STATUS_NTLM_BLOCKED;
     345             :         }
     346             : 
     347       20284 :         if (client_domain != NULL) {
     348       18520 :                 upper_client_domain = talloc_strdup_upper(mem_ctx, client_domain);
     349       18520 :                 if (upper_client_domain == NULL) {
     350           0 :                         return NT_STATUS_NO_MEMORY;
     351             :                 }
     352             :         }
     353             : 
     354       20284 :         if (stored_nt == NULL) {
     355           2 :                 DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", 
     356             :                          username));
     357             :         }
     358             : 
     359       20284 :         *lm_sess_key = data_blob(NULL, 0);
     360       20284 :         *user_sess_key = data_blob(NULL, 0);
     361             : 
     362             :         /* Check for cleartext netlogon. Used by Exchange 5.5. */
     363       20284 :         if ((logon_parameters & MSV1_0_CLEARTEXT_PASSWORD_ALLOWED)
     364        1179 :             && challenge->length == 8
     365        1179 :             && (all_zero(challenge->data, challenge->length))) {
     366             :                 struct samr_Password client_nt;
     367             :                 struct samr_Password client_lm;
     368        1164 :                 char *unix_pw = NULL;
     369             :                 bool lm_ok;
     370        1164 :                 size_t converted_size = 0;
     371             : 
     372        1164 :                 DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n",
     373             :                          username));
     374        1164 :                 mdfour(client_nt.hash, nt_response->data, nt_response->length);
     375             : 
     376        2106 :                 if (lm_response->length && 
     377        1876 :                     (convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, 
     378         942 :                                           lm_response->data, lm_response->length, 
     379             :                                            (void *)&unix_pw, &converted_size))) {
     380        1876 :                         if (E_deshash(unix_pw, client_lm.hash)) {
     381         240 :                                 lm_ok = true;
     382             :                         } else {
     383         702 :                                 lm_ok = false;
     384             :                         }
     385             :                 } else {
     386         222 :                         lm_ok = false;
     387             :                 }
     388        1164 :                 return hash_password_check(mem_ctx, 
     389             :                                            lanman_auth,
     390             :                                            lm_ok ? &client_lm : NULL, 
     391        1164 :                                            nt_response->length ? &client_nt : NULL, 
     392             :                                            username,  
     393             :                                            stored_lanman, stored_nt);
     394             :         }
     395             : 
     396       19120 :         if (nt_response->length != 0 && nt_response->length < 24) {
     397           0 :                 DBG_NOTICE("invalid NT password length (%zu) for user %s\n",
     398             :                            nt_response->length,
     399             :                            username);
     400             :         }
     401             : 
     402       19120 :         if (nt_response->length > 24 && stored_nt) {
     403             :                 /* We have the NT MD4 hash challenge available - see if we can
     404             :                    use it 
     405             :                 */
     406       14770 :                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n",
     407             :                         client_domain ? client_domain : "<NULL>"));
     408       14770 :                 if (smb_pwd_check_ntlmv2(mem_ctx,
     409             :                                          nt_response, 
     410       14770 :                                          stored_nt->hash, challenge, 
     411             :                                          client_username, 
     412             :                                          client_domain,
     413             :                                          user_sess_key)) {
     414       13152 :                         if (user_sess_key->length) {
     415       13152 :                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     416             :                         }
     417       13152 :                         return NT_STATUS_OK;
     418             :                 }
     419             : 
     420        1618 :                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n",
     421             :                         upper_client_domain ? upper_client_domain : "<NULL>"));
     422        1618 :                 if (smb_pwd_check_ntlmv2(mem_ctx,
     423             :                                          nt_response, 
     424        1618 :                                          stored_nt->hash, challenge, 
     425             :                                          client_username, 
     426             :                                          upper_client_domain,
     427             :                                          user_sess_key)) {
     428           0 :                         if (user_sess_key->length) {
     429           0 :                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     430             :                         }
     431           0 :                         return NT_STATUS_OK;
     432             :                 }
     433             : 
     434        1618 :                 DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n"));
     435        2929 :                 if (smb_pwd_check_ntlmv2(mem_ctx,
     436             :                                          nt_response, 
     437        1618 :                                          stored_nt->hash, challenge, 
     438             :                                          client_username, 
     439             :                                          "",
     440             :                                          user_sess_key)) {
     441         288 :                         if (user_sess_key->length) {
     442         288 :                                 *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     443             :                         }
     444         288 :                         return NT_STATUS_OK;
     445             :                 } else {
     446        1330 :                         DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n"));
     447             :                 }
     448        4350 :         } else if (nt_response->length == 24 && stored_nt) {
     449        3354 :                 if (ntlm_auth == NTLM_AUTH_ON
     450          32 :                     || (ntlm_auth == NTLM_AUTH_MSCHAPv2_NTLMV2_ONLY && (logon_parameters & MSV1_0_ALLOW_MSVCHAPV2))) {
     451             :                         /* We have the NT MD4 hash challenge available - see if we can
     452             :                            use it (ie. does it exist in the smbpasswd file).
     453             :                         */
     454        3323 :                         DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n"));
     455        3323 :                         if (smb_pwd_check_ntlmv1(mem_ctx, 
     456             :                                                  nt_response, 
     457        3323 :                                                  stored_nt->hash, challenge,
     458             :                                                  user_sess_key)) {
     459             :                                 /* The LM session key for this response is not very secure, 
     460             :                                    so use it only if we otherwise allow LM authentication */
     461             : 
     462        1669 :                                 if (lanman_auth && stored_lanman) {
     463           5 :                                         *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, MIN(8, user_sess_key->length));
     464             :                                 }
     465        1669 :                                 return NT_STATUS_OK;
     466             :                         } else {
     467        1654 :                                 DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n",
     468             :                                          username));
     469        1654 :                                 return NT_STATUS_WRONG_PASSWORD;
     470             :                         }
     471             :                 } else {
     472          31 :                         DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n",
     473             :                                  username));                    
     474             :                         /* no return, because we might pick up LMv2 in the LM field */
     475             :                 }
     476             :         }
     477             : 
     478        2357 :         if (lm_response->length == 0) {
     479          67 :                 DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n",
     480             :                          username));
     481          67 :                 return NT_STATUS_WRONG_PASSWORD;
     482             :         }
     483             : 
     484        2290 :         if (lm_response->length < 24) {
     485           0 :                 DBG_NOTICE("invalid LanMan password length (%zu) for "
     486             :                            "user %s\n",
     487             :                            nt_response->length, username);
     488           0 :                 return NT_STATUS_WRONG_PASSWORD;
     489             :         }
     490             : 
     491        2290 :         if (!lanman_auth) {
     492        2290 :                 DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n",
     493             :                          username));
     494           0 :         } else if (!stored_lanman) {
     495           0 :                 DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n",
     496             :                          username));
     497           0 :         } else if (strchr_m(username, '@')) {
     498           0 :                 DEBUG(3,("ntlm_password_check: NO LanMan password allowed for username@realm logins (user: %s)\n",
     499             :                          username));
     500             :         } else {
     501           0 :                 DEBUG(4,("ntlm_password_check: Checking LM password\n"));
     502           0 :                 if (smb_pwd_check_ntlmv1(mem_ctx,
     503             :                                          lm_response, 
     504           0 :                                          stored_lanman->hash, challenge,
     505             :                                          NULL)) {
     506             :                         /* The session key for this response is still very odd.  
     507             :                            It not very secure, so use it only if we otherwise 
     508             :                            allow LM authentication */
     509             : 
     510           0 :                         if (lanman_auth && stored_lanman) {
     511             :                                 uint8_t first_8_lm_hash[16];
     512           0 :                                 memcpy(first_8_lm_hash, stored_lanman->hash, 8);
     513           0 :                                 memset(first_8_lm_hash + 8, '\0', 8);
     514           0 :                                 *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
     515           0 :                                 *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
     516             :                         }
     517           0 :                         return NT_STATUS_OK;
     518             :                 }
     519             :         }
     520             : 
     521        2290 :         if (!stored_nt) {
     522           2 :                 DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username));
     523           2 :                 return NT_STATUS_WRONG_PASSWORD;
     524             :         }
     525             : 
     526             :         /* This is for 'LMv2' authentication.  almost NTLMv2 but limited to 24 bytes.
     527             :            - related to Win9X, legacy NAS pass-though authentication
     528             :         */
     529        2288 :         DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n",
     530             :                 client_domain ? client_domain : "<NULL>"));
     531        2288 :         if (smb_pwd_check_ntlmv2(mem_ctx,
     532             :                                  lm_response, 
     533        2288 :                                  stored_nt->hash, challenge, 
     534             :                                  client_username,
     535             :                                  client_domain,
     536             :                                  &tmp_sess_key)) {
     537         462 :                 if (nt_response->length > 24) {
     538             :                         /* If NTLMv2 authentication has preceded us
     539             :                          * (even if it failed), then use the session
     540             :                          * key from that.  See the RPC-SAMLOGON
     541             :                          * torture test */
     542         204 :                         smb_sess_key_ntlmv2(mem_ctx,
     543             :                                             nt_response, 
     544         204 :                                             stored_nt->hash, challenge, 
     545             :                                             client_username,
     546             :                                             client_domain,
     547             :                                             user_sess_key);
     548             :                 } else {
     549             :                         /* Otherwise, use the LMv2 session key */
     550         258 :                         *user_sess_key = tmp_sess_key;
     551             :                 }
     552         462 :                 if (user_sess_key->length) {
     553         462 :                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     554             :                 }
     555         462 :                 return NT_STATUS_OK;
     556             :         }
     557             : 
     558        1826 :         DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n",
     559             :                 upper_client_domain ? upper_client_domain : "<NULL>"));
     560        1826 :         if (smb_pwd_check_ntlmv2(mem_ctx,
     561             :                                  lm_response, 
     562        1826 :                                  stored_nt->hash, challenge, 
     563             :                                  client_username,
     564             :                                  upper_client_domain,
     565             :                                  &tmp_sess_key)) {
     566           0 :                 if (nt_response->length > 24) {
     567             :                         /* If NTLMv2 authentication has preceded us
     568             :                          * (even if it failed), then use the session
     569             :                          * key from that.  See the RPC-SAMLOGON
     570             :                          * torture test */
     571           0 :                         smb_sess_key_ntlmv2(mem_ctx,
     572             :                                             nt_response, 
     573           0 :                                             stored_nt->hash, challenge, 
     574             :                                             client_username,
     575             :                                             upper_client_domain,
     576             :                                             user_sess_key);
     577             :                 } else {
     578             :                         /* Otherwise, use the LMv2 session key */
     579           0 :                         *user_sess_key = tmp_sess_key;
     580             :                 }
     581           0 :                 if (user_sess_key->length) {
     582           0 :                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     583             :                 }
     584           0 :                 return NT_STATUS_OK;
     585             :         }
     586             : 
     587        1826 :         DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n"));
     588        1826 :         if (smb_pwd_check_ntlmv2(mem_ctx,
     589             :                                  lm_response, 
     590        1826 :                                  stored_nt->hash, challenge, 
     591             :                                  client_username,
     592             :                                  "",
     593             :                                  &tmp_sess_key)) {
     594         144 :                 if (nt_response->length > 24) {
     595             :                         /* If NTLMv2 authentication has preceded us
     596             :                          * (even if it failed), then use the session
     597             :                          * key from that.  See the RPC-SAMLOGON
     598             :                          * torture test */
     599           0 :                         smb_sess_key_ntlmv2(mem_ctx,
     600             :                                             nt_response, 
     601           0 :                                             stored_nt->hash, challenge, 
     602             :                                             client_username,
     603             :                                             "",
     604             :                                             user_sess_key);
     605             :                 } else {
     606             :                         /* Otherwise, use the LMv2 session key */
     607         144 :                         *user_sess_key = tmp_sess_key;
     608             :                 }
     609         144 :                 if (user_sess_key->length) {
     610         144 :                         *lm_sess_key = data_blob_talloc(mem_ctx, user_sess_key->data, MIN(8, user_sess_key->length));
     611             :                 }
     612         144 :                 return NT_STATUS_OK;
     613             :         }
     614             : 
     615             :         /* Apparently NT accepts NT responses in the LM field
     616             :            - I think this is related to Win9X pass-though authentication
     617             :         */
     618        1682 :         DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n"));
     619        1682 :         if (ntlm_auth == NTLM_AUTH_ON) {
     620        1674 :                 if (smb_pwd_check_ntlmv1(mem_ctx, 
     621             :                                          lm_response, 
     622        1674 :                                          stored_nt->hash, challenge,
     623             :                                          NULL)) {
     624             :                         /* The session key for this response is still very odd.  
     625             :                            It not very secure, so use it only if we otherwise 
     626             :                            allow LM authentication */
     627             : 
     628         204 :                         if (lanman_auth && stored_lanman) {
     629             :                                 uint8_t first_8_lm_hash[16];
     630           0 :                                 memcpy(first_8_lm_hash, stored_lanman->hash, 8);
     631           0 :                                 memset(first_8_lm_hash + 8, '\0', 8);
     632           0 :                                 *user_sess_key = data_blob_talloc(mem_ctx, first_8_lm_hash, 16);
     633           0 :                                 *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8);
     634             :                         }
     635         204 :                         return NT_STATUS_OK;
     636             :                 }
     637        1470 :                 DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username));
     638             :         } else {
     639           8 :                 DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username));
     640             :         }
     641             : 
     642             :         /* Try and match error codes */
     643        1478 :         if (strchr_m(username, '@')) {
     644         162 :                 return NT_STATUS_NOT_FOUND;
     645             :         }
     646        1316 :         return NT_STATUS_WRONG_PASSWORD;
     647             : }
     648             : 

Generated by: LCOV version 1.13