2005-10-14 07:57:35 +04:00
/*
Unix SMB / CIFS implementation .
User credentials handling
Copyright ( C ) Andrew Tridgell 2001
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2001 - 2005
Copyright ( C ) Stefan Metzmacher 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-10-14 07:57:35 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-10-14 07:57:35 +04:00
*/
# include "includes.h"
2006-03-16 03:23:11 +03:00
# include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
2008-09-24 17:30:23 +04:00
# include "../lib/crypto/crypto.h"
2006-03-14 18:03:25 +03:00
# include "libcli/auth/libcli_auth.h"
2006-11-07 03:48:36 +03:00
# include "auth/credentials/credentials.h"
2013-07-31 14:41:40 +04:00
# include "auth/credentials/credentials_internal.h"
2005-10-14 07:57:35 +04:00
2019-06-26 07:41:05 +03:00
# include "lib/crypto/gnutls_helpers.h"
2018-10-30 18:56:54 +03:00
# include <gnutls/gnutls.h>
# include <gnutls/crypto.h>
2017-12-19 12:49:10 +03:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_AUTH
2008-04-02 06:53:27 +04:00
_PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response ( struct cli_credentials * cred , TALLOC_CTX * mem_ctx ,
2005-10-14 07:57:35 +04:00
int * flags ,
2015-11-20 11:29:11 +03:00
DATA_BLOB challenge ,
const NTTIME * server_timestamp ,
DATA_BLOB target_info ,
2005-10-14 07:57:35 +04:00
DATA_BLOB * _lm_response , DATA_BLOB * _nt_response ,
DATA_BLOB * _lm_session_key , DATA_BLOB * _session_key )
{
2016-10-27 14:32:31 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
const char * user = NULL ;
const char * domain = NULL ;
DATA_BLOB lm_response = data_blob_null ;
DATA_BLOB nt_response = data_blob_null ;
DATA_BLOB lm_session_key = data_blob_null ;
DATA_BLOB session_key = data_blob_null ;
const struct samr_Password * nt_hash = NULL ;
2019-11-08 17:40:01 +03:00
int rc ;
2016-10-27 14:32:31 +03:00
2020-08-19 16:46:11 +03:00
if ( cred - > kerberos_state = = CRED_USE_KERBEROS_REQUIRED ) {
2016-10-27 14:32:31 +03:00
TALLOC_FREE ( frame ) ;
return NT_STATUS_INVALID_PARAMETER_MIX ;
}
2005-10-14 07:57:35 +04:00
2008-05-05 06:58:15 +04:00
/* We may already have an NTLM response we prepared earlier.
* This is used for NTLM pass - though authentication */
if ( cred - > nt_response . data | | cred - > lm_response . data ) {
2016-10-27 14:32:31 +03:00
if ( cred - > nt_response . length ! = 0 ) {
nt_response = data_blob_dup_talloc ( frame ,
cred - > nt_response ) ;
if ( nt_response . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
}
2021-12-18 12:40:36 +03:00
if ( cred - > nt_session_key . length ! = 0 ) {
session_key = data_blob_dup_talloc ( frame ,
cred - > nt_session_key ) ;
if ( session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
}
2016-10-27 14:32:31 +03:00
if ( cred - > lm_response . length ! = 0 ) {
lm_response = data_blob_dup_talloc ( frame ,
cred - > lm_response ) ;
if ( lm_response . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
}
2021-12-18 12:40:36 +03:00
if ( cred - > lm_session_key . length ! = 0 ) {
lm_session_key = data_blob_dup_talloc ( frame ,
cred - > lm_session_key ) ;
if ( lm_session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
}
2008-05-05 06:58:15 +04:00
2016-10-27 14:32:31 +03:00
if ( cred - > lm_response . data = = NULL ) {
2008-05-05 06:58:15 +04:00
* flags = * flags & ~ CLI_CRED_LANMAN_AUTH ;
}
2016-10-27 14:32:31 +03:00
goto done ;
2008-05-05 06:58:15 +04:00
}
2016-10-27 14:32:31 +03:00
nt_hash = cli_credentials_get_nt_hash ( cred , frame ) ;
2005-10-14 07:57:35 +04:00
2016-10-27 14:32:31 +03:00
cli_credentials_get_ntlm_username_domain ( cred , frame , & user , & domain ) ;
if ( user = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
if ( domain = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-10-14 07:57:35 +04:00
2005-10-31 03:23:38 +03:00
/* If we are sending a username@realm login (see function
* above ) , then we will not send LM , it will not be
* accepted */
if ( cred - > principal_obtained > cred - > username_obtained ) {
* flags = * flags & ~ CLI_CRED_LANMAN_AUTH ;
}
/* Likewise if we are a machine account (avoid protocol downgrade attacks) */
2005-11-01 16:33:05 +03:00
if ( cred - > machine_account ) {
2005-10-31 03:23:38 +03:00
* flags = * flags & ~ CLI_CRED_LANMAN_AUTH ;
}
2005-10-14 07:57:35 +04:00
if ( ! nt_hash ) {
/* do nothing - blobs are zero length */
/* session key is all zeros */
2016-10-27 14:32:31 +03:00
session_key = data_blob_talloc_zero ( frame , 16 ) ;
if ( session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
lm_session_key = data_blob_talloc_zero ( frame , 16 ) ;
if ( lm_session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-10-14 07:57:35 +04:00
2005-10-27 03:39:04 +04:00
/* not doing NTLM2 without a password */
2005-10-14 07:57:35 +04:00
* flags & = ~ CLI_CRED_NTLM2 ;
} else if ( * flags & CLI_CRED_NTLMv2_AUTH ) {
if ( ! target_info . length ) {
/* be lazy, match win2k - we can't do NTLMv2 without it */
DEBUG ( 1 , ( " Server did not provide 'target information', required for NTLMv2 \n " ) ) ;
2016-10-27 14:32:31 +03:00
TALLOC_FREE ( frame ) ;
2005-10-14 07:57:35 +04:00
return NT_STATUS_INVALID_PARAMETER ;
}
/* TODO: if the remote server is standalone, then we should replace 'domain'
with the server name as supplied above */
2016-10-27 14:32:31 +03:00
if ( ! SMBNTLMv2encrypt_hash ( frame ,
2005-10-14 07:57:35 +04:00
user ,
domain ,
nt_hash - > hash , & challenge ,
2015-11-20 11:31:35 +03:00
server_timestamp , & target_info ,
2005-10-14 07:57:35 +04:00
& lm_response , & nt_response ,
NULL , & session_key ) ) {
2016-10-27 14:32:31 +03:00
TALLOC_FREE ( frame ) ;
2005-10-14 07:57:35 +04:00
return NT_STATUS_NO_MEMORY ;
}
/* LM Key is incompatible... */
* flags & = ~ CLI_CRED_LANMAN_AUTH ;
2015-11-24 23:24:47 +03:00
if ( lm_response . length ! = 0 ) {
/*
* We should not expose the lm key .
*/
memset ( lm_response . data , 0 , lm_response . length ) ;
}
2005-10-14 07:57:35 +04:00
} else if ( * flags & CLI_CRED_NTLM2 ) {
uint8_t session_nonce [ 16 ] ;
uint8_t session_nonce_hash [ 16 ] ;
uint8_t user_session_key [ 16 ] ;
2016-10-27 14:32:31 +03:00
lm_response = data_blob_talloc_zero ( frame , 24 ) ;
if ( lm_response . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-10-14 07:57:35 +04:00
generate_random_buffer ( lm_response . data , 8 ) ;
memcpy ( session_nonce , challenge . data , 8 ) ;
memcpy ( & session_nonce [ 8 ] , lm_response . data , 8 ) ;
2016-10-27 14:32:31 +03:00
2018-10-30 18:56:54 +03:00
rc = gnutls_hash_fast ( GNUTLS_DIG_MD5 ,
session_nonce ,
sizeof ( session_nonce ) ,
session_nonce_hash ) ;
if ( rc < 0 ) {
2019-06-11 16:22:06 +03:00
return gnutls_error_to_ntstatus ( rc , NT_STATUS_NTLM_BLOCKED ) ;
2018-10-30 18:56:54 +03:00
}
2005-10-14 07:57:35 +04:00
DEBUG ( 5 , ( " NTLMSSP challenge set by NTLM2 \n " ) ) ;
DEBUG ( 5 , ( " challenge is: \n " ) ) ;
dump_data ( 5 , session_nonce_hash , 8 ) ;
2016-10-27 14:32:31 +03:00
nt_response = data_blob_talloc_zero ( frame , 24 ) ;
if ( nt_response . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2019-11-08 17:40:01 +03:00
rc = SMBOWFencrypt ( nt_hash - > hash ,
session_nonce_hash ,
nt_response . data ) ;
if ( rc ! = 0 ) {
TALLOC_FREE ( frame ) ;
return gnutls_error_to_ntstatus ( rc , NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ) ;
}
2016-10-27 14:32:31 +03:00
2018-10-30 18:56:54 +03:00
ZERO_ARRAY ( session_nonce_hash ) ;
2016-10-27 14:32:31 +03:00
session_key = data_blob_talloc_zero ( frame , 16 ) ;
if ( session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-10-14 07:57:35 +04:00
SMBsesskeygen_ntv1 ( nt_hash - > hash , user_session_key ) ;
2018-10-30 18:56:54 +03:00
rc = gnutls_hmac_fast ( GNUTLS_MAC_MD5 ,
user_session_key ,
sizeof ( user_session_key ) ,
session_nonce ,
sizeof ( session_nonce ) ,
session_key . data ) ;
if ( rc < 0 ) {
2019-06-11 16:22:06 +03:00
return gnutls_error_to_ntstatus ( rc , NT_STATUS_NTLM_BLOCKED ) ;
2018-10-30 18:56:54 +03:00
}
ZERO_ARRAY ( user_session_key ) ;
2005-10-14 07:57:35 +04:00
dump_data_pw ( " NTLM2 session key: \n " , session_key . data , session_key . length ) ;
/* LM Key is incompatible... */
* flags & = ~ CLI_CRED_LANMAN_AUTH ;
} else {
2016-10-27 14:32:31 +03:00
const char * password = cli_credentials_get_password ( cred ) ;
2006-03-25 04:00:37 +03:00
uint8_t lm_hash [ 16 ] ;
2016-10-27 14:32:31 +03:00
bool do_lm = false ;
nt_response = data_blob_talloc_zero ( frame , 24 ) ;
if ( nt_response . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2019-11-08 17:40:01 +03:00
rc = SMBOWFencrypt ( nt_hash - > hash , challenge . data ,
nt_response . data ) ;
if ( rc ! = 0 ) {
TALLOC_FREE ( frame ) ;
return gnutls_error_to_ntstatus ( rc , NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ) ;
}
2016-10-27 14:32:31 +03:00
session_key = data_blob_talloc_zero ( frame , 16 ) ;
if ( session_key . data = = NULL ) {
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-10-14 07:57:35 +04:00
SMBsesskeygen_ntv1 ( nt_hash - > hash , session_key . data ) ;
dump_data_pw ( " NT session key: \n " , session_key . data , session_key . length ) ;
/* lanman auth is insecure, it may be disabled.
We may also not have a password */
2016-10-27 14:32:31 +03:00
if ( password ! = NULL ) {
do_lm = E_deshash ( password , lm_hash ) ;
}
if ( * flags & CLI_CRED_LANMAN_AUTH & & do_lm ) {
lm_response = data_blob_talloc_zero ( frame , 24 ) ;
if ( lm_response . data = = NULL ) {
ZERO_STRUCT ( lm_hash ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
2005-10-14 07:57:35 +04:00
}
2016-10-27 14:32:31 +03:00
2019-11-08 17:40:01 +03:00
rc = SMBencrypt_hash ( lm_hash ,
challenge . data ,
lm_response . data ) ;
if ( rc ! = 0 ) {
ZERO_STRUCT ( lm_hash ) ;
TALLOC_FREE ( frame ) ;
return gnutls_error_to_ntstatus ( rc , NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ) ;
}
2005-10-14 07:57:35 +04:00
} else {
2016-10-27 14:32:31 +03:00
/* just copy the nt_response */
lm_response = data_blob_dup_talloc ( frame , nt_response ) ;
if ( lm_response . data = = NULL ) {
ZERO_STRUCT ( lm_hash ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
}
2006-03-31 09:33:35 +04:00
2016-10-27 14:32:31 +03:00
if ( do_lm ) {
lm_session_key = data_blob_talloc_zero ( frame , 16 ) ;
if ( lm_session_key . data = = NULL ) {
ZERO_STRUCT ( lm_hash ) ;
TALLOC_FREE ( frame ) ;
return NT_STATUS_NO_MEMORY ;
}
memcpy ( lm_session_key . data , lm_hash , 8 ) ;
2006-03-25 04:00:37 +03:00
2016-10-27 14:32:31 +03:00
if ( ! ( * flags & CLI_CRED_NTLM_AUTH ) ) {
memcpy ( session_key . data , lm_session_key . data , 16 ) ;
2006-03-25 04:00:37 +03:00
}
2016-10-27 14:32:31 +03:00
ZERO_STRUCT ( lm_hash ) ;
2005-10-14 07:57:35 +04:00
}
}
2016-10-27 14:32:31 +03:00
done :
2016-12-07 19:17:44 +03:00
if ( _lm_response ! = NULL ) {
2016-10-27 14:32:31 +03:00
talloc_steal ( mem_ctx , lm_response . data ) ;
2005-10-14 07:57:35 +04:00
* _lm_response = lm_response ;
2016-12-07 19:17:44 +03:00
} else {
data_blob_clear ( & lm_response ) ;
2005-10-14 07:57:35 +04:00
}
2016-12-07 19:17:44 +03:00
if ( _nt_response ! = NULL ) {
2016-10-27 14:32:31 +03:00
talloc_steal ( mem_ctx , nt_response . data ) ;
2005-10-14 07:57:35 +04:00
* _nt_response = nt_response ;
2016-12-07 19:17:44 +03:00
} else {
data_blob_clear ( & nt_response ) ;
2005-10-14 07:57:35 +04:00
}
2016-12-07 19:17:44 +03:00
if ( _lm_session_key ! = NULL ) {
2016-10-27 14:32:31 +03:00
talloc_steal ( mem_ctx , lm_session_key . data ) ;
2005-10-14 07:57:35 +04:00
* _lm_session_key = lm_session_key ;
2016-12-07 19:17:44 +03:00
} else {
data_blob_clear ( & lm_session_key ) ;
2005-10-14 07:57:35 +04:00
}
2016-12-07 19:17:44 +03:00
if ( _session_key ! = NULL ) {
2016-10-27 14:32:31 +03:00
talloc_steal ( mem_ctx , session_key . data ) ;
2005-10-14 07:57:35 +04:00
* _session_key = session_key ;
2016-12-07 19:17:44 +03:00
} else {
data_blob_clear ( & session_key ) ;
2005-10-14 07:57:35 +04:00
}
2016-10-27 14:32:31 +03:00
TALLOC_FREE ( frame ) ;
2005-10-14 07:57:35 +04:00
return NT_STATUS_OK ;
}
2014-12-16 16:58:11 +03:00
/*
* Set a utf16 password on the credentials context , including an indication
* of ' how ' the password was obtained
*
* This is required because the nt_hash is calculated over the raw utf16 blob ,
* which might not be completely valid utf16 , which means the conversion
* from CH_UTF16MUNGED to CH_UTF8 might loose information .
*/
_PUBLIC_ bool cli_credentials_set_utf16_password ( struct cli_credentials * cred ,
const DATA_BLOB * password_utf16 ,
enum credentials_obtained obtained )
{
2016-12-14 12:02:10 +03:00
cred - > password_will_be_nt_hash = false ;
2014-12-16 16:58:11 +03:00
if ( password_utf16 = = NULL ) {
return cli_credentials_set_password ( cred , NULL , obtained ) ;
}
if ( obtained > = cred - > password_obtained ) {
struct samr_Password * nt_hash = NULL ;
char * password_talloc = NULL ;
size_t password_len = 0 ;
bool ok ;
nt_hash = talloc ( cred , struct samr_Password ) ;
if ( nt_hash = = NULL ) {
return false ;
}
ok = convert_string_talloc ( cred ,
CH_UTF16MUNGED , CH_UTF8 ,
password_utf16 - > data ,
password_utf16 - > length ,
( void * ) & password_talloc ,
& password_len ) ;
if ( ! ok ) {
TALLOC_FREE ( nt_hash ) ;
return false ;
}
ok = cli_credentials_set_password ( cred , password_talloc , obtained ) ;
TALLOC_FREE ( password_talloc ) ;
if ( ! ok ) {
TALLOC_FREE ( nt_hash ) ;
return false ;
}
mdfour ( nt_hash - > hash , password_utf16 - > data , password_utf16 - > length ) ;
cred - > nt_hash = nt_hash ;
return true ;
}
return false ;
}
2015-01-30 19:20:27 +03:00
/*
* Set a old utf16 password on the credentials context .
*
* This is required because the nt_hash is calculated over the raw utf16 blob ,
* which might not be completely valid utf16 , which means the conversion
* from CH_UTF16MUNGED to CH_UTF8 might loose information .
*/
_PUBLIC_ bool cli_credentials_set_old_utf16_password ( struct cli_credentials * cred ,
const DATA_BLOB * password_utf16 )
{
struct samr_Password * nt_hash = NULL ;
char * password_talloc = NULL ;
size_t password_len = 0 ;
bool ok ;
if ( password_utf16 = = NULL ) {
return cli_credentials_set_old_password ( cred , NULL , CRED_SPECIFIED ) ;
}
nt_hash = talloc ( cred , struct samr_Password ) ;
if ( nt_hash = = NULL ) {
return false ;
}
ok = convert_string_talloc ( cred ,
CH_UTF16MUNGED , CH_UTF8 ,
password_utf16 - > data ,
password_utf16 - > length ,
( void * ) & password_talloc ,
& password_len ) ;
if ( ! ok ) {
TALLOC_FREE ( nt_hash ) ;
return false ;
}
ok = cli_credentials_set_old_password ( cred , password_talloc , CRED_SPECIFIED ) ;
TALLOC_FREE ( password_talloc ) ;
if ( ! ok ) {
TALLOC_FREE ( nt_hash ) ;
return false ;
}
mdfour ( nt_hash - > hash , password_utf16 - > data , password_utf16 - > length ) ;
cred - > old_nt_hash = nt_hash ;
return true ;
}
2016-12-14 12:02:10 +03:00
_PUBLIC_ void cli_credentials_set_password_will_be_nt_hash ( struct cli_credentials * cred ,
bool val )
{
/*
* We set this here and the next cli_credentials_set_password ( )
* that resets the password or password callback
* will pick this up .
*
* cli_credentials_set_nt_hash ( ) and
* cli_credentials_set_utf16_password ( ) will reset this
* to false .
*/
cred - > password_will_be_nt_hash = val ;
}
2008-05-05 06:58:15 +04:00
_PUBLIC_ bool cli_credentials_set_nt_hash ( struct cli_credentials * cred ,
const struct samr_Password * nt_hash ,
enum credentials_obtained obtained )
{
2016-12-14 12:02:10 +03:00
cred - > password_will_be_nt_hash = false ;
2008-05-05 06:58:15 +04:00
if ( obtained > = cred - > password_obtained ) {
cli_credentials_set_password ( cred , NULL , obtained ) ;
if ( nt_hash ) {
cred - > nt_hash = talloc ( cred , struct samr_Password ) ;
2015-02-09 11:06:32 +03:00
if ( cred - > nt_hash = = NULL ) {
return false ;
}
2008-05-05 06:58:15 +04:00
* cred - > nt_hash = * nt_hash ;
} else {
cred - > nt_hash = NULL ;
}
return true ;
}
return false ;
}
2015-02-09 11:04:42 +03:00
_PUBLIC_ bool cli_credentials_set_old_nt_hash ( struct cli_credentials * cred ,
const struct samr_Password * nt_hash )
{
cli_credentials_set_old_password ( cred , NULL , CRED_SPECIFIED ) ;
if ( nt_hash ) {
cred - > old_nt_hash = talloc ( cred , struct samr_Password ) ;
if ( cred - > old_nt_hash = = NULL ) {
return false ;
}
* cred - > old_nt_hash = * nt_hash ;
} else {
cred - > old_nt_hash = NULL ;
}
return true ;
}
2008-05-05 06:58:15 +04:00
_PUBLIC_ bool cli_credentials_set_ntlm_response ( struct cli_credentials * cred ,
2021-12-18 12:40:36 +03:00
const DATA_BLOB * lm_response ,
const DATA_BLOB * lm_session_key ,
const DATA_BLOB * nt_response ,
const DATA_BLOB * nt_session_key ,
2008-05-05 06:58:15 +04:00
enum credentials_obtained obtained )
{
if ( obtained > = cred - > password_obtained ) {
cli_credentials_set_password ( cred , NULL , obtained ) ;
2021-12-18 12:40:36 +03:00
data_blob_clear_free ( & cred - > lm_response ) ;
data_blob_clear_free ( & cred - > lm_session_key ) ;
data_blob_clear_free ( & cred - > nt_response ) ;
data_blob_clear_free ( & cred - > nt_session_key ) ;
if ( lm_response ! = NULL & & lm_response - > length ! = 0 ) {
cred - > lm_response = data_blob_talloc ( cred ,
lm_response - > data ,
lm_response - > length ) ;
if ( cred - > lm_response . data = = NULL ) {
return false ;
}
2008-05-05 06:58:15 +04:00
}
2021-12-18 12:40:36 +03:00
if ( lm_session_key ! = NULL & & lm_session_key - > length ! = 0 ) {
cred - > lm_session_key = data_blob_talloc ( cred ,
lm_session_key - > data ,
lm_session_key - > length ) ;
if ( cred - > lm_session_key . data = = NULL ) {
return false ;
}
2008-05-05 06:58:15 +04:00
}
2021-12-18 12:40:36 +03:00
if ( nt_response ! = NULL & & nt_response - > length ! = 0 ) {
cred - > nt_response = data_blob_talloc ( cred ,
nt_response - > data ,
nt_response - > length ) ;
if ( cred - > nt_response . data = = NULL ) {
return false ;
}
}
if ( nt_session_key ! = NULL & & nt_session_key - > length ! = 0 ) {
cred - > nt_session_key = data_blob_talloc ( cred ,
nt_session_key - > data ,
nt_session_key - > length ) ;
if ( cred - > nt_session_key . data = = NULL ) {
return false ;
}
}
2008-05-05 06:58:15 +04:00
return true ;
}
return false ;
}