LCOV - code coverage report
Current view: top level - auth/credentials - credentials_ntlm.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 192 276 69.6 %
Date: 2024-04-21 15:09:00 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    User credentials handling
       5             : 
       6             :    Copyright (C) Andrew Tridgell      2001
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2005
       8             :    Copyright (C) Stefan Metzmacher 2005
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
      26             : #include "../lib/crypto/crypto.h"
      27             : #include "libcli/auth/libcli_auth.h"
      28             : #include "auth/credentials/credentials.h"
      29             : #include "auth/credentials/credentials_internal.h"
      30             : 
      31             : #include "lib/crypto/gnutls_helpers.h"
      32             : #include <gnutls/gnutls.h>
      33             : #include <gnutls/crypto.h>
      34             : 
      35             : #undef DBGC_CLASS
      36             : #define DBGC_CLASS DBGC_AUTH
      37             : 
      38       40550 : _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
      39             :                                            int *flags,
      40             :                                            DATA_BLOB challenge,
      41             :                                            const NTTIME *server_timestamp,
      42             :                                            DATA_BLOB target_info,
      43             :                                            DATA_BLOB *_lm_response, DATA_BLOB *_nt_response,
      44             :                                            DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key)
      45             : {
      46       40550 :         TALLOC_CTX *frame = talloc_stackframe();
      47       40550 :         const char *user = NULL;
      48       40550 :         const char *domain = NULL;
      49       40550 :         DATA_BLOB lm_response = data_blob_null;
      50       40550 :         DATA_BLOB nt_response = data_blob_null;
      51       40550 :         DATA_BLOB lm_session_key = data_blob_null;
      52       40550 :         DATA_BLOB session_key = data_blob_null;
      53       40550 :         const struct samr_Password *nt_hash = NULL;
      54         514 :         int rc;
      55             : 
      56       40550 :         if (cred->kerberos_state == CRED_USE_KERBEROS_REQUIRED) {
      57           0 :                 TALLOC_FREE(frame);
      58           0 :                 return NT_STATUS_INVALID_PARAMETER_MIX;
      59             :         }
      60             : 
      61             :         /* We may already have an NTLM response we prepared earlier.
      62             :          * This is used for NTLM pass-though authentication */
      63       40550 :         if (cred->nt_response.data || cred->lm_response.data) {
      64          12 :                 if (cred->nt_response.length != 0) {
      65          12 :                         nt_response = data_blob_dup_talloc(frame,
      66             :                                                            cred->nt_response);
      67          12 :                         if (nt_response.data == NULL) {
      68           0 :                                 TALLOC_FREE(frame);
      69           0 :                                 return NT_STATUS_NO_MEMORY;
      70             :                         }
      71             :                 }
      72          12 :                 if (cred->nt_session_key.length != 0) {
      73          12 :                         session_key = data_blob_dup_talloc(frame,
      74             :                                                            cred->nt_session_key);
      75          12 :                         if (session_key.data == NULL) {
      76           0 :                                 TALLOC_FREE(frame);
      77           0 :                                 return NT_STATUS_NO_MEMORY;
      78             :                         }
      79             :                 }
      80          12 :                 if (cred->lm_response.length != 0) {
      81          12 :                         lm_response = data_blob_dup_talloc(frame,
      82             :                                                            cred->lm_response);
      83          12 :                         if (lm_response.data == NULL) {
      84           0 :                                 TALLOC_FREE(frame);
      85           0 :                                 return NT_STATUS_NO_MEMORY;
      86             :                         }
      87             :                 }
      88          12 :                 if (cred->lm_session_key.length != 0) {
      89          12 :                         lm_session_key = data_blob_dup_talloc(frame,
      90             :                                                               cred->lm_session_key);
      91          12 :                         if (lm_session_key.data == NULL) {
      92           0 :                                 TALLOC_FREE(frame);
      93           0 :                                 return NT_STATUS_NO_MEMORY;
      94             :                         }
      95             :                 }
      96             : 
      97          12 :                 if (cred->lm_response.data == NULL) {
      98           0 :                         *flags = *flags & ~CLI_CRED_LANMAN_AUTH;
      99             :                 }
     100          12 :                 goto done;
     101             :         }
     102             : 
     103       40538 :         nt_hash = cli_credentials_get_nt_hash(cred, frame);
     104             : 
     105       40538 :         cli_credentials_get_ntlm_username_domain(cred, frame, &user, &domain);
     106       40538 :         if (user == NULL) {
     107           0 :                 TALLOC_FREE(frame);
     108           0 :                 return NT_STATUS_NO_MEMORY;
     109             :         }
     110       40538 :         if (domain == NULL) {
     111           0 :                 TALLOC_FREE(frame);
     112           0 :                 return NT_STATUS_NO_MEMORY;
     113             :         }
     114             : 
     115             :         /* If we are sending a username@realm login (see function
     116             :          * above), then we will not send LM, it will not be
     117             :          * accepted */
     118       40538 :         if (cred->principal_obtained > cred->username_obtained) {
     119           0 :                 *flags = *flags & ~CLI_CRED_LANMAN_AUTH;
     120             :         }
     121             : 
     122             :         /* Likewise if we are a machine account (avoid protocol downgrade attacks) */
     123       40538 :         if (cred->machine_account) {
     124         156 :                 *flags = *flags & ~CLI_CRED_LANMAN_AUTH;
     125             :         }
     126             : 
     127       40538 :         if (!nt_hash) {
     128             :                 /* do nothing - blobs are zero length */
     129             : 
     130             :                 /* session key is all zeros */
     131        1079 :                 session_key = data_blob_talloc_zero(frame, 16);
     132        1079 :                 if (session_key.data == NULL) {
     133           0 :                         TALLOC_FREE(frame);
     134           0 :                         return NT_STATUS_NO_MEMORY;
     135             :                 }
     136        1079 :                 lm_session_key = data_blob_talloc_zero(frame, 16);
     137        1079 :                 if (lm_session_key.data == NULL) {
     138           0 :                         TALLOC_FREE(frame);
     139           0 :                         return NT_STATUS_NO_MEMORY;
     140             :                 }
     141             : 
     142             :                 /* not doing NTLM2 without a password */
     143        1079 :                 *flags &= ~CLI_CRED_NTLM2;
     144       39459 :         } else if (*flags & CLI_CRED_NTLMv2_AUTH) {
     145             : 
     146       38490 :                 if (!target_info.length) {
     147             :                         /* be lazy, match win2k - we can't do NTLMv2 without it */
     148           0 :                         DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
     149           0 :                         TALLOC_FREE(frame);
     150           0 :                         return NT_STATUS_INVALID_PARAMETER;
     151             :                 }
     152             : 
     153             :                 /* TODO: if the remote server is standalone, then we should replace 'domain'
     154             :                    with the server name as supplied above */
     155             : 
     156       38490 :                 if (!SMBNTLMv2encrypt_hash(frame,
     157             :                                            user,
     158             :                                            domain,
     159       38490 :                                            nt_hash->hash, &challenge,
     160             :                                            server_timestamp, &target_info,
     161             :                                            &lm_response, &nt_response,
     162             :                                            NULL, &session_key)) {
     163           0 :                         TALLOC_FREE(frame);
     164           0 :                         return NT_STATUS_NO_MEMORY;
     165             :                 }
     166             : 
     167             :                 /* LM Key is incompatible... */
     168       38490 :                 *flags &= ~CLI_CRED_LANMAN_AUTH;
     169       38490 :                 if (lm_response.length != 0) {
     170             :                         /*
     171             :                          * We should not expose the lm key.
     172             :                          */
     173       38490 :                         memset(lm_response.data, 0, lm_response.length);
     174             :                 }
     175         969 :         } else if (*flags & CLI_CRED_NTLM2) {
     176           1 :                 uint8_t session_nonce[16];
     177           1 :                 uint8_t session_nonce_hash[16];
     178           1 :                 uint8_t user_session_key[16];
     179             : 
     180         170 :                 lm_response = data_blob_talloc_zero(frame, 24);
     181         170 :                 if (lm_response.data == NULL) {
     182           0 :                         TALLOC_FREE(frame);
     183           0 :                         return NT_STATUS_NO_MEMORY;
     184             :                 }
     185         170 :                 generate_random_buffer(lm_response.data, 8);
     186             : 
     187         170 :                 memcpy(session_nonce, challenge.data, 8);
     188         170 :                 memcpy(&session_nonce[8], lm_response.data, 8);
     189             : 
     190         170 :                 rc = gnutls_hash_fast(GNUTLS_DIG_MD5,
     191             :                                       session_nonce,
     192             :                                       sizeof(session_nonce),
     193             :                                       session_nonce_hash);
     194         170 :                 if (rc < 0) {
     195           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     196             :                 }
     197             : 
     198         170 :                 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
     199         170 :                 DEBUG(5, ("challenge is: \n"));
     200         170 :                 dump_data(5, session_nonce_hash, 8);
     201             : 
     202         170 :                 nt_response = data_blob_talloc_zero(frame, 24);
     203         170 :                 if (nt_response.data == NULL) {
     204           0 :                         TALLOC_FREE(frame);
     205           0 :                         return NT_STATUS_NO_MEMORY;
     206             :                 }
     207         170 :                 rc = SMBOWFencrypt(nt_hash->hash,
     208             :                                    session_nonce_hash,
     209             :                                    nt_response.data);
     210         170 :                 if (rc != 0) {
     211           0 :                         TALLOC_FREE(frame);
     212           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     213             :                 }
     214             : 
     215         170 :                 ZERO_ARRAY(session_nonce_hash);
     216             : 
     217         170 :                 session_key = data_blob_talloc_zero(frame, 16);
     218         170 :                 if (session_key.data == NULL) {
     219           0 :                         TALLOC_FREE(frame);
     220           0 :                         return NT_STATUS_NO_MEMORY;
     221             :                 }
     222             : 
     223         170 :                 SMBsesskeygen_ntv1(nt_hash->hash, user_session_key);
     224             : 
     225         171 :                 rc = gnutls_hmac_fast(GNUTLS_MAC_MD5,
     226             :                                       user_session_key,
     227             :                                       sizeof(user_session_key),
     228             :                                       session_nonce,
     229             :                                       sizeof(session_nonce),
     230         170 :                                       session_key.data);
     231         170 :                 if (rc < 0) {
     232           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_NTLM_BLOCKED);
     233             :                 }
     234             : 
     235         170 :                 ZERO_ARRAY(user_session_key);
     236             : 
     237         170 :                 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
     238             : 
     239             :                 /* LM Key is incompatible... */
     240         170 :                 *flags &= ~CLI_CRED_LANMAN_AUTH;
     241             :         } else {
     242         799 :                 const char *password = cli_credentials_get_password(cred);
     243           9 :                 uint8_t lm_hash[16];
     244         799 :                 bool do_lm = false;
     245             : 
     246         799 :                 nt_response = data_blob_talloc_zero(frame, 24);
     247         799 :                 if (nt_response.data == NULL) {
     248           0 :                         TALLOC_FREE(frame);
     249           0 :                         return NT_STATUS_NO_MEMORY;
     250             :                 }
     251         799 :                 rc = SMBOWFencrypt(nt_hash->hash, challenge.data,
     252             :                                    nt_response.data);
     253         799 :                 if (rc != 0) {
     254           0 :                         TALLOC_FREE(frame);
     255           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     256             :                 }
     257             : 
     258         799 :                 session_key = data_blob_talloc_zero(frame, 16);
     259         799 :                 if (session_key.data == NULL) {
     260           0 :                         TALLOC_FREE(frame);
     261           0 :                         return NT_STATUS_NO_MEMORY;
     262             :                 }
     263         799 :                 SMBsesskeygen_ntv1(nt_hash->hash, session_key.data);
     264         799 :                 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
     265             : 
     266             :                 /* lanman auth is insecure, it may be disabled.
     267             :                    We may also not have a password */
     268             : 
     269         799 :                 if (password != NULL) {
     270         798 :                         do_lm = E_deshash(password, lm_hash);
     271             :                 }
     272             : 
     273         799 :                 if (*flags & CLI_CRED_LANMAN_AUTH && do_lm) {
     274         677 :                         lm_response = data_blob_talloc_zero(frame, 24);
     275         677 :                         if (lm_response.data == NULL) {
     276           0 :                                 ZERO_STRUCT(lm_hash);
     277           0 :                                 TALLOC_FREE(frame);
     278           0 :                                 return NT_STATUS_NO_MEMORY;
     279             :                         }
     280             : 
     281         679 :                         rc = SMBencrypt_hash(lm_hash,
     282         677 :                                              challenge.data,
     283             :                                              lm_response.data);
     284         677 :                         if (rc != 0) {
     285           0 :                                 ZERO_STRUCT(lm_hash);
     286           0 :                                 TALLOC_FREE(frame);
     287           0 :                                 return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     288             :                         }
     289             :                 } else {
     290             :                         /* just copy the nt_response */
     291         122 :                         lm_response = data_blob_dup_talloc(frame, nt_response);
     292         122 :                         if (lm_response.data == NULL) {
     293           0 :                                 ZERO_STRUCT(lm_hash);
     294           0 :                                 TALLOC_FREE(frame);
     295           0 :                                 return NT_STATUS_NO_MEMORY;
     296             :                         }
     297             :                 }
     298             : 
     299         799 :                 if (do_lm) {
     300         696 :                         lm_session_key = data_blob_talloc_zero(frame, 16);
     301         696 :                         if (lm_session_key.data == NULL) {
     302           0 :                                 ZERO_STRUCT(lm_hash);
     303           0 :                                 TALLOC_FREE(frame);
     304           0 :                                 return NT_STATUS_NO_MEMORY;
     305             :                         }
     306         696 :                         memcpy(lm_session_key.data, lm_hash, 8);
     307             : 
     308         696 :                         if (!(*flags & CLI_CRED_NTLM_AUTH)) {
     309          32 :                                 memcpy(session_key.data, lm_session_key.data, 16);
     310             :                         }
     311         696 :                         ZERO_STRUCT(lm_hash);
     312             :                 }
     313             :         }
     314             : 
     315       40550 : done:
     316       40550 :         if (_lm_response != NULL) {
     317       40550 :                 talloc_steal(mem_ctx, lm_response.data);
     318       40550 :                 *_lm_response = lm_response;
     319             :         } else {
     320           0 :                 data_blob_clear(&lm_response);
     321             :         }
     322       40550 :         if (_nt_response != NULL) {
     323       40546 :                 talloc_steal(mem_ctx, nt_response.data);
     324       40546 :                 *_nt_response = nt_response;
     325             :         } else {
     326           4 :                 data_blob_clear(&nt_response);
     327             :         }
     328       40550 :         if (_lm_session_key != NULL) {
     329       37791 :                 talloc_steal(mem_ctx, lm_session_key.data);
     330       37791 :                 *_lm_session_key = lm_session_key;
     331             :         } else {
     332        2759 :                 data_blob_clear(&lm_session_key);
     333             :         }
     334       40550 :         if (_session_key != NULL) {
     335       37812 :                 talloc_steal(mem_ctx, session_key.data);
     336       37812 :                 *_session_key = session_key;
     337             :         } else {
     338        2738 :                 data_blob_clear(&session_key);
     339             :         }
     340       40550 :         TALLOC_FREE(frame);
     341       40550 :         return NT_STATUS_OK;
     342             : }
     343             : 
     344             : /*
     345             :  * Set a utf16 password on the credentials context, including an indication
     346             :  * of 'how' the password was obtained
     347             :  *
     348             :  * This is required because the nt_hash is calculated over the raw utf16 blob,
     349             :  * which might not be completely valid utf16, which means the conversion
     350             :  * from CH_UTF16MUNGED to CH_UTF8 might lose information.
     351             :  */
     352         809 : _PUBLIC_ bool cli_credentials_set_utf16_password(struct cli_credentials *cred,
     353             :                                                  const DATA_BLOB *password_utf16,
     354             :                                                  enum credentials_obtained obtained)
     355             : {
     356         809 :         cred->password_will_be_nt_hash = false;
     357             : 
     358         809 :         if (password_utf16 == NULL) {
     359           0 :                 return cli_credentials_set_password(cred, NULL, obtained);
     360             :         }
     361             : 
     362         809 :         if (obtained >= cred->password_obtained) {
     363         809 :                 struct samr_Password *nt_hash = NULL;
     364         809 :                 char *password_talloc = NULL;
     365         809 :                 size_t password_len = 0;
     366           1 :                 bool ok;
     367             : 
     368         809 :                 nt_hash = talloc(cred, struct samr_Password);
     369         809 :                 if (nt_hash == NULL) {
     370           0 :                         return false;
     371             :                 }
     372             : 
     373         810 :                 ok = convert_string_talloc(cred,
     374             :                                            CH_UTF16MUNGED, CH_UTF8,
     375         809 :                                            password_utf16->data,
     376         809 :                                            password_utf16->length,
     377             :                                            &password_talloc,
     378             :                                            &password_len);
     379         809 :                 if (!ok) {
     380           0 :                         TALLOC_FREE(nt_hash);
     381           0 :                         return false;
     382             :                 }
     383             : 
     384         809 :                 ok = cli_credentials_set_password(cred, password_talloc, obtained);
     385         809 :                 TALLOC_FREE(password_talloc);
     386         809 :                 if (!ok) {
     387           0 :                         TALLOC_FREE(nt_hash);
     388           0 :                         return false;
     389             :                 }
     390             : 
     391         809 :                 mdfour(nt_hash->hash, password_utf16->data, password_utf16->length);
     392         809 :                 cred->nt_hash = nt_hash;
     393         809 :                 return true;
     394             :         }
     395             : 
     396           0 :         return false;
     397             : }
     398             : 
     399             : /*
     400             :  * Set a old utf16 password on the credentials context.
     401             :  *
     402             :  * This is required because the nt_hash is calculated over the raw utf16 blob,
     403             :  * which might not be completely valid utf16, which means the conversion
     404             :  * from CH_UTF16MUNGED to CH_UTF8 might lose information.
     405             :  */
     406           1 : _PUBLIC_ bool cli_credentials_set_old_utf16_password(struct cli_credentials *cred,
     407             :                                                      const DATA_BLOB *password_utf16)
     408             : {
     409           1 :         struct samr_Password *nt_hash = NULL;
     410           1 :         char *password_talloc = NULL;
     411           1 :         size_t password_len = 0;
     412           1 :         bool ok;
     413             : 
     414           1 :         if (password_utf16 == NULL) {
     415           0 :                 return cli_credentials_set_old_password(cred, NULL, CRED_SPECIFIED);
     416             :         }
     417             : 
     418           1 :         nt_hash = talloc(cred, struct samr_Password);
     419           1 :         if (nt_hash == NULL) {
     420           0 :                 return false;
     421             :         }
     422             : 
     423           2 :         ok = convert_string_talloc(cred,
     424             :                                    CH_UTF16MUNGED, CH_UTF8,
     425           1 :                                    password_utf16->data,
     426           1 :                                    password_utf16->length,
     427             :                                    &password_talloc,
     428             :                                    &password_len);
     429           1 :         if (!ok) {
     430           0 :                 TALLOC_FREE(nt_hash);
     431           0 :                 return false;
     432             :         }
     433             : 
     434           1 :         ok = cli_credentials_set_old_password(cred, password_talloc, CRED_SPECIFIED);
     435           1 :         TALLOC_FREE(password_talloc);
     436           1 :         if (!ok) {
     437           0 :                 TALLOC_FREE(nt_hash);
     438           0 :                 return false;
     439             :         }
     440             : 
     441           1 :         mdfour(nt_hash->hash, password_utf16->data, password_utf16->length);
     442           1 :         cred->old_nt_hash = nt_hash;
     443           1 :         return true;
     444             : }
     445             : 
     446           3 : _PUBLIC_ void cli_credentials_set_password_will_be_nt_hash(struct cli_credentials *cred,
     447             :                                                            bool val)
     448             : {
     449             :         /*
     450             :          * We set this here and the next cli_credentials_set_password()
     451             :          * that resets the password or password callback
     452             :          * will pick this up.
     453             :          *
     454             :          * cli_credentials_set_nt_hash() and
     455             :          * cli_credentials_set_utf16_password() will reset this
     456             :          * to false.
     457             :          */
     458           3 :         cred->password_will_be_nt_hash = val;
     459           3 : }
     460             : 
     461          48 : _PUBLIC_ bool cli_credentials_is_password_nt_hash(struct cli_credentials *cred)
     462             : {
     463          48 :         return cred->password_will_be_nt_hash;
     464             : }
     465             : 
     466         170 : _PUBLIC_ bool cli_credentials_set_nt_hash(struct cli_credentials *cred,
     467             :                                  const struct samr_Password *nt_hash,
     468             :                                  enum credentials_obtained obtained)
     469             : {
     470         170 :         cred->password_will_be_nt_hash = false;
     471             : 
     472         170 :         if (obtained >= cred->password_obtained) {
     473         170 :                 cli_credentials_set_password(cred, NULL, obtained);
     474         170 :                 if (nt_hash) {
     475         170 :                         cred->nt_hash = talloc(cred, struct samr_Password);
     476         170 :                         if (cred->nt_hash == NULL) {
     477           0 :                                 return false;
     478             :                         }
     479         170 :                         *cred->nt_hash = *nt_hash;
     480             :                 } else {
     481           0 :                         cred->nt_hash = NULL;
     482             :                 }
     483         170 :                 return true;
     484             :         }
     485             : 
     486           0 :         return false;
     487             : }
     488             : 
     489           0 : _PUBLIC_ bool cli_credentials_set_old_nt_hash(struct cli_credentials *cred,
     490             :                                               const struct samr_Password *nt_hash)
     491             : {
     492           0 :         cli_credentials_set_old_password(cred, NULL, CRED_SPECIFIED);
     493           0 :         if (nt_hash) {
     494           0 :                 cred->old_nt_hash = talloc(cred, struct samr_Password);
     495           0 :                 if (cred->old_nt_hash == NULL) {
     496           0 :                         return false;
     497             :                 }
     498           0 :                 *cred->old_nt_hash = *nt_hash;
     499             :         } else {
     500           0 :                 cred->old_nt_hash = NULL;
     501             :         }
     502             : 
     503           0 :         return true;
     504             : }
     505             : 
     506          12 : _PUBLIC_ bool cli_credentials_set_ntlm_response(struct cli_credentials *cred,
     507             :                                                 const DATA_BLOB *lm_response,
     508             :                                                 const DATA_BLOB *lm_session_key,
     509             :                                                 const DATA_BLOB *nt_response,
     510             :                                                 const DATA_BLOB *nt_session_key,
     511             :                                                 enum credentials_obtained obtained)
     512             : {
     513          12 :         if (obtained >= cred->password_obtained) {
     514          12 :                 cli_credentials_set_password(cred, NULL, obtained);
     515             : 
     516          12 :                 data_blob_clear_free(&cred->lm_response);
     517          12 :                 data_blob_clear_free(&cred->lm_session_key);
     518          12 :                 data_blob_clear_free(&cred->nt_response);
     519          12 :                 data_blob_clear_free(&cred->nt_session_key);
     520             : 
     521          12 :                 if (lm_response != NULL && lm_response->length != 0) {
     522          12 :                         cred->lm_response = data_blob_talloc(cred,
     523             :                                                         lm_response->data,
     524             :                                                         lm_response->length);
     525          12 :                         if (cred->lm_response.data == NULL) {
     526           0 :                                 return false;
     527             :                         }
     528             :                 }
     529          12 :                 if (lm_session_key != NULL && lm_session_key->length != 0) {
     530          12 :                         cred->lm_session_key = data_blob_talloc(cred,
     531             :                                                         lm_session_key->data,
     532             :                                                         lm_session_key->length);
     533          12 :                         if (cred->lm_session_key.data == NULL) {
     534           0 :                                 return false;
     535             :                         }
     536             :                 }
     537             : 
     538          12 :                 if (nt_response != NULL && nt_response->length != 0) {
     539          12 :                         cred->nt_response = data_blob_talloc(cred,
     540             :                                                         nt_response->data,
     541             :                                                         nt_response->length);
     542          12 :                         if (cred->nt_response.data == NULL) {
     543           0 :                                 return false;
     544             :                         }
     545             :                 }
     546          12 :                 if (nt_session_key != NULL && nt_session_key->length != 0) {
     547          12 :                         cred->nt_session_key = data_blob_talloc(cred,
     548             :                                                         nt_session_key->data,
     549             :                                                         nt_session_key->length);
     550          12 :                         if (cred->nt_session_key.data == NULL) {
     551           0 :                                 return false;
     552             :                         }
     553             :                 }
     554             : 
     555          12 :                 return true;
     556             :         }
     557             : 
     558           0 :         return false;
     559             : }
     560             : 

Generated by: LCOV version 1.14