2005-04-25 09:03:50 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
handle NLTMSSP , client server side parsing
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# include "auth/auth.h"
# include "auth/ntlmssp/ntlmssp.h"
# include "lib/crypto/crypto.h"
2005-06-17 17:12:13 +04:00
# include "librpc/gen_ndr/ndr_samr.h" /* for struct samrPassword */
2005-04-25 09:03:50 +04:00
/*********************************************************************
Client side NTLMSSP
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* Next state function for the Initial packet
*
* @ param ntlmssp_state NTLMSSP State
* @ param out_mem_ctx The DATA_BLOB * out will be allocated on this context
2005-04-25 14:33:00 +04:00
* @ param in A NULL data blob ( input ignored )
* @ param out The initial negotiate request to the server , as an talloc ( ) ed DATA_BLOB , on out_mem_ctx
2005-04-25 09:03:50 +04:00
* @ return Errors or NT_STATUS_OK .
*/
2005-04-25 10:33:20 +04:00
NTSTATUS ntlmssp_client_initial ( struct gensec_security * gensec_security ,
2005-04-25 09:03:50 +04:00
TALLOC_CTX * out_mem_ctx ,
DATA_BLOB in , DATA_BLOB * out )
{
2005-04-25 10:33:20 +04:00
struct gensec_ntlmssp_state * gensec_ntlmssp_state = gensec_security - > private_data ;
2005-04-25 14:33:00 +04:00
if ( gensec_ntlmssp_state - > unicode ) {
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_UNICODE ;
2005-04-25 09:03:50 +04:00
} else {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_OEM ;
2005-04-25 09:03:50 +04:00
}
2005-04-25 14:33:00 +04:00
if ( gensec_ntlmssp_state - > use_ntlmv2 ) {
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_NTLM2 ;
2005-04-25 09:03:50 +04:00
}
/* generate the ntlmssp negotiate packet */
msrpc_gen ( out_mem_ctx ,
out , " CddAA " ,
" NTLMSSP " ,
NTLMSSP_NEGOTIATE ,
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags ,
gensec_ntlmssp_state - > get_domain ( ) ,
2005-04-25 10:33:20 +04:00
cli_credentials_get_workstation ( gensec_security - > credentials ) ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > expected_state = NTLMSSP_CHALLENGE ;
2005-04-25 09:03:50 +04:00
return NT_STATUS_MORE_PROCESSING_REQUIRED ;
}
/**
* Next state function for the Challenge Packet . Generate an auth packet .
*
2005-04-25 14:33:00 +04:00
* @ param gensec_security GENSEC state
* @ param out_mem_ctx Memory context for * out
* @ param in The server challnege , as a DATA_BLOB . reply . data must be NULL
* @ param out The next request ( auth packet ) to the server , as an allocated DATA_BLOB , on the out_mem_ctx context
2005-04-25 09:03:50 +04:00
* @ return Errors or NT_STATUS_OK .
*/
2005-04-25 10:33:20 +04:00
NTSTATUS ntlmssp_client_challenge ( struct gensec_security * gensec_security ,
2005-04-25 09:03:50 +04:00
TALLOC_CTX * out_mem_ctx ,
const DATA_BLOB in , DATA_BLOB * out )
{
2005-04-25 10:33:20 +04:00
struct gensec_ntlmssp_state * gensec_ntlmssp_state = gensec_security - > private_data ;
2005-04-25 09:03:50 +04:00
uint32_t chal_flags , ntlmssp_command , unkn1 , unkn2 ;
DATA_BLOB server_domain_blob ;
DATA_BLOB challenge_blob ;
DATA_BLOB struct_blob = data_blob ( NULL , 0 ) ;
char * server_domain ;
const char * chal_parse_string ;
const char * auth_gen_string ;
uint8_t lm_hash [ 16 ] ;
DATA_BLOB lm_response = data_blob ( NULL , 0 ) ;
DATA_BLOB nt_response = data_blob ( NULL , 0 ) ;
DATA_BLOB session_key = data_blob ( NULL , 0 ) ;
DATA_BLOB lm_session_key = data_blob ( NULL , 0 ) ;
DATA_BLOB encrypted_session_key = data_blob ( NULL , 0 ) ;
NTSTATUS nt_status ;
2005-06-17 17:12:13 +04:00
const struct samr_Password * nt_hash ;
2005-04-25 10:33:20 +04:00
const char * user , * domain , * password ;
2005-04-25 14:33:00 +04:00
if ( ! msrpc_parse ( out_mem_ctx ,
2005-04-25 09:03:50 +04:00
& in , " CdBd " ,
" NTLMSSP " ,
& ntlmssp_command ,
& server_domain_blob ,
& chal_flags ) ) {
DEBUG ( 1 , ( " Failed to parse the NTLMSSP Challenge: (#1) \n " ) ) ;
dump_data ( 2 , in . data , in . length ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
data_blob_free ( & server_domain_blob ) ;
DEBUG ( 3 , ( " Got challenge flags: \n " ) ) ;
debug_ntlmssp_flags ( chal_flags ) ;
2005-04-25 14:33:00 +04:00
ntlmssp_handle_neg_flags ( gensec_ntlmssp_state , chal_flags , gensec_ntlmssp_state - > allow_lm_key ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
if ( gensec_ntlmssp_state - > unicode ) {
2005-04-25 09:03:50 +04:00
if ( chal_flags & NTLMSSP_CHAL_TARGET_INFO ) {
chal_parse_string = " CdUdbddB " ;
} else {
chal_parse_string = " CdUdbdd " ;
}
auth_gen_string = " CdBBUUUBd " ;
} else {
if ( chal_flags & NTLMSSP_CHAL_TARGET_INFO ) {
chal_parse_string = " CdAdbddB " ;
} else {
chal_parse_string = " CdAdbdd " ;
}
auth_gen_string = " CdBBAAABd " ;
}
DEBUG ( 3 , ( " NTLMSSP: Set final flags: \n " ) ) ;
2005-04-25 14:33:00 +04:00
debug_ntlmssp_flags ( gensec_ntlmssp_state - > neg_flags ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
if ( ! msrpc_parse ( out_mem_ctx ,
2005-04-25 09:03:50 +04:00
& in , chal_parse_string ,
" NTLMSSP " ,
& ntlmssp_command ,
& server_domain ,
& chal_flags ,
& challenge_blob , 8 ,
& unkn1 , & unkn2 ,
& struct_blob ) ) {
DEBUG ( 1 , ( " Failed to parse the NTLMSSP Challenge: (#2) \n " ) ) ;
dump_data ( 2 , in . data , in . length ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > server_domain = server_domain ;
2005-04-25 09:03:50 +04:00
if ( challenge_blob . length ! = 8 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2005-09-22 05:50:58 +04:00
cli_credentials_get_ntlm_username_domain ( gensec_security - > credentials , out_mem_ctx ,
& user , & domain ) ;
2005-04-25 10:33:20 +04:00
2005-06-17 17:12:13 +04:00
nt_hash = cli_credentials_get_nt_hash ( gensec_security - > credentials , out_mem_ctx ) ;
2005-04-25 10:33:20 +04:00
2005-06-17 17:12:13 +04:00
if ( ! nt_hash ) {
2005-04-25 09:03:50 +04:00
static const uint8_t zeros [ 16 ] ;
/* do nothing - blobs are zero length */
/* session key is all zeros */
2005-04-25 14:33:00 +04:00
session_key = data_blob_talloc ( gensec_ntlmssp_state , zeros , 16 ) ;
lm_session_key = data_blob_talloc ( gensec_ntlmssp_state , zeros , 16 ) ;
2005-04-25 09:03:50 +04:00
2005-04-30 12:09:47 +04:00
lm_response = data_blob ( NULL , 0 ) ;
2005-04-26 11:21:34 +04:00
nt_response = data_blob ( NULL , 0 ) ;
2005-04-25 09:03:50 +04:00
/* not doing NLTM2 without a password */
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags & = ~ NTLMSSP_NEGOTIATE_NTLM2 ;
} else if ( gensec_ntlmssp_state - > use_ntlmv2 ) {
2005-04-25 09:03:50 +04:00
if ( ! struct_blob . length ) {
/* be lazy, match win2k - we can't do NTLMv2 without it */
DEBUG ( 1 , ( " Server did not provide 'target information', required for NTLMv2 \n " ) ) ;
return NT_STATUS_INVALID_PARAMETER ;
}
/* TODO: if the remote server is standalone, then we should replace 'domain'
with the server name as supplied above */
2005-06-19 17:26:32 +04:00
if ( ! SMBNTLMv2encrypt_hash ( gensec_ntlmssp_state ,
user ,
2005-06-17 17:12:13 +04:00
domain ,
nt_hash - > hash , & challenge_blob ,
& struct_blob ,
& lm_response , & nt_response ,
NULL , & session_key ) ) {
2005-04-25 09:03:50 +04:00
data_blob_free ( & challenge_blob ) ;
data_blob_free ( & struct_blob ) ;
return NT_STATUS_NO_MEMORY ;
}
/* LM Key is incompatible... */
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags & = ~ NTLMSSP_NEGOTIATE_LM_KEY ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
} else if ( gensec_ntlmssp_state - > neg_flags & NTLMSSP_NEGOTIATE_NTLM2 ) {
2005-04-25 09:03:50 +04:00
struct MD5Context md5_session_nonce_ctx ;
uint8_t session_nonce [ 16 ] ;
uint8_t session_nonce_hash [ 16 ] ;
uint8_t user_session_key [ 16 ] ;
2005-04-25 14:33:00 +04:00
lm_response = data_blob_talloc ( gensec_ntlmssp_state , NULL , 24 ) ;
2005-04-25 09:03:50 +04:00
generate_random_buffer ( lm_response . data , 8 ) ;
memset ( lm_response . data + 8 , 0 , 16 ) ;
memcpy ( session_nonce , challenge_blob . data , 8 ) ;
memcpy ( & session_nonce [ 8 ] , lm_response . data , 8 ) ;
MD5Init ( & md5_session_nonce_ctx ) ;
MD5Update ( & md5_session_nonce_ctx , challenge_blob . data , 8 ) ;
MD5Update ( & md5_session_nonce_ctx , lm_response . data , 8 ) ;
MD5Final ( session_nonce_hash , & md5_session_nonce_ctx ) ;
DEBUG ( 5 , ( " NTLMSSP challenge set by NTLM2 \n " ) ) ;
DEBUG ( 5 , ( " challenge is: \n " ) ) ;
dump_data ( 5 , session_nonce_hash , 8 ) ;
2005-04-25 14:33:00 +04:00
nt_response = data_blob_talloc ( gensec_ntlmssp_state , NULL , 24 ) ;
2005-06-17 17:12:13 +04:00
SMBOWFencrypt ( nt_hash - > hash ,
session_nonce_hash ,
nt_response . data ) ;
2005-04-25 14:33:00 +04:00
session_key = data_blob_talloc ( gensec_ntlmssp_state , NULL , 16 ) ;
2005-04-25 09:03:50 +04:00
2005-06-17 17:12:13 +04:00
SMBsesskeygen_ntv1 ( nt_hash - > hash , user_session_key ) ;
2005-04-25 09:03:50 +04:00
hmac_md5 ( user_session_key , session_nonce , sizeof ( session_nonce ) , session_key . data ) ;
dump_data_pw ( " NTLM2 session key: \n " , session_key . data , session_key . length ) ;
/* LM Key is incompatible... */
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags & = ~ NTLMSSP_NEGOTIATE_LM_KEY ;
2005-04-25 09:03:50 +04:00
} else {
2005-04-25 14:33:00 +04:00
if ( gensec_ntlmssp_state - > use_nt_response ) {
nt_response = data_blob_talloc ( gensec_ntlmssp_state , NULL , 24 ) ;
2005-06-17 17:12:13 +04:00
SMBOWFencrypt ( nt_hash - > hash , challenge_blob . data ,
nt_response . data ) ;
2005-04-25 14:33:00 +04:00
session_key = data_blob_talloc ( gensec_ntlmssp_state , NULL , 16 ) ;
2005-06-17 17:12:13 +04:00
SMBsesskeygen_ntv1 ( nt_hash - > hash , session_key . data ) ;
2005-04-25 09:03:50 +04:00
dump_data_pw ( " NT session key: \n " , session_key . data , session_key . length ) ;
}
2005-06-17 17:12:13 +04:00
/* lanman auth is insecure, it may be disabled. We may also not have a password */
2005-08-29 08:30:22 +04:00
if ( lp_client_lanman_auth ( ) ) {
password = cli_credentials_get_password ( gensec_security - > credentials ) ;
if ( ! password ) {
lm_response = nt_response ;
2005-04-25 09:03:50 +04:00
} else {
2005-08-29 08:30:22 +04:00
lm_response = data_blob_talloc ( gensec_ntlmssp_state , NULL , 24 ) ;
if ( ! SMBencrypt ( password , challenge_blob . data ,
lm_response . data ) ) {
/* If the LM password was too long (and therefore the LM hash being
of the first 14 chars only ) , don ' t send it */
data_blob_free ( & lm_response ) ;
/* LM Key is incompatible with 'long' passwords */
gensec_ntlmssp_state - > neg_flags & = ~ NTLMSSP_NEGOTIATE_LM_KEY ;
} else {
E_deshash ( password , lm_hash ) ;
lm_session_key = data_blob_talloc ( gensec_ntlmssp_state , NULL , 16 ) ;
memcpy ( lm_session_key . data , lm_hash , 8 ) ;
memset ( & lm_session_key . data [ 8 ] , ' \0 ' , 8 ) ;
if ( ! gensec_ntlmssp_state - > use_nt_response ) {
2005-04-25 09:03:50 +04:00
session_key = lm_session_key ;
2005-08-29 08:30:22 +04:00
}
2005-04-25 09:03:50 +04:00
}
}
} else {
/* LM Key is incompatible... */
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags & = ~ NTLMSSP_NEGOTIATE_LM_KEY ;
2005-04-25 09:03:50 +04:00
}
}
2005-04-25 14:33:00 +04:00
if ( ( gensec_ntlmssp_state - > neg_flags & NTLMSSP_NEGOTIATE_LM_KEY )
2005-04-25 09:03:50 +04:00
& & lp_client_lanman_auth ( ) & & lm_session_key . length = = 16 ) {
2005-04-25 14:33:00 +04:00
DATA_BLOB new_session_key = data_blob_talloc ( gensec_ntlmssp_state , NULL , 16 ) ;
2005-04-25 09:03:50 +04:00
if ( lm_response . length = = 24 ) {
SMBsesskeygen_lm_sess_key ( lm_session_key . data , lm_response . data ,
new_session_key . data ) ;
} else {
static const uint8_t zeros [ 24 ] ;
SMBsesskeygen_lm_sess_key ( lm_session_key . data , zeros ,
new_session_key . data ) ;
}
new_session_key . length = 16 ;
session_key = new_session_key ;
dump_data_pw ( " LM session key \n " , session_key . data , session_key . length ) ;
}
/* Key exchange encryptes a new client-generated session key with
the password - derived key */
2005-04-25 14:33:00 +04:00
if ( gensec_ntlmssp_state - > neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH ) {
2005-04-25 09:03:50 +04:00
/* Make up a new session key */
uint8_t client_session_key [ 16 ] ;
generate_random_buffer ( client_session_key , sizeof ( client_session_key ) ) ;
/* Encrypt the new session key with the old one */
2005-04-25 14:33:00 +04:00
encrypted_session_key = data_blob_talloc ( gensec_ntlmssp_state ,
2005-04-25 09:03:50 +04:00
client_session_key , sizeof ( client_session_key ) ) ;
dump_data_pw ( " KEY_EXCH session key: \n " , encrypted_session_key . data , encrypted_session_key . length ) ;
arcfour_crypt ( encrypted_session_key . data , session_key . data , encrypted_session_key . length ) ;
dump_data_pw ( " KEY_EXCH session key (enc): \n " , encrypted_session_key . data , encrypted_session_key . length ) ;
/* Mark the new session key as the 'real' session key */
2005-04-25 14:33:00 +04:00
session_key = data_blob_talloc ( gensec_ntlmssp_state , client_session_key , sizeof ( client_session_key ) ) ;
2005-04-25 09:03:50 +04:00
}
/* this generates the actual auth packet */
if ( ! msrpc_gen ( out_mem_ctx ,
out , auth_gen_string ,
" NTLMSSP " ,
NTLMSSP_AUTH ,
lm_response . data , lm_response . length ,
nt_response . data , nt_response . length ,
2005-04-25 10:33:20 +04:00
domain ,
user ,
cli_credentials_get_workstation ( gensec_security - > credentials ) ,
2005-04-25 09:03:50 +04:00
encrypted_session_key . data , encrypted_session_key . length ,
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags ) ) {
2005-04-25 09:03:50 +04:00
return NT_STATUS_NO_MEMORY ;
}
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > session_key = session_key ;
2005-04-25 09:03:50 +04:00
/* The client might be using 56 or 40 bit weakened keys */
2005-04-25 14:33:00 +04:00
ntlmssp_weaken_keys ( gensec_ntlmssp_state ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > chal = challenge_blob ;
gensec_ntlmssp_state - > lm_resp = lm_response ;
gensec_ntlmssp_state - > nt_resp = nt_response ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > expected_state = NTLMSSP_DONE ;
2005-04-25 09:03:50 +04:00
2005-08-29 08:30:22 +04:00
if ( gensec_security - > want_features & ( GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL ) ) {
2005-08-23 09:29:37 +04:00
nt_status = ntlmssp_sign_init ( gensec_ntlmssp_state ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
DEBUG ( 1 , ( " Could not setup NTLMSSP signing/sealing system (error was: %s) \n " ,
nt_errstr ( nt_status ) ) ) ;
return nt_status ;
}
2005-04-25 09:03:50 +04:00
}
2005-08-29 08:30:22 +04:00
return NT_STATUS_OK ;
2005-04-25 09:03:50 +04:00
}
2005-04-25 14:33:00 +04:00
NTSTATUS gensec_ntlmssp_client_start ( struct gensec_security * gensec_security )
2005-04-25 09:03:50 +04:00
{
2005-04-25 14:33:00 +04:00
struct gensec_ntlmssp_state * gensec_ntlmssp_state ;
NTSTATUS nt_status ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
nt_status = gensec_ntlmssp_start ( gensec_security ) ;
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
gensec_ntlmssp_state = gensec_security - > private_data ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > role = NTLMSSP_CLIENT ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > get_domain = lp_workgroup ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > unicode = lp_parm_bool ( - 1 , " ntlmssp_client " , " unicode " , True ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > use_nt_response = lp_parm_bool ( - 1 , " ntlmssp_client " , " send_nt_reponse " , True ) ;
gensec_ntlmssp_state - > allow_lm_key = ( lp_lanman_auth ( )
2005-04-25 09:03:50 +04:00
& & lp_parm_bool ( - 1 , " ntlmssp_client " , " allow_lm_key " , False ) ) ;
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > use_ntlmv2 = lp_client_ntlmv2_auth ( ) ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > expected_state = NTLMSSP_INITIAL ;
2005-04-25 09:03:50 +04:00
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags =
2005-04-25 09:03:50 +04:00
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_REQUEST_TARGET ;
if ( lp_parm_bool ( - 1 , " ntlmssp_client " , " 128bit " , True ) ) {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_128 ;
2005-04-25 09:03:50 +04:00
}
if ( lp_parm_bool ( - 1 , " ntlmssp_client " , " keyexchange " , True ) ) {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_KEY_EXCH ;
2005-04-25 09:03:50 +04:00
}
if ( lp_parm_bool ( - 1 , " ntlmssp_client " , " ntlm2 " , True ) ) {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_NTLM2 ;
2005-04-25 09:03:50 +04:00
} else {
/* apparently we can't do ntlmv2 if we don't do ntlm2 */
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > use_ntlmv2 = False ;
2005-04-25 09:03:50 +04:00
}
if ( gensec_security - > want_features & GENSEC_FEATURE_SESSION_KEY ) {
/*
* We need to set this to allow a later SetPassword
* via the SAMR pipe to succeed . Strange . . . . We could
* also add NTLMSSP_NEGOTIATE_SEAL here . JRA .
*
* Without this , Windows will not create the master key
* that it thinks is only used for NTLMSSP signing and
* sealing . ( It is actually pulled out and used directly )
*/
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SIGN ;
2005-04-25 09:03:50 +04:00
}
if ( gensec_security - > want_features & GENSEC_FEATURE_SIGN ) {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SIGN ;
2005-04-25 09:03:50 +04:00
}
if ( gensec_security - > want_features & GENSEC_FEATURE_SEAL ) {
2005-04-25 14:33:00 +04:00
gensec_ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SEAL ;
2005-04-25 09:03:50 +04:00
}
gensec_security - > private_data = gensec_ntlmssp_state ;
return NT_STATUS_OK ;
}