1997-12-13 17:16:07 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1997-12-13 17:16:07 +03:00
NBT netbios routines and daemon - version 2
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Luke Kenneth Casson Leighton 1994 - 1998
Copyright ( C ) Jeremy Allison 1994 - 1998
1997-12-13 17:16:07 +03:00
SMB Version handling
1998-01-22 16:27:43 +03:00
Copyright ( C ) John H Terpstra 1995 - 1998
1997-12-13 17:16:07 +03: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-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1997-12-13 17:16:07 +03: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 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1997-12-13 17:16:07 +03:00
*/
# include "includes.h"
2010-08-03 00:48:16 +04:00
# include "../librpc/gen_ndr/svcctl.h"
2010-08-18 17:22:09 +04:00
# include "nmbd/nmbd.h"
1997-12-13 17:16:07 +03:00
extern int updatecount ;
2007-10-19 04:40:25 +04:00
extern bool found_lm_clients ;
1997-12-13 17:16:07 +03:00
/****************************************************************************
Send a browser reset packet .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-01-03 11:28:12 +03:00
void send_browser_reset ( int reset_type , const char * to_name , int to_type , struct in_addr to_ip )
1997-12-13 17:16:07 +03:00
{
2007-11-30 04:25:41 +03:00
char outbuf [ 1024 ] ;
2003-08-27 05:25:01 +04:00
char * p ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " send_browser_reset: sending reset request type %d to %s<%02x> IP %s. \n " ,
reset_type , to_name , to_type , inet_ntoa ( to_ip ) ) ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
p = outbuf ;
SCVAL ( p , 0 , ANN_ResetBrowserState ) ;
p + + ;
SCVAL ( p , 0 , reset_type ) ;
p + + ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
send_mailslot ( True , BROWSE_MAILSLOT , outbuf , PTR_DIFF ( p , outbuf ) ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , 0x0 , to_name , to_type , to_ip ,
1998-08-30 21:04:24 +04:00
FIRST_SUBNET - > myip , DGRAM_PORT ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Broadcast a packet to the local net requesting that all servers in this
workgroup announce themselves to us .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void broadcast_announce_request ( struct subnet_record * subrec , struct work_record * work )
{
2007-11-30 04:25:41 +03:00
char outbuf [ 1024 ] ;
2003-08-27 05:25:01 +04:00
char * p ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
work - > needannounce = True ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " broadcast_announce_request: sending announce request for workgroup %s \
1997-12-13 17:16:07 +03:00
to subnet % s \ n " , work->work_group, subrec->subnet_name));
2003-08-27 05:25:01 +04:00
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
p = outbuf ;
SCVAL ( p , 0 , ANN_AnnouncementRequest ) ;
p + + ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
SCVAL ( p , 0 , work - > token ) ; /* (local) Unique workgroup token id. */
p + + ;
2011-06-09 09:31:03 +04:00
p + = push_string_check ( p + 1 , lp_netbios_name ( ) , 15 , STR_ASCII | STR_UPPER | STR_TERMINATE ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
send_mailslot ( False , BROWSE_MAILSLOT , outbuf , PTR_DIFF ( p , outbuf ) ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , 0x0 , work - > work_group , 0x1e , subrec - > bcast_ip ,
1998-08-30 21:04:24 +04:00
subrec - > myip , DGRAM_PORT ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Broadcast an announcement .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_announcement ( struct subnet_record * subrec , int announce_type ,
2002-11-13 02:20:50 +03:00
const char * from_name , const char * to_name , int to_type , struct in_addr to_ip ,
1997-12-13 17:16:07 +03:00
time_t announce_interval ,
2002-11-13 02:20:50 +03:00
const char * server_name , int server_type , const char * server_comment )
1997-12-13 17:16:07 +03:00
{
2007-11-30 04:25:41 +03:00
char outbuf [ 1024 ] ;
2004-03-16 03:10:30 +03:00
unstring upper_server_name ;
2003-08-27 05:25:01 +04:00
char * p ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
p = outbuf + 1 ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
SCVAL ( outbuf , 0 , announce_type ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
/* Announcement parameters. */
SCVAL ( p , 0 , updatecount ) ;
SIVAL ( p , 1 , announce_interval * 1000 ) ; /* Milliseconds - despite the spec. */
1997-12-13 17:16:07 +03:00
2011-05-04 00:10:01 +04:00
strlcpy ( upper_server_name , server_name ? server_name : " " , sizeof ( upper_server_name ) ) ;
2012-08-09 02:35:28 +04:00
if ( ! strupper_m ( upper_server_name ) ) {
DEBUG ( 2 , ( " strupper_m %s failed \n " , upper_server_name ) ) ;
return ;
}
2009-03-17 06:04:43 +03:00
push_string_check ( p + 5 , upper_server_name , 16 , STR_ASCII | STR_TERMINATE ) ;
1997-12-13 17:16:07 +03:00
2011-06-21 09:14:29 +04:00
SCVAL ( p , 21 , SAMBA_MAJOR_NBT_ANNOUNCE_VERSION ) ; /* Major version. */
SCVAL ( p , 22 , SAMBA_MINOR_NBT_ANNOUNCE_VERSION ) ; /* Minor version. */
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
SIVAL ( p , 23 , server_type & ~ SV_TYPE_LOCAL_LIST_ONLY ) ;
/* Browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT). */
SSVAL ( p , 27 , BROWSER_ELECTION_VERSION ) ;
SSVAL ( p , 29 , BROWSER_CONSTANT ) ; /* Browse signature. */
1997-12-13 17:16:07 +03:00
2009-03-17 06:04:43 +03:00
p + = 31 + push_string_check ( p + 31 , server_comment , sizeof ( outbuf ) - ( p + 31 - outbuf ) , STR_ASCII | STR_TERMINATE ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
send_mailslot ( False , BROWSE_MAILSLOT , outbuf , PTR_DIFF ( p , outbuf ) ,
from_name , 0x0 , to_name , to_type , to_ip , subrec - > myip ,
DGRAM_PORT ) ;
1997-12-13 17:16:07 +03:00
}
1997-12-16 12:20:34 +03:00
/****************************************************************************
Broadcast a LanMan announcement .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_lm_announcement ( struct subnet_record * subrec , int announce_type ,
char * from_name , char * to_name , int to_type , struct in_addr to_ip ,
time_t announce_interval ,
char * server_name , int server_type , char * server_comment )
{
2007-11-30 04:25:41 +03:00
char outbuf [ 1024 ] ;
2003-08-27 05:25:01 +04:00
char * p = outbuf ;
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
SSVAL ( p , 0 , announce_type ) ;
SIVAL ( p , 2 , server_type & ~ SV_TYPE_LOCAL_LIST_ONLY ) ;
2011-06-21 09:14:29 +04:00
SCVAL ( p , 6 , SAMBA_MAJOR_NBT_ANNOUNCE_VERSION ) ; /* Major version. */
SCVAL ( p , 7 , SAMBA_MINOR_NBT_ANNOUNCE_VERSION ) ; /* Minor version. */
2003-08-27 05:25:01 +04:00
SSVAL ( p , 8 , announce_interval ) ; /* In seconds - according to spec. */
p + = 10 ;
2009-03-17 06:04:43 +03:00
p + = push_string_check ( p , server_name , 15 , STR_ASCII | STR_UPPER | STR_TERMINATE ) ;
p + = push_string_check ( p , server_comment , sizeof ( outbuf ) - ( p - outbuf ) , STR_ASCII | STR_UPPER | STR_TERMINATE ) ;
2003-08-27 05:25:01 +04:00
send_mailslot ( False , LANMAN_MAILSLOT , outbuf , PTR_DIFF ( p , outbuf ) ,
from_name , 0x0 , to_name , to_type , to_ip , subrec - > myip ,
1998-08-30 21:04:24 +04:00
DGRAM_PORT ) ;
1997-12-16 12:20:34 +03:00
}
1997-12-13 17:16:07 +03:00
/****************************************************************************
We are a local master browser . Announce this to WORKGROUP < 1 e > .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_local_master_announcement ( struct subnet_record * subrec , struct work_record * work ,
struct server_record * servrec )
{
2003-08-27 05:25:01 +04:00
/* Ensure we don't have the prohibited bit set. */
2015-04-30 06:14:34 +03:00
uint32_t type = servrec - > serv . type & ~ SV_TYPE_LOCAL_LIST_ONLY ;
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s \n " ,
2011-06-09 09:31:03 +04:00
type , lp_netbios_name ( ) , subrec - > subnet_name , work - > work_group ) ) ;
2003-08-27 05:25:01 +04:00
send_announcement ( subrec , ANN_LocalMasterAnnouncement ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , /* From nbt name. */
2003-08-27 05:25:01 +04:00
work - > work_group , 0x1e , /* To nbt name. */
subrec - > bcast_ip , /* To ip. */
work - > announce_interval , /* Time until next announce. */
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , /* Name to announce. */
2003-08-27 05:25:01 +04:00
type , /* Type field. */
servrec - > serv . comment ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Announce the workgroup WORKGROUP to MSBROWSE < 01 > .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_workgroup_announcement ( struct subnet_record * subrec , struct work_record * work )
{
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " send_workgroup_announcement: on subnet %s for workgroup %s \n " ,
subrec - > subnet_name , work - > work_group ) ) ;
send_announcement ( subrec , ANN_DomainAnnouncement ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , /* From nbt name. */
2003-08-27 05:25:01 +04:00
MSBROWSE , 0x1 , /* To nbt name. */
subrec - > bcast_ip , /* To ip. */
work - > announce_interval , /* Time until next announce. */
work - > work_group , /* Name to announce. */
SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT , /* workgroup announce flags. */
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) ) ; /* From name as comment. */
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Announce the given host to WORKGROUP < 1 d > .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_host_announcement ( struct subnet_record * subrec , struct work_record * work ,
struct server_record * servrec )
{
2003-08-27 05:25:01 +04:00
/* Ensure we don't have the prohibited bits set. */
2015-04-30 06:14:34 +03:00
uint32_t type = servrec - > serv . type & ~ SV_TYPE_LOCAL_LIST_ONLY ;
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " send_host_announcement: type %x for host %s on subnet %s for workgroup %s \n " ,
type , servrec - > serv . name , subrec - > subnet_name , work - > work_group ) ) ;
send_announcement ( subrec , ANN_HostAnnouncement ,
servrec - > serv . name , /* From nbt name. */
work - > work_group , 0x1d , /* To nbt name. */
subrec - > bcast_ip , /* To ip. */
work - > announce_interval , /* Time until next announce. */
servrec - > serv . name , /* Name to announce. */
type , /* Type field. */
servrec - > serv . comment ) ;
1997-12-13 17:16:07 +03:00
}
1997-12-16 12:20:34 +03:00
/****************************************************************************
Announce the given LanMan host
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_lm_host_announcement ( struct subnet_record * subrec , struct work_record * work ,
struct server_record * servrec , int lm_interval )
{
2003-08-27 05:25:01 +04:00
/* Ensure we don't have the prohibited bits set. */
2015-04-30 06:14:34 +03:00
uint32_t type = servrec - > serv . type & ~ SV_TYPE_LOCAL_LIST_ONLY ;
2003-08-27 05:25:01 +04:00
DEBUG ( 3 , ( " send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d \n " ,
type , servrec - > serv . name , subrec - > subnet_name , work - > work_group , lm_interval ) ) ;
send_lm_announcement ( subrec , ANN_HostAnnouncement ,
servrec - > serv . name , /* From nbt name. */
work - > work_group , 0x00 , /* To nbt name. */
subrec - > bcast_ip , /* To ip. */
lm_interval , /* Time until next announce. */
servrec - > serv . name , /* Name to announce (fstring not netbios name struct). */
type , /* Type field. */
servrec - > serv . comment ) ;
1997-12-16 12:20:34 +03:00
}
1997-12-13 17:16:07 +03:00
/****************************************************************************
Announce a server record .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void announce_server ( struct subnet_record * subrec , struct work_record * work ,
struct server_record * servrec )
{
2003-08-27 05:25:01 +04:00
/* Only do domain announcements if we are a master and it's
our primary name we ' re being asked to announce . */
2011-06-09 09:31:03 +04:00
if ( AM_LOCAL_MASTER_BROWSER ( work ) & & strequal ( lp_netbios_name ( ) , servrec - > serv . name ) ) {
2003-08-27 05:25:01 +04:00
send_local_master_announcement ( subrec , work , servrec ) ;
send_workgroup_announcement ( subrec , work ) ;
} else {
send_host_announcement ( subrec , work , servrec ) ;
}
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Go through all my registered names on all broadcast subnets and announce
them if the timeout requires it .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_my_server_names ( time_t t )
{
2003-08-27 05:25:01 +04:00
struct subnet_record * subrec ;
for ( subrec = FIRST_SUBNET ; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST ( subrec ) ) {
struct work_record * work = find_workgroup_on_subnet ( subrec , lp_workgroup ( ) ) ;
if ( work ) {
struct server_record * servrec ;
if ( work - > needannounce ) {
/* Drop back to a max 3 minute announce. This is to prevent a
single lost packet from breaking things for too long . */
work - > announce_interval = MIN ( work - > announce_interval ,
CHECK_TIME_MIN_HOST_ANNCE * 60 ) ;
work - > lastannounce_time = t - ( work - > announce_interval + 1 ) ;
work - > needannounce = False ;
}
/* Announce every minute at first then progress to every 12 mins */
2018-09-17 22:45:14 +03:00
if ( t > = work - > lastannounce_time & &
2017-12-07 17:24:59 +03:00
( t - work - > lastannounce_time ) < work - > announce_interval ) {
2003-08-27 05:25:01 +04:00
continue ;
2017-12-07 17:24:59 +03:00
}
2003-08-27 05:25:01 +04:00
if ( work - > announce_interval < ( CHECK_TIME_MAX_HOST_ANNCE * 60 ) )
work - > announce_interval + = 60 ;
work - > lastannounce_time = t ;
for ( servrec = work - > serverlist ; servrec ; servrec = servrec - > next ) {
if ( is_myname ( servrec - > serv . name ) )
announce_server ( subrec , work , servrec ) ;
}
} /* if work */
} /* for subrec */
1997-12-13 17:16:07 +03:00
}
1997-12-16 12:20:34 +03:00
/****************************************************************************
Go through all my registered names on all broadcast subnets and announce
them as a LanMan server if the timeout requires it .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_my_lm_server_names ( time_t t )
{
2003-08-27 05:25:01 +04:00
struct subnet_record * subrec ;
static time_t last_lm_announce_time = 0 ;
int announce_interval = lp_lm_interval ( ) ;
int lm_announce = lp_lm_announce ( ) ;
if ( ( announce_interval < = 0 ) | | ( lm_announce < = 0 ) ) {
/* user absolutely does not want LM announcements to be sent. */
return ;
}
if ( ( lm_announce > = 2 ) & & ( ! found_lm_clients ) ) {
/* has been set to 2 (Auto) but no LM clients detected (yet). */
return ;
}
/* Otherwise: must have been set to 1 (Yes), or LM clients *have*
been detected . */
for ( subrec = FIRST_SUBNET ; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST ( subrec ) ) {
struct work_record * work = find_workgroup_on_subnet ( subrec , lp_workgroup ( ) ) ;
if ( work ) {
struct server_record * servrec ;
if ( last_lm_announce_time & & ( ( t - last_lm_announce_time ) < announce_interval ) )
continue ;
last_lm_announce_time = t ;
for ( servrec = work - > serverlist ; servrec ; servrec = servrec - > next ) {
if ( is_myname ( servrec - > serv . name ) )
/* skipping equivalent of announce_server() */
send_lm_host_announcement ( subrec , work , servrec , announce_interval ) ;
}
} /* if work */
} /* for subrec */
1997-12-16 12:20:34 +03:00
}
1997-12-13 17:16:07 +03:00
/* Announce timer. Moved into global static so it can be reset
when a machine becomes a local master browser . */
static time_t announce_timer_last = 0 ;
/****************************************************************************
Reset the announce_timer so that a local master browser announce will be done
immediately .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
void reset_announce_timer ( void )
1997-12-13 17:16:07 +03:00
{
2003-08-27 05:25:01 +04:00
announce_timer_last = time ( NULL ) - ( CHECK_TIME_MST_ANNOUNCE * 60 ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Announce myself as a local master browser to a domain master browser .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_myself_to_domain_master_browser ( time_t t )
{
2003-08-27 05:25:01 +04:00
struct subnet_record * subrec ;
struct work_record * work ;
if ( ! we_are_a_wins_client ( ) ) {
DEBUG ( 10 , ( " announce_myself_to_domain_master_browser: no unicast subnet, ignoring. \n " ) ) ;
return ;
}
if ( ! announce_timer_last )
announce_timer_last = t ;
if ( ( t - announce_timer_last ) < ( CHECK_TIME_MST_ANNOUNCE * 60 ) ) {
DEBUG ( 10 , ( " announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d \n " ,
( int ) t , ( int ) announce_timer_last ,
CHECK_TIME_MST_ANNOUNCE * 60 ) ) ;
return ;
}
announce_timer_last = t ;
/* Look over all our broadcast subnets to see if any of them
has the state set as local master browser . */
for ( subrec = FIRST_SUBNET ; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST ( subrec ) ) {
for ( work = subrec - > workgrouplist ; work ; work = work - > next ) {
if ( AM_LOCAL_MASTER_BROWSER ( work ) ) {
DEBUG ( 4 , ( " announce_myself_to_domain_master_browser: I am a local master browser for \
1997-12-13 17:16:07 +03:00
workgroup % s on subnet % s \ n " , work->work_group, subrec->subnet_name));
2003-08-27 05:25:01 +04:00
/* Look in nmbd_browsersync.c for the rest of this code. */
announce_and_sync_with_domain_master_browser ( subrec , work ) ;
}
}
}
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Announce all samba ' s server entries as ' gone ' .
This must * only * be called on shutdown .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_my_servers_removed ( void )
{
2003-08-27 05:25:01 +04:00
int announce_interval = lp_lm_interval ( ) ;
int lm_announce = lp_lm_announce ( ) ;
struct subnet_record * subrec ;
for ( subrec = FIRST_SUBNET ; subrec ; subrec = NEXT_SUBNET_EXCLUDING_UNICAST ( subrec ) ) {
struct work_record * work ;
for ( work = subrec - > workgrouplist ; work ; work = work - > next ) {
struct server_record * servrec ;
work - > announce_interval = 0 ;
for ( servrec = work - > serverlist ; servrec ; servrec = servrec - > next ) {
if ( ! is_myname ( servrec - > serv . name ) )
continue ;
servrec - > serv . type = 0 ;
if ( AM_LOCAL_MASTER_BROWSER ( work ) )
send_local_master_announcement ( subrec , work , servrec ) ;
send_host_announcement ( subrec , work , servrec ) ;
if ( ( announce_interval < = 0 ) | | ( lm_announce < = 0 ) ) {
/* user absolutely does not want LM announcements to be sent. */
continue ;
}
if ( ( lm_announce > = 2 ) & & ( ! found_lm_clients ) ) {
/* has been set to 2 (Auto) but no LM clients detected (yet). */
continue ;
}
/*
* lm announce was set or we have seen lm announcements , so do
* a lm announcement of host removed .
*/
send_lm_host_announcement ( subrec , work , servrec , 0 ) ;
}
}
}
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Do all the " remote " announcements . These are used to put ourselves
on a remote browse list . They are done blind , no checking is done to
see if there is actually a local master browser at the other end .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_remote ( time_t t )
{
2003-08-27 05:25:01 +04:00
char * s ;
const char * ptr ;
static time_t last_time = 0 ;
2007-12-08 04:32:32 +03:00
char * s2 ;
2003-08-27 05:25:01 +04:00
struct in_addr addr ;
char * comment ;
int stype = lp_default_server_announce ( ) ;
2007-12-08 04:32:32 +03:00
TALLOC_CTX * frame = NULL ;
2003-08-27 05:25:01 +04:00
if ( last_time & & ( t < ( last_time + REMOTE_ANNOUNCE_INTERVAL ) ) )
return ;
last_time = t ;
2012-07-18 09:37:23 +04:00
s = lp_remote_announce ( talloc_tos ( ) ) ;
2003-08-27 05:25:01 +04:00
if ( ! * s )
return ;
2014-02-04 06:08:58 +04:00
comment = string_truncate ( lp_server_string ( talloc_tos ( ) ) ,
2012-07-18 09:37:23 +04:00
MAX_SERVER_STRING_LENGTH ) ;
2003-08-27 05:25:01 +04:00
2007-12-08 04:32:32 +03:00
frame = talloc_stackframe ( ) ;
for ( ptr = s ; next_token_talloc ( frame , & ptr , & s2 , NULL ) ; ) {
2007-11-20 02:15:09 +03:00
/* The entries are of the form a.b.c.d/WORKGROUP with
2003-08-27 05:25:01 +04:00
WORKGROUP being optional */
const char * wgroup ;
char * pwgroup ;
int i ;
pwgroup = strchr_m ( s2 , ' / ' ) ;
if ( pwgroup )
* pwgroup + + = 0 ;
if ( ! pwgroup | | ! * pwgroup )
wgroup = lp_workgroup ( ) ;
else
wgroup = pwgroup ;
2008-10-23 22:41:15 +04:00
addr = interpret_addr2 ( s2 ) ;
2007-11-20 02:15:09 +03:00
2003-08-27 05:25:01 +04:00
/* Announce all our names including aliases */
/* Give the ip address as the address of our first
broadcast subnet . */
for ( i = 0 ; my_netbios_names ( i ) ; i + + ) {
const char * name = my_netbios_names ( i ) ;
DEBUG ( 5 , ( " announce_remote: Doing remote announce for server %s to IP %s. \n " ,
name , inet_ntoa ( addr ) ) ) ;
send_announcement ( FIRST_SUBNET , ANN_HostAnnouncement ,
name , /* From nbt name. */
wgroup , 0x1d , /* To nbt name. */
addr , /* To ip. */
REMOTE_ANNOUNCE_INTERVAL , /* Time until next announce. */
name , /* Name to announce. */
stype , /* Type field. */
comment ) ;
}
}
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
1997-12-13 17:16:07 +03:00
}
/****************************************************************************
Implement the ' remote browse sync ' feature Andrew added .
These are used to put our browse lists into remote browse lists .
2003-08-27 05:25:01 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-12-13 17:16:07 +03:00
void browse_sync_remote ( time_t t )
2007-11-20 02:15:09 +03:00
{
2003-08-27 05:25:01 +04:00
char * s ;
const char * ptr ;
2007-11-20 02:15:09 +03:00
static time_t last_time = 0 ;
2007-12-08 04:32:32 +03:00
char * s2 ;
2003-08-27 05:25:01 +04:00
struct in_addr addr ;
struct work_record * work ;
2007-11-20 02:15:09 +03:00
char outbuf [ 1024 ] ;
2003-08-27 05:25:01 +04:00
char * p ;
2004-03-16 00:45:45 +03:00
unstring myname ;
2007-12-08 04:32:32 +03:00
TALLOC_CTX * frame = NULL ;
2007-11-20 02:15:09 +03:00
2003-08-27 05:25:01 +04:00
if ( last_time & & ( t < ( last_time + REMOTE_ANNOUNCE_INTERVAL ) ) )
return ;
2007-11-20 02:15:09 +03:00
2003-08-27 05:25:01 +04:00
last_time = t ;
2012-07-18 09:37:23 +04:00
s = lp_remote_browse_sync ( talloc_tos ( ) ) ;
2003-08-27 05:25:01 +04:00
if ( ! * s )
return ;
/*
* We only do this if we are the local master browser
* for our workgroup on the firsst subnet .
*/
if ( ( work = find_workgroup_on_subnet ( FIRST_SUBNET , lp_workgroup ( ) ) ) = = NULL ) {
DEBUG ( 0 , ( " browse_sync_remote: Cannot find workgroup %s on subnet %s \n " ,
lp_workgroup ( ) , FIRST_SUBNET - > subnet_name ) ) ;
return ;
}
2007-11-20 02:15:09 +03:00
2003-08-27 05:25:01 +04:00
if ( ! AM_LOCAL_MASTER_BROWSER ( work ) ) {
DEBUG ( 5 , ( " browse_sync_remote: We can only do this if we are a local master browser \
2002-11-13 02:20:50 +03:00
for workgroup % s on subnet % s . \ n " , lp_workgroup(), FIRST_SUBNET->subnet_name ));
2003-08-27 05:25:01 +04:00
return ;
2007-11-20 02:15:09 +03:00
}
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
memset ( outbuf , ' \0 ' , sizeof ( outbuf ) ) ;
p = outbuf ;
SCVAL ( p , 0 , ANN_MasterAnnouncement ) ;
p + + ;
1997-12-13 17:16:07 +03:00
2011-06-09 09:31:03 +04:00
unstrcpy ( myname , lp_netbios_name ( ) ) ;
2012-08-09 02:35:28 +04:00
if ( ! strupper_m ( myname ) ) {
DEBUG ( 2 , ( " strupper_m %s failed \n " , myname ) ) ;
return ;
}
2003-08-27 05:25:01 +04:00
myname [ 15 ] = ' \0 ' ;
2007-11-20 02:15:09 +03:00
push_ascii ( p , myname , sizeof ( outbuf ) - PTR_DIFF ( p , outbuf ) - 1 , STR_TERMINATE ) ;
2003-04-23 17:27:35 +04:00
2007-04-03 00:10:21 +04:00
p = skip_string ( outbuf , sizeof ( outbuf ) , p ) ;
1997-12-13 17:16:07 +03:00
2007-12-08 04:32:32 +03:00
frame = talloc_stackframe ( ) ;
for ( ptr = s ; next_token_talloc ( frame , & ptr , & s2 , NULL ) ; ) {
2003-08-27 05:25:01 +04:00
/* The entries are of the form a.b.c.d */
2008-10-23 22:41:15 +04:00
addr = interpret_addr2 ( s2 ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
DEBUG ( 5 , ( " announce_remote: Doing remote browse sync announce for server %s to IP %s. \n " ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , inet_ntoa ( addr ) ) ) ;
1997-12-13 17:16:07 +03:00
2003-08-27 05:25:01 +04:00
send_mailslot ( True , BROWSE_MAILSLOT , outbuf , PTR_DIFF ( p , outbuf ) ,
2011-06-09 09:31:03 +04:00
lp_netbios_name ( ) , 0x0 , " * " , 0x0 , addr , FIRST_SUBNET - > myip , DGRAM_PORT ) ;
2003-08-27 05:25:01 +04:00
}
2007-12-08 04:32:32 +03:00
TALLOC_FREE ( frame ) ;
1997-12-13 17:16:07 +03:00
}