2005-04-08 08:57:09 +00:00
/*
Unix SMB / CIFS implementation .
NBT datagram netlogon server
Copyright ( C ) Andrew Tridgell 2005
2008-05-17 13:24:29 +10:00
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2008
2005-04-08 08:57:09 +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-04-08 08:57:09 +00: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 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-04-08 08:57:09 +00:00
*/
# include "includes.h"
# include "nbt_server/nbt_server.h"
# include "lib/socket/socket.h"
2011-02-10 14:12:51 +11:00
# include <ldb.h>
2005-12-28 15:38:36 +00:00
# include "dsdb/samdb/samdb.h"
# include "auth/auth.h"
2007-09-08 12:42:09 +00:00
# include "param/param.h"
2007-12-06 16:54:34 +01:00
# include "smbd/service_task.h"
2013-11-05 20:39:56 +01:00
# include "dsdb/samdb/ldb_modules/util.h"
2008-05-17 20:53:29 +10:00
# include "libcli/security/security.h"
2008-10-20 18:59:51 +02:00
# include "nbt_server/dgram/proto.h"
2015-12-28 19:01:54 +00:00
# include "libds/common/roles.h"
2005-04-08 08:57:09 +00:00
2005-04-10 23:09:38 +00:00
/*
reply to a GETDC request
*/
static void nbtd_netlogon_getdc ( struct dgram_mailslot_handler * dgmslot ,
2006-03-25 09:24:53 +00:00
struct nbtd_interface * iface ,
2005-04-10 23:09:38 +00:00
struct nbt_dgram_packet * packet ,
2006-01-09 22:12:53 +00:00
const struct socket_address * src ,
2005-04-10 23:09:38 +00:00
struct nbt_netlogon_packet * netlogon )
{
struct nbt_name * name = & packet - > data . msg . dest_name ;
2007-10-06 21:33:16 +00:00
struct nbtd_interface * reply_iface = nbtd_find_reply_iface ( iface , src - > addr , false ) ;
2005-04-10 23:09:38 +00:00
struct nbt_netlogon_response_from_pdc * pdc ;
2005-08-03 18:30:21 +00:00
struct ldb_context * samctx ;
2008-05-17 13:24:29 +10:00
struct nbt_netlogon_response netlogon_response ;
2005-04-10 23:09:38 +00:00
2008-05-17 20:53:29 +10:00
/* only answer getdc requests on the PDC or LOGON names */
if ( name - > type ! = NBT_NAME_PDC & & name - > type ! = NBT_NAME_LOGON ) {
2005-04-10 23:09:38 +00:00
return ;
}
2009-06-01 13:42:51 +10:00
samctx = iface - > nbtsrv - > sam_ctx ;
2012-06-10 22:08:20 +10:00
if ( lpcfg_server_role ( iface - > nbtsrv - > task - > lp_ctx ) ! = ROLE_ACTIVE_DIRECTORY_DC
2009-05-26 12:31:39 +10:00
| | ! samdb_is_pdc ( samctx ) ) {
2008-05-17 20:53:29 +10:00
DEBUG ( 2 , ( " Not a PDC, so not processing LOGON_PRIMARY_QUERY \n " ) ) ;
return ;
}
2010-07-16 14:32:42 +10:00
if ( strcasecmp_m ( name - > name , lpcfg_workgroup ( iface - > nbtsrv - > task - > lp_ctx ) ) ! = 0 ) {
2009-05-26 12:31:39 +10:00
DEBUG ( 5 , ( " GetDC requested for a domian %s that we don't host \n " , name - > name ) ) ;
2005-08-03 18:30:21 +00:00
return ;
}
2005-04-10 23:09:38 +00:00
/* setup a GETDC reply */
2008-05-17 13:24:29 +10:00
ZERO_STRUCT ( netlogon_response ) ;
netlogon_response . response_type = NETLOGON_GET_PDC ;
2008-10-02 08:09:25 +02:00
pdc = & netlogon_response . data . get_pdc ;
2005-04-10 23:09:38 +00:00
2008-05-17 13:24:29 +10:00
pdc - > command = NETLOGON_RESPONSE_FROM_PDC ;
2010-07-16 14:32:42 +10:00
pdc - > pdc_name = lpcfg_netbios_name ( iface - > nbtsrv - > task - > lp_ctx ) ;
2005-04-10 23:09:38 +00:00
pdc - > unicode_pdc_name = pdc - > pdc_name ;
2010-07-16 14:32:42 +10:00
pdc - > domain_name = lpcfg_workgroup ( iface - > nbtsrv - > task - > lp_ctx ) ;
2005-04-10 23:09:38 +00:00
pdc - > nt_version = 1 ;
pdc - > lmnt_token = 0xFFFF ;
pdc - > lm20_token = 0xFFFF ;
2006-03-25 09:24:53 +00:00
dgram_mailslot_netlogon_reply ( reply_iface - > dgmsock ,
2005-04-10 23:09:38 +00:00
packet ,
2010-07-16 14:32:42 +10:00
lpcfg_netbios_name ( iface - > nbtsrv - > task - > lp_ctx ) ,
2005-04-10 23:09:38 +00:00
netlogon - > req . pdc . mailslot_name ,
2008-05-17 13:24:29 +10:00
& netlogon_response ) ;
2005-04-10 23:09:38 +00:00
}
2005-04-14 07:40:23 +00:00
/*
reply to a ADS style GETDC request
*/
2008-05-17 13:24:29 +10:00
static void nbtd_netlogon_samlogon ( struct dgram_mailslot_handler * dgmslot ,
struct nbtd_interface * iface ,
struct nbt_dgram_packet * packet ,
const struct socket_address * src ,
struct nbt_netlogon_packet * netlogon )
2005-04-14 07:40:23 +00:00
{
struct nbt_name * name = & packet - > data . msg . dest_name ;
2007-10-06 21:33:16 +00:00
struct nbtd_interface * reply_iface = nbtd_find_reply_iface ( iface , src - > addr , false ) ;
2005-04-14 07:40:23 +00:00
struct ldb_context * samctx ;
2006-03-25 09:24:53 +00:00
const char * my_ip = reply_iface - > ip_address ;
2008-05-17 13:24:29 +10:00
struct dom_sid * sid ;
struct nbt_netlogon_response netlogon_response ;
NTSTATUS status ;
2006-01-09 22:12:53 +00:00
if ( ! my_ip ) {
DEBUG ( 0 , ( " Could not obtain own IP address for datagram socket \n " ) ) ;
return ;
}
2005-04-14 07:40:23 +00:00
/* only answer getdc requests on the PDC or LOGON names */
if ( name - > type ! = NBT_NAME_PDC & & name - > type ! = NBT_NAME_LOGON ) {
return ;
}
2008-06-30 12:22:50 +10:00
samctx = iface - > nbtsrv - > sam_ctx ;
2005-04-14 07:40:23 +00:00
2008-05-17 13:24:29 +10:00
if ( netlogon - > req . logon . sid_size ) {
sid = & netlogon - > req . logon . sid ;
} else {
sid = NULL ;
2005-08-03 18:30:21 +00:00
}
2008-05-17 20:53:29 +10:00
status = fill_netlogon_samlogon_response ( samctx , packet , NULL , name - > name , sid , NULL ,
2008-05-21 12:37:36 +10:00
netlogon - > req . logon . user_name , netlogon - > req . logon . acct_control , src - > addr ,
2010-04-27 23:39:57 +10:00
netlogon - > req . logon . nt_version , iface - > nbtsrv - > task - > lp_ctx , & netlogon_response . data . samlogon , false ) ;
2008-05-17 13:24:29 +10:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-05-17 20:53:29 +10:00
DEBUG ( 2 , ( " NBT netlogon query failed domain=%s sid=%s version=%d - %s \n " ,
name - > name , dom_sid_string ( packet , sid ) , netlogon - > req . logon . nt_version , nt_errstr ( status ) ) ) ;
2005-04-14 07:40:23 +00:00
return ;
}
2008-05-17 20:53:29 +10:00
netlogon_response . response_type = NETLOGON_SAMLOGON ;
2005-04-14 07:40:23 +00:00
packet - > data . msg . dest_name . type = 0 ;
2006-03-25 09:24:53 +00:00
dgram_mailslot_netlogon_reply ( reply_iface - > dgmsock ,
2005-04-14 07:40:23 +00:00
packet ,
2010-07-16 14:32:42 +10:00
lpcfg_netbios_name ( iface - > nbtsrv - > task - > lp_ctx ) ,
2008-05-17 13:24:29 +10:00
netlogon - > req . logon . mailslot_name ,
& netlogon_response ) ;
2005-04-14 07:40:23 +00:00
}
2005-04-08 08:57:09 +00:00
/*
handle incoming netlogon mailslot requests
*/
void nbtd_mailslot_netlogon_handler ( struct dgram_mailslot_handler * dgmslot ,
struct nbt_dgram_packet * packet ,
2006-01-09 22:12:53 +00:00
struct socket_address * src )
2005-04-08 08:57:09 +00:00
{
NTSTATUS status = NT_STATUS_NO_MEMORY ;
2005-04-10 23:09:38 +00:00
struct nbtd_interface * iface =
2009-02-02 09:55:58 +01:00
talloc_get_type ( dgmslot - > private_data , struct nbtd_interface ) ;
2005-04-08 08:57:09 +00:00
struct nbt_netlogon_packet * netlogon =
talloc ( dgmslot , struct nbt_netlogon_packet ) ;
2005-04-10 23:09:38 +00:00
struct nbtd_iface_name * iname ;
struct nbt_name * name = & packet - > data . msg . dest_name ;
2005-04-08 08:57:09 +00:00
if ( netlogon = = NULL ) goto failed ;
2005-04-10 23:09:38 +00:00
/*
see if the we are listening on the destination netbios name
*/
iname = nbtd_find_iname ( iface , name , 0 ) ;
if ( iname = = NULL ) {
status = NT_STATUS_BAD_NETWORK_NAME ;
goto failed ;
}
2011-10-31 12:15:18 +01:00
DEBUG ( 5 , ( " netlogon request to %s from %s:%d \n " ,
2005-10-14 12:56:13 +00:00
nbt_name_string ( netlogon , name ) , src - > addr , src - > port ) ) ;
2008-05-17 13:24:29 +10:00
status = dgram_mailslot_netlogon_parse_request ( dgmslot , netlogon , packet , netlogon ) ;
2005-04-08 08:57:09 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) goto failed ;
2005-04-10 23:09:38 +00:00
switch ( netlogon - > command ) {
2008-05-17 13:24:29 +10:00
case LOGON_PRIMARY_QUERY :
2008-05-20 11:54:50 +10:00
nbtd_netlogon_getdc ( dgmslot , iface , packet ,
2008-05-17 13:24:29 +10:00
src , netlogon ) ;
2005-04-10 23:09:38 +00:00
break ;
2008-05-17 13:24:29 +10:00
case LOGON_SAM_LOGON_REQUEST :
2008-05-20 11:54:50 +10:00
nbtd_netlogon_samlogon ( dgmslot , iface , packet ,
2008-05-17 13:24:29 +10:00
src , netlogon ) ;
2005-04-14 07:40:23 +00:00
break ;
2005-04-10 23:09:38 +00:00
default :
DEBUG ( 2 , ( " unknown netlogon op %d from %s:%d \n " ,
2005-10-14 12:56:13 +00:00
netlogon - > command , src - > addr , src - > port ) ) ;
2005-05-05 11:14:12 +00:00
NDR_PRINT_DEBUG ( nbt_netlogon_packet , netlogon ) ;
2005-04-10 23:09:38 +00:00
break ;
}
2005-04-08 08:57:09 +00:00
talloc_free ( netlogon ) ;
return ;
failed :
2006-03-03 08:01:09 +00:00
DEBUG ( 2 , ( " nbtd netlogon handler failed from %s:%d to %s - %s \n " ,
src - > addr , src - > port , nbt_name_string ( netlogon , name ) ,
nt_errstr ( status ) ) ) ;
2005-04-08 08:57:09 +00:00
talloc_free ( netlogon ) ;
}