2009-12-23 15:17:16 -05:00
/*
2005-06-03 11:23:15 +00:00
Unix SMB / CIFS implementation .
KDC Server startup
2008-09-05 16:45:58 +10:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2005 - 2008
2005-06-03 11:23:15 +00:00
Copyright ( C ) Andrew Tridgell 2005
2005-10-14 06:12:05 +00:00
Copyright ( C ) Stefan Metzmacher 2005
2005-06-03 11:23:15 +00:00
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 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2005-06-03 11:23:15 +00:00
( at your option ) any later version .
2009-12-23 15:17:16 -05:00
2005-06-03 11:23:15 +00: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 .
2009-12-23 15:17:16 -05:00
2005-06-03 11:23:15 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-06-03 11:23:15 +00:00
*/
# include "includes.h"
2020-11-20 15:27:17 +01:00
# include "samba/process_model.h"
2009-12-15 12:58:40 +01:00
# include "lib/tsocket/tsocket.h"
2005-07-19 09:27:20 +00:00
# include "lib/messaging/irpc.h"
2008-09-03 15:30:17 +10:00
# include "librpc/gen_ndr/ndr_irpc.h"
# include "librpc/gen_ndr/ndr_krb5pac.h"
2006-08-17 13:37:04 +00:00
# include "lib/socket/netif.h"
2007-09-08 12:42:09 +00:00
# include "param/param.h"
2016-06-10 11:10:50 +02:00
# include "kdc/kdc-server.h"
2016-06-13 11:20:44 +02:00
# include "kdc/kdc-proxy.h"
2010-11-11 14:09:41 +11:00
# include "kdc/kdc-glue.h"
2012-01-11 18:06:55 +11:00
# include "kdc/pac-glue.h"
2016-09-07 16:38:06 +02:00
# include "kdc/kpasswd-service.h"
2010-11-12 17:23:34 +11:00
# include "dsdb/samdb/samdb.h"
# include "auth/session.h"
2015-12-28 19:01:54 +00:00
# include "libds/common/roles.h"
2016-06-10 09:42:33 +02:00
# include <kdc.h>
# include <hdb.h>
2007-01-10 01:51:35 +00:00
2022-09-09 12:32:57 +02:00
# undef DBGC_CLASS
# define DBGC_CLASS DBGC_KERBEROS
2017-04-20 12:24:43 -07:00
NTSTATUS server_service_kdc_init ( TALLOC_CTX * ) ;
2011-03-19 00:43:50 +01:00
2022-02-22 14:39:13 +13:00
extern struct krb5plugin_kdc_ftable kdc_plugin_table ;
2006-02-03 23:19:00 +00:00
2005-10-21 01:25:55 +00:00
/**
Wrapper for krb5_kdc_process_krb5_request , converting to / from Samba
calling conventions
*/
2016-06-10 09:50:45 +02:00
static kdc_code kdc_process ( struct kdc_server * kdc ,
TALLOC_CTX * mem_ctx ,
DATA_BLOB * input ,
DATA_BLOB * reply ,
struct tsocket_address * peer_addr ,
struct tsocket_address * my_addr ,
int datagram_reply )
2005-10-21 01:25:55 +00:00
{
2009-12-15 12:58:40 +01:00
int ret ;
char * pa ;
struct sockaddr_storage ss ;
2005-10-21 01:25:55 +00:00
krb5_data k5_reply ;
2016-06-10 09:42:33 +02:00
krb5_kdc_configuration * kdc_config =
( krb5_kdc_configuration * ) kdc - > private_data ;
2006-11-07 06:59:56 +00:00
krb5_data_zero ( & k5_reply ) ;
2006-01-09 22:12:53 +00:00
2007-06-13 05:44:24 +00:00
krb5_kdc_update_time ( NULL ) ;
2009-12-15 12:58:40 +01:00
ret = tsocket_address_bsd_sockaddr ( peer_addr , ( struct sockaddr * ) & ss ,
sizeof ( struct sockaddr_storage ) ) ;
if ( ret < 0 ) {
2016-06-10 09:50:45 +02:00
return KDC_ERROR ;
2009-12-15 12:58:40 +01:00
}
pa = tsocket_address_string ( peer_addr , mem_ctx ) ;
if ( pa = = NULL ) {
2016-06-10 09:50:45 +02:00
return KDC_ERROR ;
2009-12-15 12:58:40 +01:00
}
2023-08-10 16:17:06 +12:00
DBG_DEBUG ( " Received KDC packet of length %zu from %s \n " ,
2023-08-10 16:17:51 +12:00
input - > length , pa ) ;
2005-10-21 01:25:55 +00:00
2009-12-23 15:17:16 -05:00
ret = krb5_kdc_process_krb5_request ( kdc - > smb_krb5_context - > krb5_context ,
2016-06-10 09:42:33 +02:00
kdc_config ,
2005-10-21 01:25:55 +00:00
input - > data , input - > length ,
& k5_reply ,
2009-12-15 12:58:40 +01:00
pa ,
( struct sockaddr * ) & ss ,
2006-11-07 06:59:56 +00:00
datagram_reply ) ;
2005-10-21 01:25:55 +00:00
if ( ret = = - 1 ) {
* reply = data_blob ( NULL , 0 ) ;
2016-06-10 09:50:45 +02:00
return KDC_ERROR ;
2005-10-21 01:25:55 +00:00
}
2010-11-12 17:23:34 +11:00
if ( ret = = HDB_ERR_NOT_FOUND_HERE ) {
* reply = data_blob ( NULL , 0 ) ;
2016-06-10 09:50:45 +02:00
return KDC_PROXY_REQUEST ;
2010-11-12 17:23:34 +11:00
}
2006-11-07 06:59:56 +00:00
if ( k5_reply . length ) {
* reply = data_blob_talloc ( mem_ctx , k5_reply . data , k5_reply . length ) ;
2009-03-25 12:21:59 +01:00
krb5_data_free ( & k5_reply ) ;
2006-11-07 06:59:56 +00:00
} else {
2009-12-23 15:17:16 -05:00
* reply = data_blob ( NULL , 0 ) ;
2006-11-07 06:59:56 +00:00
}
2016-06-10 09:50:45 +02:00
return KDC_OK ;
2005-10-21 01:25:55 +00:00
}
2005-06-03 11:23:15 +00:00
/*
setup our listening sockets on the configured network interfaces
*/
2017-09-18 13:05:24 +12:00
static NTSTATUS kdc_startup_interfaces ( struct kdc_server * kdc ,
struct loadparm_context * lp_ctx ,
struct interface * ifaces ,
const struct model_ops * model_ops )
2005-06-03 11:23:15 +00:00
{
2007-12-11 22:23:14 +01:00
int num_interfaces ;
2005-06-03 11:23:15 +00:00
TALLOC_CTX * tmp_ctx = talloc_new ( kdc ) ;
NTSTATUS status ;
2006-02-03 23:19:00 +00:00
int i ;
2010-11-15 08:41:16 +11:00
uint16_t kdc_port = lpcfg_krb5_port ( lp_ctx ) ;
uint16_t kpasswd_port = lpcfg_kpasswd_port ( lp_ctx ) ;
bool done_wildcard = false ;
2007-12-11 22:23:14 +01:00
2011-05-02 15:57:19 +10:00
num_interfaces = iface_list_count ( ifaces ) ;
2009-12-23 15:17:16 -05:00
2010-11-15 08:41:16 +11:00
/* if we are allowing incoming packets from any address, then
we need to bind to the wildcard address */
if ( ! lpcfg_bind_interfaces_only ( lp_ctx ) ) {
2019-01-18 19:09:12 +01:00
size_t num_binds = 0 ;
2014-02-27 10:28:23 +01:00
char * * wcard = iface_list_wildcard ( kdc ) ;
2011-05-12 12:35:02 +02:00
NT_STATUS_HAVE_NO_MEMORY ( wcard ) ;
for ( i = 0 ; wcard [ i ] ; i + + ) {
if ( kdc_port ) {
status = kdc_add_socket ( kdc , model_ops ,
" kdc " , wcard [ i ] , kdc_port ,
kdc_process , false ) ;
2014-06-05 12:32:30 -07:00
if ( NT_STATUS_IS_OK ( status ) ) {
num_binds + + ;
}
2011-05-12 12:35:02 +02:00
}
if ( kpasswd_port ) {
status = kdc_add_socket ( kdc , model_ops ,
" kpasswd " , wcard [ i ] , kpasswd_port ,
2016-09-07 16:38:06 +02:00
kpasswd_process , false ) ;
2014-06-05 12:32:30 -07:00
if ( NT_STATUS_IS_OK ( status ) ) {
num_binds + + ;
}
2011-05-12 12:35:02 +02:00
}
2010-11-15 08:41:16 +11:00
}
2011-05-12 12:35:02 +02:00
talloc_free ( wcard ) ;
2014-06-05 12:32:30 -07:00
if ( num_binds = = 0 ) {
return NT_STATUS_INVALID_PARAMETER_MIX ;
}
2010-11-15 08:41:16 +11:00
done_wildcard = true ;
}
2006-02-03 23:19:00 +00:00
for ( i = 0 ; i < num_interfaces ; i + + ) {
2011-05-02 15:57:19 +10:00
const char * address = talloc_strdup ( tmp_ctx , iface_list_n_ip ( ifaces , i ) ) ;
2009-11-20 08:47:40 -06:00
if ( kdc_port ) {
2009-11-23 22:28:11 -06:00
status = kdc_add_socket ( kdc , model_ops ,
2010-11-15 08:41:16 +11:00
" kdc " , address , kdc_port ,
kdc_process , done_wildcard ) ;
2009-11-20 08:47:40 -06:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
}
if ( kpasswd_port ) {
2009-11-23 22:28:11 -06:00
status = kdc_add_socket ( kdc , model_ops ,
2010-11-15 08:41:16 +11:00
" kpasswd " , address , kpasswd_port ,
2016-09-07 16:38:06 +02:00
kpasswd_process , done_wildcard ) ;
2009-11-20 08:47:40 -06:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
}
2006-02-03 23:19:00 +00:00
}
2005-06-03 11:23:15 +00:00
talloc_free ( tmp_ctx ) ;
return NT_STATUS_OK ;
}
2009-12-23 15:17:16 -05:00
static NTSTATUS kdc_check_generic_kerberos ( struct irpc_message * msg ,
2008-09-03 15:30:17 +10:00
struct kdc_check_generic_kerberos * r )
{
struct PAC_Validate pac_validate ;
DATA_BLOB srv_sig ;
struct PAC_SIGNATURE_DATA kdc_sig ;
2009-02-01 00:03:47 +01:00
struct kdc_server * kdc = talloc_get_type ( msg - > private_data , struct kdc_server ) ;
2016-06-10 09:42:33 +02:00
krb5_kdc_configuration * kdc_config =
( krb5_kdc_configuration * ) kdc - > private_data ;
2008-09-03 15:30:17 +10:00
enum ndr_err_code ndr_err ;
int ret ;
2022-02-22 19:41:14 +13:00
hdb_entry ent ;
2008-09-03 15:30:17 +10:00
krb5_principal principal ;
2016-06-10 09:42:33 +02:00
2008-09-03 15:30:17 +10:00
/* There is no reply to this request */
r - > out . generic_reply = data_blob ( NULL , 0 ) ;
2010-05-09 17:20:01 +02:00
ndr_err = ndr_pull_struct_blob ( & r - > in . generic_request , msg , & pac_validate ,
2008-09-03 15:30:17 +10:00
( ndr_pull_flags_fn_t ) ndr_pull_PAC_Validate ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2009-12-23 15:17:16 -05:00
2012-01-11 16:13:37 +11:00
if ( pac_validate . MessageType ! = NETLOGON_GENERIC_KRB5_PAC_VALIDATE ) {
2008-09-03 15:30:17 +10:00
/* We don't implement any other message types - such as certificate validation - yet */
return NT_STATUS_INVALID_PARAMETER ;
}
2008-09-22 14:23:22 -07:00
2008-09-03 15:30:17 +10:00
if ( pac_validate . ChecksumAndSignature . length ! = ( pac_validate . ChecksumLength + pac_validate . SignatureLength )
| | pac_validate . ChecksumAndSignature . length < pac_validate . ChecksumLength
| | pac_validate . ChecksumAndSignature . length < pac_validate . SignatureLength ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2009-12-23 15:17:16 -05:00
srv_sig = data_blob_const ( pac_validate . ChecksumAndSignature . data ,
2008-09-03 15:30:17 +10:00
pac_validate . ChecksumLength ) ;
2009-12-23 15:17:16 -05:00
ret = krb5_make_principal ( kdc - > smb_krb5_context - > krb5_context , & principal ,
2010-07-16 14:32:42 +10:00
lpcfg_realm ( kdc - > task - > lp_ctx ) ,
" krbtgt " , lpcfg_realm ( kdc - > task - > lp_ctx ) ,
2008-09-03 15:30:17 +10:00
NULL ) ;
if ( ret ! = 0 ) {
return NT_STATUS_NO_MEMORY ;
}
2016-06-10 09:42:33 +02:00
ret = kdc_config - > db [ 0 ] - > hdb_fetch_kvno ( kdc - > smb_krb5_context - > krb5_context ,
kdc_config - > db [ 0 ] ,
2010-11-29 11:24:08 +11:00
principal ,
HDB_F_GET_KRBTGT | HDB_F_DECRYPT ,
0 ,
& ent ) ;
2016-06-10 09:12:39 +02:00
2008-09-03 15:30:17 +10:00
if ( ret ! = 0 ) {
2022-02-22 19:41:14 +13:00
hdb_free_entry ( kdc - > smb_krb5_context - > krb5_context , kdc_config - > db [ 0 ] , & ent ) ;
2008-09-03 15:30:17 +10:00
krb5_free_principal ( kdc - > smb_krb5_context - > krb5_context , principal ) ;
2009-12-23 15:17:16 -05:00
2008-09-03 15:30:17 +10:00
return NT_STATUS_LOGON_FAILURE ;
}
2009-12-23 15:17:16 -05:00
2008-09-03 15:30:17 +10:00
kdc_sig . type = pac_validate . SignatureType ;
kdc_sig . signature = data_blob_const ( & pac_validate . ChecksumAndSignature . data [ pac_validate . ChecksumLength ] ,
pac_validate . SignatureLength ) ;
2012-01-11 18:06:55 +11:00
ret = kdc_check_pac ( kdc - > smb_krb5_context - > krb5_context , srv_sig , & kdc_sig , & ent ) ;
2008-09-03 15:30:17 +10:00
2022-02-22 19:41:14 +13:00
hdb_free_entry ( kdc - > smb_krb5_context - > krb5_context , kdc_config - > db [ 0 ] , & ent ) ;
2008-09-03 15:30:17 +10:00
krb5_free_principal ( kdc - > smb_krb5_context - > krb5_context , principal ) ;
if ( ret ! = 0 ) {
return NT_STATUS_LOGON_FAILURE ;
}
2009-12-23 15:17:16 -05:00
2008-09-03 15:30:17 +10:00
return NT_STATUS_OK ;
}
2005-06-03 11:23:15 +00:00
/*
startup the kdc task
*/
2018-08-23 09:35:52 +12:00
static NTSTATUS kdc_task_init ( struct task_server * task )
2005-06-03 11:23:15 +00:00
{
struct kdc_server * kdc ;
NTSTATUS status ;
2007-12-11 22:23:14 +01:00
struct interface * ifaces ;
2005-06-03 11:23:15 +00:00
2010-07-16 14:32:42 +10:00
switch ( lpcfg_server_role ( task - > lp_ctx ) ) {
2006-02-03 23:19:00 +00:00
case ROLE_STANDALONE :
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: no KDC required in standalone configuration " , false ) ;
2018-08-23 09:35:52 +12:00
return NT_STATUS_INVALID_DOMAIN_ROLE ;
2006-02-03 23:19:00 +00:00
case ROLE_DOMAIN_MEMBER :
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: no KDC required in member server configuration " , false ) ;
2018-08-23 09:35:52 +12:00
return NT_STATUS_INVALID_DOMAIN_ROLE ;
2012-06-10 22:08:20 +10:00
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
2020-11-11 18:50:45 +02:00
case ROLE_IPA_DC :
2018-09-04 12:12:49 +12:00
task_server_terminate (
task , " Cannot start KDC as a 'classic Samba' DC " , false ) ;
2018-08-23 09:35:52 +12:00
return NT_STATUS_INVALID_DOMAIN_ROLE ;
2012-06-10 22:08:20 +10:00
case ROLE_ACTIVE_DIRECTORY_DC :
2006-02-03 23:19:00 +00:00
/* Yes, we want a KDC */
break ;
}
2011-06-02 15:40:28 +10:00
load_interface_list ( task , task - > lp_ctx , & ifaces ) ;
2007-12-11 22:23:14 +01:00
2011-05-02 15:57:19 +10:00
if ( iface_list_count ( ifaces ) = = 0 ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: no network interfaces configured " , false ) ;
2018-08-23 09:35:52 +12:00
return NT_STATUS_UNSUCCESSFUL ;
2005-06-03 11:23:15 +00:00
}
2006-03-09 17:48:41 +00:00
task_server_set_title ( task , " task[kdc] " ) ;
2010-11-12 17:23:34 +11:00
kdc = talloc_zero ( task , struct kdc_server ) ;
2005-06-03 11:23:15 +00:00
if ( kdc = = NULL ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: out of memory " , true ) ;
2018-08-23 09:35:52 +12:00
return NT_STATUS_NO_MEMORY ;
2005-06-03 11:23:15 +00:00
}
kdc - > task = task ;
2018-08-23 11:26:40 +12:00
task - > private_data = kdc ;
2005-06-03 11:23:15 +00:00
2018-08-23 11:26:40 +12:00
/* start listening on the configured network interfaces */
status = kdc_startup_interfaces ( kdc , task - > lp_ctx , ifaces ,
task - > model_ops ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
task_server_terminate ( task , " kdc failed to setup interfaces " , true ) ;
return status ;
}
return NT_STATUS_OK ;
}
/*
initialise the kdc task after a fork
*/
2018-08-29 13:16:08 +12:00
static void kdc_post_fork ( struct task_server * task , struct process_details * pd )
2018-08-23 11:26:40 +12:00
{
struct kdc_server * kdc ;
krb5_kdc_configuration * kdc_config = NULL ;
NTSTATUS status ;
krb5_error_code ret ;
int ldb_ret ;
if ( task = = NULL ) {
task_server_terminate ( task , " kdc: Null task " , true ) ;
return ;
}
if ( task - > private_data = = NULL ) {
task_server_terminate ( task , " kdc: No kdc_server info " , true ) ;
return ;
}
kdc = talloc_get_type_abort ( task - > private_data , struct kdc_server ) ;
2010-11-12 17:23:34 +11:00
/* get a samdb connection */
2018-04-12 06:41:30 +12:00
kdc - > samdb = samdb_connect ( kdc ,
kdc - > task - > event_ctx ,
kdc - > task - > lp_ctx ,
system_session ( kdc - > task - > lp_ctx ) ,
NULL ,
0 ) ;
2010-11-12 17:23:34 +11:00
if ( ! kdc - > samdb ) {
2018-08-28 07:46:59 +12:00
DBG_WARNING ( " kdc_task_init: unable to connect to samdb \n " ) ;
2010-11-12 17:23:34 +11:00
task_server_terminate ( task , " kdc: krb5_init_context samdb connect failed " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2010-11-12 17:23:34 +11:00
}
ldb_ret = samdb_rodc ( kdc - > samdb , & kdc - > am_rodc ) ;
if ( ldb_ret ! = LDB_SUCCESS ) {
2018-08-28 07:46:59 +12:00
DBG_WARNING ( " kdc_task_init: "
" Cannot determine if we are an RODC: %s \n " ,
ldb_errstring ( kdc - > samdb ) ) ;
2010-11-12 17:23:34 +11:00
task_server_terminate ( task , " kdc: krb5_init_context samdb RODC connect failed " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2010-11-12 17:23:34 +11:00
}
kdc - > proxy_timeout = lpcfg_parm_int ( kdc - > task - > lp_ctx , NULL , " kdc " , " proxy timeout " , 5 ) ;
2005-06-03 14:32:10 +00:00
initialize_krb5_error_table ( ) ;
2014-04-17 22:35:33 +12:00
ret = smb_krb5_init_context ( kdc , task - > lp_ctx , & kdc - > smb_krb5_context ) ;
2005-06-03 14:32:10 +00:00
if ( ret ) {
2018-08-28 07:46:59 +12:00
DBG_WARNING ( " kdc_task_init: krb5_init_context failed (%s) \n " ,
error_message ( ret ) ) ;
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: krb5_init_context failed " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2005-06-03 14:32:10 +00:00
}
2005-09-28 02:22:31 +00:00
krb5_add_et_list ( kdc - > smb_krb5_context - > krb5_context , initialize_hdb_error_table_r ) ;
2009-12-23 15:17:16 -05:00
ret = krb5_kdc_get_config ( kdc - > smb_krb5_context - > krb5_context ,
2016-06-10 09:42:33 +02:00
& kdc_config ) ;
2007-01-24 02:48:40 +00:00
if ( ret ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: failed to get KDC configuration " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2007-01-24 02:48:40 +00:00
}
2009-12-23 15:17:16 -05:00
2016-06-10 09:42:33 +02:00
kdc_config - > logf = ( krb5_log_facility * ) kdc - > smb_krb5_context - > pvt_log_data ;
kdc_config - > db = talloc ( kdc , struct HDB * ) ;
if ( ! kdc_config - > db ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: out of memory " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2005-06-03 14:32:10 +00:00
}
2016-06-10 09:42:33 +02:00
kdc_config - > num_db = 1 ;
2009-12-23 15:17:16 -05:00
2011-07-14 21:02:20 +02:00
/*
2017-11-07 18:03:45 +01:00
* Note with the CVE - 2022 - 37966 patches ,
* see https : //bugzilla.samba.org/show_bug.cgi?id=15219
* and https : //bugzilla.samba.org/show_bug.cgi?id=15237
* we want to use the strongest keys for everything .
2011-07-14 21:02:20 +02:00
*
2017-11-07 18:03:45 +01:00
* Some of these don ' t have any real effect anymore ,
* but it is better to have them as true . . .
2011-07-14 21:02:20 +02:00
*/
2017-11-07 18:03:45 +01:00
kdc_config - > tgt_use_strongest_session_key = true ;
2020-04-10 23:10:28 +02:00
kdc_config - > preauth_use_strongest_session_key = true ;
2017-11-07 18:03:45 +01:00
kdc_config - > svc_use_strongest_session_key = true ;
2016-06-10 09:42:33 +02:00
kdc_config - > use_strongest_server_key = true ;
2011-07-14 21:02:20 +02:00
2021-06-17 21:27:06 +12:00
kdc_config - > force_include_pa_etype_salt = true ;
2021-12-15 12:30:28 +13:00
/*
* For Samba CVE - 2020 - 25719 Require PAC to be present
* This instructs Heimdal to match AD behaviour ,
* as seen after Microsoft ' s CVE - 2021 - 42287 when
* PacRequestorEnforcement is set to 2.
*
* Samba BUG : https : //bugzilla.samba.org/show_bug.cgi?id=14686
* REF : https : //support.microsoft.com/en-au/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041
*/
kdc_config - > require_pac = true ;
2022-03-09 12:39:07 +01:00
/*
* By default we enable RFC6113 / FAST support ,
* but we have an option to disable in order to
* test against a KDC with FAST support .
*/
kdc_config - > enable_fast = lpcfg_kdc_enable_fast ( task - > lp_ctx ) ;
2023-06-09 15:46:33 +12:00
{
static const char * dummy_string = " Microsoft " ;
/*
* The FAST cookie is not cryptographically required ,
* provided that the non - AD gss - preauth authentication
* method is removed ( as this is the only multi - step
* authentication method ) .
*
* gss - preauth has been disabled both by not being
* configured and by being made dependent
* configuration for a " real " fast cookie .
*
* The hide_client_names feature in Heimdal is the
* only other state that is persisted in the cookie ,
* and this does not need to be in the cookie for
* single - shot authentication protocols such as ENC - TS
* and ENC - CHAL , the standard password protocols in
* AD .
*
* Furthermore , the Heimdal KDC does not fail if the
* client does not supply a FAST cookie , showing that
* the presence of the cookie is not required .
*/
kdc_config - > enable_fast_cookie = false ;
kdc_config - > dummy_fast_cookie = smb_krb5_make_data ( discard_const_p ( char , dummy_string ) ,
strlen ( dummy_string ) ) ;
}
2021-12-15 12:30:28 +13:00
/*
* Match Windows and RFC6113 and Windows but break older
* Heimdal clients .
*/
kdc_config - > enable_armored_pa_enc_timestamp = false ;
2009-07-27 16:09:25 +10:00
/* Register hdb-samba4 hooks for use as a keytab */
2009-07-27 13:48:45 +10:00
2010-01-28 00:08:36 -05:00
kdc - > base_ctx = talloc_zero ( kdc , struct samba_kdc_base_context ) ;
if ( ! kdc - > base_ctx ) {
2009-09-18 18:05:55 -07:00
task_server_terminate ( task , " kdc: out of memory " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2009-07-27 16:09:25 +10:00
}
2010-01-28 00:08:36 -05:00
kdc - > base_ctx - > ev_ctx = task - > event_ctx ;
kdc - > base_ctx - > lp_ctx = task - > lp_ctx ;
2017-02-21 14:07:54 +13:00
kdc - > base_ctx - > msg_ctx = task - > msg_ctx ;
2010-01-28 00:08:36 -05:00
status = hdb_samba4_create_kdc ( kdc - > base_ctx ,
kdc - > smb_krb5_context - > krb5_context ,
2016-06-10 09:42:33 +02:00
& kdc_config - > db [ 0 ] ) ;
2010-01-28 00:08:36 -05:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
task_server_terminate ( task , " kdc: hdb_samba4_create_kdc (setup KDC database) failed " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2010-01-28 00:08:36 -05:00
}
2009-07-27 13:48:45 +10:00
2009-12-23 15:17:16 -05:00
ret = krb5_plugin_register ( kdc - > smb_krb5_context - > krb5_context ,
2018-09-17 18:06:35 -07:00
PLUGIN_TYPE_DATA , " hdb_samba4_interface " ,
2011-11-30 07:45:25 +11:00
& hdb_samba4_interface ) ;
2008-09-24 12:53:10 -07:00
if ( ret ) {
2010-01-11 11:48:12 -05:00
task_server_terminate ( task , " kdc: failed to register hdb plugin " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2008-09-24 12:53:10 -07:00
}
2022-05-26 16:36:30 +12:00
kdc - > kpasswd_keytab_name = talloc_asprintf ( kdc , " HDBGET:samba4:&%p " , kdc - > base_ctx ) ;
if ( kdc - > kpasswd_keytab_name = = NULL ) {
2016-09-07 16:38:06 +02:00
task_server_terminate ( task ,
" kdc: Failed to set keytab name " ,
true ) ;
2018-08-23 11:26:40 +12:00
return ;
2016-09-07 16:38:06 +02:00
}
2022-05-24 17:52:05 +12:00
ret = krb5_kt_register ( kdc - > smb_krb5_context - > krb5_context , & hdb_get_kt_ops ) ;
2018-09-17 18:50:55 -07:00
if ( ret ) {
task_server_terminate ( task , " kdc: failed to register keytab plugin " , true ) ;
return ;
}
2022-02-22 14:39:13 +13:00
/* Register KDC hooks */
2009-12-23 15:17:16 -05:00
ret = krb5_plugin_register ( kdc - > smb_krb5_context - > krb5_context ,
2022-02-22 14:39:13 +13:00
PLUGIN_TYPE_DATA , " kdc " ,
& kdc_plugin_table ) ;
2007-06-13 05:44:24 +00:00
if ( ret ) {
2022-02-22 14:39:13 +13:00
task_server_terminate ( task , " kdc: failed to register kdc plugin " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2007-06-13 05:44:24 +00:00
}
2022-02-22 14:39:13 +13:00
ret = krb5_kdc_plugin_init ( kdc - > smb_krb5_context - > krb5_context ) ;
2010-11-15 09:08:43 +11:00
if ( ret ) {
2022-02-22 14:39:13 +13:00
task_server_terminate ( task , " kdc: failed to init kdc plugin " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2010-11-15 09:08:43 +11:00
}
2016-06-10 09:42:33 +02:00
ret = krb5_kdc_pkinit_config ( kdc - > smb_krb5_context - > krb5_context , kdc_config ) ;
2010-11-15 09:08:43 +11:00
if ( ret ) {
task_server_terminate ( task , " kdc: failed to init kdc pkinit subsystem " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2010-11-15 09:08:43 +11:00
}
2016-06-10 09:42:33 +02:00
kdc - > private_data = kdc_config ;
2007-01-10 01:51:35 +00:00
2009-12-23 15:17:16 -05:00
status = IRPC_REGISTER ( task - > msg_ctx , irpc , KDC_CHECK_GENERIC_KERBEROS ,
2008-09-03 15:30:17 +10:00
kdc_check_generic_kerberos , kdc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2010-11-15 08:41:16 +11:00
task_server_terminate ( task , " kdc failed to setup monitoring " , true ) ;
2018-08-23 11:26:40 +12:00
return ;
2008-09-03 15:30:17 +10:00
}
2005-07-19 09:27:20 +00:00
irpc_add_name ( task - > msg_ctx , " kdc_server " ) ;
2005-06-03 11:23:15 +00:00
}
/* called at smbd startup - register ourselves as a server service */
2017-04-20 12:24:43 -07:00
NTSTATUS server_service_kdc_init ( TALLOC_CTX * ctx )
2005-06-03 11:23:15 +00:00
{
2018-08-23 09:29:56 +12:00
static const struct service_details details = {
2017-09-15 07:09:23 +12:00
. inhibit_fork_on_accept = true ,
2018-08-23 11:26:40 +12:00
. inhibit_pre_fork = false ,
2018-08-23 09:35:52 +12:00
. task_init = kdc_task_init ,
2018-08-23 11:26:40 +12:00
. post_fork = kdc_post_fork
2017-09-15 07:09:23 +12:00
} ;
2018-08-23 09:35:52 +12:00
return register_server_service ( ctx , " kdc " , & details ) ;
2005-06-03 11:23:15 +00:00
}