2012-01-30 15:42:39 +04:00
/*
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-04-25 09:03:50 +04:00
( at your option ) any later version .
2012-01-30 15:42:39 +04:00
2005-04-25 09:03:50 +04:00
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 .
2012-01-30 15:42:39 +04:00
2005-04-25 09:03:50 +04:00
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-04-25 09:03:50 +04:00
*/
# include "includes.h"
2009-01-31 13:34:12 +03:00
# include "system/network.h"
2009-12-16 18:41:21 +03:00
# include "lib/tsocket/tsocket.h"
2005-04-25 09:03:50 +04:00
# include "auth/ntlmssp/ntlmssp.h"
2010-05-24 22:03:42 +04:00
# include "../librpc/gen_ndr/ndr_ntlmssp.h"
2011-07-25 10:04:38 +04:00
# include "auth/ntlmssp/ntlmssp_ndr.h"
# include "auth/ntlmssp/ntlmssp_private.h"
2009-04-16 04:17:17 +04:00
# include "../libcli/auth/libcli_auth.h"
2008-09-24 17:30:23 +04:00
# include "../lib/crypto/crypto.h"
2006-11-07 03:48:36 +03:00
# include "auth/gensec/gensec.h"
2013-08-05 09:12:01 +04:00
# include "auth/gensec/gensec_internal.h"
2012-01-30 15:42:39 +04:00
# include "auth/common_auth.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2005-04-25 09:03:50 +04:00
2010-08-06 11:53:44 +04:00
2012-01-30 15:42:39 +04:00
/**
2005-04-25 09:03:50 +04:00
* Return the credentials of a logged on user , including session keys
* etc .
*
* Only valid after a successful authentication
*
* May only be called once per authentication .
*
*/
NTSTATUS gensec_ntlmssp_session_info ( struct gensec_security * gensec_security ,
2011-08-01 09:39:01 +04:00
TALLOC_CTX * mem_ctx ,
2012-01-30 15:42:39 +04:00
struct auth_session_info * * session_info )
2005-04-25 09:03:50 +04:00
{
NTSTATUS nt_status ;
2009-12-29 19:56:56 +03:00
struct gensec_ntlmssp_context * gensec_ntlmssp =
2009-12-30 10:23:13 +03:00
talloc_get_type_abort ( gensec_security - > private_data ,
2009-12-29 19:56:56 +03:00
struct gensec_ntlmssp_context ) ;
2012-01-30 04:53:04 +04:00
uint32_t session_info_flags = 0 ;
if ( gensec_security - > want_features & GENSEC_FEATURE_UNIX_TOKEN ) {
session_info_flags | = AUTH_SESSION_INFO_UNIX_TOKEN ;
}
session_info_flags | = AUTH_SESSION_INFO_DEFAULT_GROUPS ;
if ( gensec_security - > auth_context & & gensec_security - > auth_context - > generate_session_info ) {
2012-02-04 10:49:49 +04:00
nt_status = gensec_security - > auth_context - > generate_session_info ( gensec_security - > auth_context , mem_ctx ,
2012-01-30 04:53:04 +04:00
gensec_ntlmssp - > server_returned_info ,
2012-01-30 14:49:33 +04:00
gensec_ntlmssp - > ntlmssp_state - > user ,
2012-01-30 04:53:04 +04:00
session_info_flags ,
session_info ) ;
} else {
DEBUG ( 0 , ( " Cannot generate a session_info without the auth_context \n " ) ) ;
return NT_STATUS_INTERNAL_ERROR ;
}
2012-01-30 15:42:39 +04:00
2005-04-25 09:03:50 +04:00
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2012-01-31 11:14:19 +04:00
nt_status = gensec_ntlmssp_session_key ( gensec_security , * session_info ,
& ( * session_info ) - > session_key ) ;
if ( NT_STATUS_EQUAL ( nt_status , NT_STATUS_NO_USER_SESSION_KEY ) ) {
( * session_info ) - > session_key = data_blob_null ;
nt_status = NT_STATUS_OK ;
}
return nt_status ;
2005-04-25 14:33:00 +04:00
}
/**
2012-01-30 15:42:39 +04:00
* Start NTLMSSP on the server side
2005-04-25 14:33:00 +04:00
*
*/
NTSTATUS gensec_ntlmssp_server_start ( struct gensec_security * gensec_security )
{
NTSTATUS nt_status ;
2009-12-30 19:57:54 +03:00
struct ntlmssp_state * ntlmssp_state ;
2009-12-29 19:56:56 +03:00
struct gensec_ntlmssp_context * gensec_ntlmssp ;
2012-01-31 09:17:04 +04:00
const char * netbios_name ;
const char * netbios_domain ;
const char * dns_name ;
const char * dns_domain ;
2005-04-25 14:33:00 +04:00
nt_status = gensec_ntlmssp_start ( gensec_security ) ;
NT_STATUS_NOT_OK_RETURN ( nt_status ) ;
2011-07-26 06:32:08 +04:00
gensec_ntlmssp =
talloc_get_type_abort ( gensec_security - > private_data ,
struct gensec_ntlmssp_context ) ;
ntlmssp_state = talloc_zero ( gensec_ntlmssp ,
struct ntlmssp_state ) ;
if ( ! ntlmssp_state ) {
return NT_STATUS_NO_MEMORY ;
}
gensec_ntlmssp - > ntlmssp_state = ntlmssp_state ;
2009-12-30 19:57:54 +03:00
ntlmssp_state - > role = NTLMSSP_SERVER ;
2005-04-25 14:33:00 +04:00
2009-12-30 19:57:54 +03:00
ntlmssp_state - > expected_state = NTLMSSP_NEGOTIATE ;
2005-04-25 14:33:00 +04:00
2012-01-31 08:57:06 +04:00
if ( lpcfg_lanman_auth ( gensec_security - > settings - > lp_ctx ) & &
gensec_setting_bool ( gensec_security - > settings ,
" ntlmssp_server " , " allow_lm_key " , false ) )
{
ntlmssp_state - > allow_lm_key = true ;
}
2005-04-25 14:33:00 +04:00
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags =
2009-08-25 14:12:59 +04:00
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION ;
2005-04-25 14:33:00 +04:00
2008-11-02 04:05:48 +03:00
if ( gensec_setting_bool ( gensec_security - > settings , " ntlmssp_server " , " 128bit " , true ) ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_128 ;
2005-04-25 14:33:00 +04:00
}
2008-11-02 04:05:48 +03:00
if ( gensec_setting_bool ( gensec_security - > settings , " ntlmssp_server " , " 56bit " , true ) ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_56 ;
2006-07-12 04:02:50 +04:00
}
2008-11-02 04:05:48 +03:00
if ( gensec_setting_bool ( gensec_security - > settings , " ntlmssp_server " , " keyexchange " , true ) ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_KEY_EXCH ;
2005-04-25 14:33:00 +04:00
}
2008-11-02 04:05:48 +03:00
if ( gensec_setting_bool ( gensec_security - > settings , " ntlmssp_server " , " alwayssign " , true ) ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_ALWAYS_SIGN ;
2006-11-20 23:58:00 +03:00
}
2008-11-02 04:05:48 +03:00
if ( gensec_setting_bool ( gensec_security - > settings , " ntlmssp_server " , " ntlm2 " , true ) ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_NTLM2 ;
2005-04-25 14:33:00 +04:00
}
2012-01-31 08:40:53 +04:00
if ( gensec_security - > want_features & GENSEC_FEATURE_SESSION_KEY ) {
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SIGN ;
}
2005-04-25 14:33:00 +04:00
if ( gensec_security - > want_features & GENSEC_FEATURE_SIGN ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SIGN ;
2005-04-25 14:33:00 +04:00
}
if ( gensec_security - > want_features & GENSEC_FEATURE_SEAL ) {
2011-10-15 06:19:41 +04:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SIGN ;
2009-12-30 19:57:54 +03:00
ntlmssp_state - > neg_flags | = NTLMSSP_NEGOTIATE_SEAL ;
2005-04-25 14:33:00 +04:00
}
2010-07-16 08:32:42 +04:00
if ( lpcfg_server_role ( gensec_security - > settings - > lp_ctx ) = = ROLE_STANDALONE ) {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > server . is_standalone = true ;
2009-12-30 12:14:07 +03:00
} else {
2009-12-30 19:57:54 +03:00
ntlmssp_state - > server . is_standalone = false ;
2009-12-30 12:14:07 +03:00
}
2005-04-25 09:03:50 +04:00
2012-02-06 11:02:11 +04:00
if ( gensec_security - > settings - > server_netbios_name ) {
netbios_name = gensec_security - > settings - > server_netbios_name ;
} else {
netbios_name = lpcfg_netbios_name ( gensec_security - > settings - > lp_ctx ) ;
}
if ( gensec_security - > settings - > server_netbios_domain ) {
netbios_domain = gensec_security - > settings - > server_netbios_domain ;
} else {
netbios_domain = lpcfg_workgroup ( gensec_security - > settings - > lp_ctx ) ;
}
2009-12-30 17:14:38 +03:00
2012-01-31 09:17:04 +04:00
if ( gensec_security - > settings - > server_dns_name ) {
dns_name = gensec_security - > settings - > server_dns_name ;
} else {
2011-05-07 12:37:24 +04:00
const char * dnsdomain = lpcfg_dnsdomain ( gensec_security - > settings - > lp_ctx ) ;
2012-01-31 09:17:04 +04:00
char * lower_netbiosname ;
lower_netbiosname = strlower_talloc ( ntlmssp_state , netbios_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( lower_netbiosname ) ;
2009-12-30 17:14:38 +03:00
/* Find out the DNS host name */
2011-05-03 06:16:16 +04:00
if ( dnsdomain & & dnsdomain [ 0 ] ! = ' \0 ' ) {
2012-01-31 09:17:04 +04:00
dns_name = talloc_asprintf ( ntlmssp_state , " %s.%s " ,
lower_netbiosname ,
dnsdomain ) ;
2011-05-03 06:16:16 +04:00
talloc_free ( lower_netbiosname ) ;
2012-01-31 09:17:04 +04:00
NT_STATUS_HAVE_NO_MEMORY ( dns_name ) ;
2011-05-03 06:16:16 +04:00
} else {
2012-01-31 09:17:04 +04:00
dns_name = lower_netbiosname ;
2009-12-30 17:14:38 +03:00
}
2012-01-31 09:17:04 +04:00
}
2009-12-30 17:14:38 +03:00
2012-01-31 09:17:04 +04:00
if ( gensec_security - > settings - > server_dns_domain ) {
dns_domain = gensec_security - > settings - > server_dns_domain ;
} else {
dns_domain = lpcfg_dnsdomain ( gensec_security - > settings - > lp_ctx ) ;
2009-12-30 17:14:38 +03:00
}
2012-01-31 09:17:04 +04:00
ntlmssp_state - > server . netbios_name = talloc_strdup ( ntlmssp_state , netbios_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( ntlmssp_state - > server . netbios_name ) ;
ntlmssp_state - > server . netbios_domain = talloc_strdup ( ntlmssp_state , netbios_domain ) ;
NT_STATUS_HAVE_NO_MEMORY ( ntlmssp_state - > server . netbios_domain ) ;
ntlmssp_state - > server . dns_name = talloc_strdup ( ntlmssp_state , dns_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( ntlmssp_state - > server . dns_name ) ;
ntlmssp_state - > server . dns_domain = talloc_strdup ( ntlmssp_state , dns_domain ) ;
NT_STATUS_HAVE_NO_MEMORY ( ntlmssp_state - > server . dns_domain ) ;
2005-04-25 09:03:50 +04:00
return NT_STATUS_OK ;
}
2012-01-31 09:17:04 +04:00