2005-04-08 12:57:09 +04:00
/*
Unix SMB / CIFS implementation .
NBT datagram server
Copyright ( C ) Andrew Tridgell 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-08 12:57:09 +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-04-08 12:57:09 +04:00
*/
# include "includes.h"
# include "nbt_server/nbt_server.h"
2020-11-20 17:27:17 +03:00
# include "samba/service_task.h"
2005-04-08 12:57:09 +04:00
# include "lib/socket/socket.h"
2006-03-07 14:07:23 +03:00
# include "libcli/resolve/resolve.h"
# include "nbt_server/dgram/proto.h"
2006-03-16 03:23:11 +03:00
# include "librpc/gen_ndr/ndr_nbt.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2005-04-08 12:57:09 +04:00
/*
a list of mailslots that we have static handlers for
*/
static const struct {
const char * mailslot_name ;
dgram_mailslot_handler_t handler ;
} mailslot_handlers [ ] = {
2008-05-17 07:24:29 +04:00
/* Handle both NTLOGON and NETLOGON in the same function, as
* they are very similar */
2005-04-08 12:57:09 +04:00
{ NBT_MAILSLOT_NETLOGON , nbtd_mailslot_netlogon_handler } ,
2008-05-17 07:24:29 +04:00
{ NBT_MAILSLOT_NTLOGON , nbtd_mailslot_netlogon_handler } ,
2005-04-08 12:57:09 +04:00
{ NBT_MAILSLOT_BROWSE , nbtd_mailslot_browse_handler }
} ;
/*
receive an incoming dgram request . This is used for general datagram
requests . Mailslot requests for our listening mailslots
are handled in the specific mailslot handlers
*/
void dgram_request_handler ( struct nbt_dgram_socket * dgmsock ,
2005-11-10 18:51:57 +03:00
struct nbt_dgram_packet * packet ,
2006-01-10 01:12:53 +03:00
struct socket_address * src )
2005-04-08 12:57:09 +04:00
{
2005-11-10 18:51:57 +03:00
DEBUG ( 0 , ( " General datagram request from %s:%d \n " , src - > addr , src - > port ) ) ;
2005-04-08 12:57:09 +04:00
NDR_PRINT_DEBUG ( nbt_dgram_packet , packet ) ;
}
/*
setup the port 138 datagram listener for a given interface
*/
NTSTATUS nbtd_dgram_setup ( struct nbtd_interface * iface , const char * bind_address )
{
2006-01-16 17:01:34 +03:00
struct nbt_dgram_socket * bcast_dgmsock = NULL ;
2005-04-08 12:57:09 +04:00
struct nbtd_server * nbtsrv = iface - > nbtsrv ;
2006-01-10 01:12:53 +03:00
struct socket_address * bcast_addr , * bind_addr ;
2005-04-08 12:57:09 +04:00
NTSTATUS status ;
2006-01-10 01:12:53 +03:00
TALLOC_CTX * tmp_ctx = talloc_new ( iface ) ;
2005-04-08 12:57:09 +04:00
/* the list of mailslots that we are interested in */
2018-04-16 17:02:42 +03:00
size_t i ;
2005-04-08 12:57:09 +04:00
2006-01-10 01:12:53 +03:00
if ( ! tmp_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
2006-01-16 17:01:34 +03:00
if ( strcmp ( " 0.0.0.0 " , iface - > netmask ) ! = 0 ) {
/* listen for broadcasts on port 138 */
2010-05-09 19:20:01 +04:00
bcast_dgmsock = nbt_dgram_socket_init ( iface , nbtsrv - > task - > event_ctx ) ;
2006-01-16 17:01:34 +03:00
if ( ! bcast_dgmsock ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
bcast_addr = socket_address_from_strings ( tmp_ctx , bcast_dgmsock - > sock - > backend_name ,
2007-09-28 05:17:46 +04:00
iface - > bcast_address ,
2010-07-16 08:32:42 +04:00
lpcfg_dgram_port ( iface - > nbtsrv - > task - > lp_ctx ) ) ;
2006-01-16 17:01:34 +03:00
if ( ! bcast_addr ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
status = socket_listen ( bcast_dgmsock - > sock , bcast_addr , 0 , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( tmp_ctx ) ;
DEBUG ( 0 , ( " Failed to bind to %s:%d - %s \n " ,
2010-07-16 08:32:42 +04:00
iface - > bcast_address , lpcfg_dgram_port ( iface - > nbtsrv - > task - > lp_ctx ) ,
2007-09-28 05:17:46 +04:00
nt_errstr ( status ) ) ) ;
2006-01-16 17:01:34 +03:00
return status ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
dgram_set_incoming_handler ( bcast_dgmsock , dgram_request_handler , iface ) ;
}
2006-01-10 01:12:53 +03:00
2005-04-08 12:57:09 +04:00
/* listen for unicasts on port 138 */
2010-05-09 19:20:01 +04:00
iface - > dgmsock = nbt_dgram_socket_init ( iface , nbtsrv - > task - > event_ctx ) ;
2006-01-10 01:12:53 +03:00
if ( ! iface - > dgmsock ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2005-04-08 12:57:09 +04:00
2006-01-16 17:01:34 +03:00
bind_addr = socket_address_from_strings ( tmp_ctx , iface - > dgmsock - > sock - > backend_name ,
2010-07-16 08:32:42 +04:00
bind_address , lpcfg_dgram_port ( iface - > nbtsrv - > task - > lp_ctx ) ) ;
2006-01-16 17:01:34 +03:00
if ( ! bind_addr ) {
talloc_free ( tmp_ctx ) ;
return NT_STATUS_NO_MEMORY ;
}
2006-01-10 01:12:53 +03:00
status = socket_listen ( iface - > dgmsock - > sock , bind_addr , 0 , 0 ) ;
2005-04-08 12:57:09 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-01-10 01:12:53 +03:00
talloc_free ( tmp_ctx ) ;
2005-04-08 12:57:09 +04:00
DEBUG ( 0 , ( " Failed to bind to %s:%d - %s \n " ,
2010-07-16 08:32:42 +04:00
bind_address , lpcfg_dgram_port ( iface - > nbtsrv - > task - > lp_ctx ) , nt_errstr ( status ) ) ) ;
2005-04-08 12:57:09 +04:00
return status ;
}
2006-01-10 01:12:53 +03:00
2005-04-08 12:57:09 +04:00
dgram_set_incoming_handler ( iface - > dgmsock , dgram_request_handler , iface ) ;
2006-01-10 01:12:53 +03:00
talloc_free ( tmp_ctx ) ;
2005-04-08 12:57:09 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( mailslot_handlers ) ; i + + ) {
/* note that we don't need to keep the pointer
to the dgmslot around - the callback is all
we need */
struct dgram_mailslot_handler * dgmslot ;
2006-01-16 17:01:34 +03:00
if ( bcast_dgmsock ) {
dgmslot = dgram_mailslot_listen ( bcast_dgmsock ,
2005-04-08 12:57:09 +04:00
mailslot_handlers [ i ] . mailslot_name ,
mailslot_handlers [ i ] . handler , iface ) ;
2006-01-16 17:01:34 +03:00
NT_STATUS_HAVE_NO_MEMORY ( dgmslot ) ;
}
2005-04-08 12:57:09 +04:00
dgmslot = dgram_mailslot_listen ( iface - > dgmsock ,
mailslot_handlers [ i ] . mailslot_name ,
mailslot_handlers [ i ] . handler , iface ) ;
NT_STATUS_HAVE_NO_MEMORY ( dgmslot ) ;
}
return NT_STATUS_OK ;
}