/*
Unix SMB / Netbios implementation .
Version 1.9 .
NBT netbios routines and daemon - version 2
Copyright ( C ) Andrew Tridgell 1994 - 1997
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
Module name : nameelect . c
Revision History :
14 jan 96 : lkcl @ pires . co . uk
added multiple workgroup domain master support
04 jul 96 : lkcl @ pires . co . uk
added system to become a master browser by stages .
*/
# include "includes.h"
extern int ClientNMB ;
extern int ClientDGRAM ;
extern int DEBUGLEVEL ;
extern pstring scope ;
extern pstring myname ;
extern fstring myworkgroup ;
extern struct in_addr ipzero ;
extern struct in_addr wins_ip ;
/* here are my election parameters */
extern time_t StartupTime ;
extern struct subnet_record * subnetlist ;
extern uint16 nb_type ; /* samba's NetBIOS name type */
/*******************************************************************
occasionally check to see if the master browser is around
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void check_master_browser ( time_t t )
{
static time_t lastrun = 0 ;
struct subnet_record * d ;
if ( ! lastrun ) lastrun = t ;
if ( t < lastrun + CHECK_TIME_MST_BROWSE * 60 ) return ;
lastrun = t ;
dump_workgroups ( ) ;
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
{
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
if ( strequal ( work - > work_group , myworkgroup ) & & ! AM_MASTER ( work ) )
{
if ( lp_local_master ( ) & & lp_preferred_master ( ) )
{
/* potential master browser - not a master browser. force
becoming a master browser , hence the log message .
*/
DEBUG ( 2 , ( " %s potential master for %s %s - force election \n " ,
timestring ( ) , work - > work_group ,
inet_ntoa ( d - > bcast_ip ) ) ) ;
browser_gone ( work - > work_group , d - > bcast_ip ) ;
}
else
{
/* if we are not the browse master of a workgroup,
and we can ' t find a browser on the subnet , do
something about it .
*/
queue_netbios_packet ( d , ClientNMB , NMB_QUERY , NAME_QUERY_MST_CHK ,
work - > work_group , 0x1d , 0 , 0 , 0 , NULL , NULL ,
True , False , d - > bcast_ip , d - > bcast_ip ) ;
}
}
}
}
}
/*******************************************************************
what to do if a master browser DOESN ' t exist .
option 1 : force an election , and participate in it
option 2 : force an election , and let everyone else participate .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void browser_gone ( char * work_name , struct in_addr ip )
{
struct subnet_record * d = find_subnet ( ip ) ;
struct work_record * work = find_workgroupstruct ( d , work_name , False ) ;
/* i don't know about this workgroup, therefore i don't care */
if ( ! work | | ! d ) return ;
/* don't do election stuff on the WINS subnet */
if ( ip_equal ( d - > bcast_ip , wins_ip ) )
return ;
if ( strequal ( work - > work_group , myworkgroup ) )
{
if ( lp_local_master ( ) )
{
/* we have discovered that there is no local master
browser , and we are configured to initiate
an election under exactly such circumstances .
*/
DEBUG ( 2 , ( " Forcing election on %s %s \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
/* we can attempt to become master browser */
work - > needelection = True ;
}
else
{
/* we need to force an election, because we are configured
not to _become_ the local master , but we still _need_ one ,
having detected that one doesn ' t exist .
*/
/* local interfaces: force an election */
send_election ( d , work - > work_group , 0 , 0 , myname ) ;
/* only removes workgroup completely on a local interface
persistent lmhosts entries on a local interface _will_ be removed ) .
*/
remove_workgroup ( d , work , True ) ;
add_workgroup_to_subnet ( d , work - > work_group ) ;
}
}
}
/****************************************************************************
send an election packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void send_election ( struct subnet_record * d , char * group , uint32 criterion ,
int timeup , char * name )
{
pstring outbuf ;
char * p ;
if ( ! d ) return ;
DEBUG ( 2 , ( " Sending election to %s for workgroup %s \n " ,
inet_ntoa ( d - > bcast_ip ) , group ) ) ;
bzero ( outbuf , sizeof ( outbuf ) ) ;
p = outbuf ;
CVAL ( p , 0 ) = ANN_Election ; /* election */
p + + ;
CVAL ( p , 0 ) = ( criterion = = 0 & & timeup = = 0 ) ? 0 : ELECTION_VERSION ;
SIVAL ( p , 1 , criterion ) ;
SIVAL ( p , 5 , timeup * 1000 ) ; /* ms - despite the spec */
p + = 13 ;
pstrcpy ( p , name ) ;
strupper ( p ) ;
p = skip_string ( p , 1 ) ;
send_mailslot_reply ( False , BROWSE_MAILSLOT , ClientDGRAM ,
outbuf , PTR_DIFF ( p , outbuf ) ,
name , group , 0 , 0x1e , d - > bcast_ip , * iface_ip ( d - > bcast_ip ) ) ;
}
/****************************************************************************
un - register a SELF name that got rejected .
if this name happens to be rejected when samba is in the process
of becoming a master browser ( registering __MSBROWSE__ , WORKGROUP ( 1 d )
or WORKGROUP ( 1 b ) ) then we must stop being a master browser . sad .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void name_unregister_work ( struct subnet_record * d , char * name , int name_type )
{
struct work_record * work ;
int remove_type_local = 0 ;
int remove_type_domain = 0 ;
int remove_type_logon = 0 ;
remove_netbios_name ( d , name , name_type , SELF , ipzero ) ;
if ( ! ( work = find_workgroupstruct ( d , name , False ) ) ) return ;
/* work out what to unbecome, from the name type being removed */
if ( ms_browser_name ( name , name_type ) )
{
remove_type_local | = SV_TYPE_MASTER_BROWSER ;
}
if ( AM_MASTER ( work ) & & strequal ( name , myworkgroup ) & & name_type = = 0x1d )
{
remove_type_local | = SV_TYPE_MASTER_BROWSER ;
}
if ( AM_DOMMST ( work ) & & strequal ( name , myworkgroup ) & & name_type = = 0x1b )
{
remove_type_domain | = SV_TYPE_DOMAIN_MASTER ;
}
if ( AM_DOMMEM ( work ) & & strequal ( name , myworkgroup ) & & name_type = = 0x1c )
{
remove_type_logon | = SV_TYPE_DOMAIN_MEMBER ;
}
if ( remove_type_local ) unbecome_local_master ( d , work , remove_type_local ) ;
if ( remove_type_domain ) unbecome_domain_master ( d , work , remove_type_domain ) ;
if ( remove_type_logon ) unbecome_logon_server ( d , work , remove_type_logon ) ;
}
/****************************************************************************
registers a name .
if the name being added is a SELF name , we must additionally check
whether to proceed to the next stage in samba becoming a master browser .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void name_register_work ( struct subnet_record * d , char * name , int name_type ,
int nb_flags , time_t ttl , struct in_addr ip , BOOL bcast )
{
enum name_source source = ( ismyip ( ip ) | | ip_equal ( ip , ipzero ) ) ?
SELF : REGISTER ;
if ( source = = SELF )
{
struct work_record * work = find_workgroupstruct ( d ,
myworkgroup , False ) ;
add_netbios_entry ( d , name , name_type , nb_flags , ttl , source , ip , True , ! bcast ) ;
if ( work )
{
int add_type_local = False ;
int add_type_domain = False ;
int add_type_logon = False ;
DEBUG ( 4 , ( " checking next stage: name_register_work %s \n " , name ) ) ;
/* work out what to become, from the name type being added */
if ( ms_browser_name ( name , name_type ) )
{
add_type_local = True ;
}
if ( strequal ( name , myworkgroup ) & & name_type = = 0x1d )
{
add_type_local = True ;
}
if ( strequal ( name , myworkgroup ) & & name_type = = 0x1b )
{
add_type_domain = True ;
}
if ( strequal ( name , myworkgroup ) & & name_type = = 0x1c )
{
add_type_logon = True ;
}
if ( add_type_local ) become_local_master ( d , work ) ;
if ( add_type_domain ) become_domain_master ( d , work ) ;
if ( add_type_logon ) become_logon_server ( d , work ) ;
}
}
}
/*******************************************************************
become the local master browser .
this is done in stages . note that this could take a while ,
particularly on a broadcast subnet , as we have to wait for
the implicit registration of each name to be accepted .
as each name is successfully registered , become_local_master ( ) is
called again , in order to initiate the next stage . see
dead_netbios_entry ( ) - deals with implicit name registration
and response_name_reg ( ) - deals with explicit registration
with a WINS server .
stage 1 : was MST_POTENTIAL - go to MST_POTENTIAL and register ^ 1 ^ 2 __MSBROWSE__ ^ 2 ^ 1.
stage 2 : was MST_BACK - go to MST_MSB and register WORKGROUP ( 0x1d )
stage 3 : was MST_MSB - go to MST_BROWSER and stay there
XXXX note : this code still does not cope with the distinction
between different types of nodes , particularly between M and P
nodes . that comes later .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void become_local_master ( struct subnet_record * d , struct work_record * work )
{
/* domain type must be limited to domain enum + server type. it must
not have SV_TYPE_SERVER or anything else with SERVER in it , else
clients get confused and start thinking this entry is a server
not a workgroup
*/
uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT ;
if ( ! work | | ! d )
return ;
if ( ! lp_local_master ( ) )
{
DEBUG ( 0 , ( " Samba not configured as a local master browser. \n " ) ) ;
return ;
}
DEBUG ( 2 , ( " Becoming master for %s %s (currently at stage %d) \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) , work - > mst_state ) ) ;
switch ( work - > mst_state )
{
case MST_POTENTIAL : /* while we were nothing but a server... */
{
DEBUG ( 3 , ( " go to first stage: register ^1^2__MSBROWSE__^2^1 \n " ) ) ;
work - > mst_state = MST_BACK ; /* an election win was successful */
work - > ElectionCriterion | = 0x5 ;
/* update our server status */
work - > ServerType & = ~ SV_TYPE_POTENTIAL_BROWSER ;
add_server_entry ( d , work , myname , work - > ServerType | SV_TYPE_LOCAL_LIST_ONLY ,
0 , lp_serverstring ( ) , True ) ;
/* add special browser name */
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
add_my_name_entry ( d , MSBROWSE , 0x01 , nb_type | NB_ACTIVE | NB_GROUP ) ;
/* DON'T do anything else after calling add_my_name_entry() */
break ;
}
case MST_BACK : /* while nothing had happened except we won an election... */
{
DEBUG ( 3 , ( " go to second stage: register as master browser \n " ) ) ;
work - > mst_state = MST_MSB ; /* registering MSBROWSE was successful */
/* add server entry on successful registration of MSBROWSE */
add_server_entry ( d , work , work - > work_group , domain_type | SV_TYPE_LOCAL_LIST_ONLY ,
0 , myname , True ) ;
/* add master name */
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
add_my_name_entry ( d , work - > work_group , 0x1d , nb_type | NB_ACTIVE ) ;
/* DON'T do anything else after calling add_my_name_entry() */
break ;
}
case MST_MSB : /* while we were still only registered MSBROWSE state... */
{
int i = 0 ;
struct server_record * sl ;
DEBUG ( 3 , ( " 2nd stage complete: registered as master browser for workgroup %s \
on subnet % s \ n " , work->work_group, inet_ntoa(d->bcast_ip)));
work - > mst_state = MST_BROWSER ; /* registering WORKGROUP(1d) succeeded */
/* update our server status */
work - > ServerType | = SV_TYPE_MASTER_BROWSER ;
DEBUG ( 3 , ( " become_local_master: updating our server %s to type %x \n " ,
myname , work - > ServerType ) ) ;
add_server_entry ( d , work , myname , work - > ServerType | SV_TYPE_LOCAL_LIST_ONLY ,
0 , lp_serverstring ( ) , True ) ;
/* Count the number of servers we have on our list. If it's
less than 10 ( just a heuristic ) request the servers
to announce themselves .
*/
for ( sl = work - > serverlist ; sl ! = NULL ; sl = sl - > next )
i + + ;
if ( i < 10 )
{
/* ask all servers on our local net to announce to us */
announce_request ( work , d - > bcast_ip ) ;
}
/* Reset the announce master timer so that we do an announce as soon as possible
now we are a master . */
reset_announce_timer ( ) ;
DEBUG ( 0 , ( " Samba is now a local master browser for workgroup %s on subnet %s \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
break ;
}
case MST_BROWSER :
{
/* don't have to do anything: just report success */
DEBUG ( 3 , ( " 3rd stage: become master browser! \n " ) ) ;
break ;
}
}
}
/*******************************************************************
become the domain master browser .
this is done in stages . note that this could take a while ,
particularly on a broadcast subnet , as we have to wait for
the implicit registration of each name to be accepted .
as each name is successfully registered , become_domain_master ( ) is
called again , in order to initiate the next stage . see
dead_netbios_entry ( ) - deals with implicit name registration
and response_name_reg ( ) - deals with explicit registration
with a WINS server .
stage 1 : was DOMAIN_NONE - go to DOMAIN_MST
XXXX note : this code still does not cope with the distinction
between different types of nodes , particularly between M and P
nodes . that comes later .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void become_domain_master ( struct subnet_record * d , struct work_record * work )
{
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
/* domain type must be limited to domain enum + server type. it must
not have SV_TYPE_SERVER or anything else with SERVER in it , else
clients get confused and start thinking this entry is a server
not a workgroup
*/
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
if ( ! work | | ! d ) return ;
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
if ( ! lp_domain_master ( ) )
{
DEBUG ( 0 , ( " Samba not configured as a domain master browser. \n " ) ) ;
return ;
}
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
DEBUG ( 2 , ( " Becoming domain master for %s %s (currently at stage %d) \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) , work - > dom_state ) ) ;
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
switch ( work - > dom_state )
{
case DOMAIN_NONE : /* while we were nothing but a server... */
{
DEBUG ( 3 , ( " become_domain_master: go to first stage: register <1b> name \n " ) ) ;
work - > dom_state = DOMAIN_WAIT ;
/* XXXX the 0x1b is domain master browser name */
add_my_name_entry ( d , work - > work_group , 0x1b , nb_type | NB_ACTIVE ) ;
/* DON'T do anything else after calling add_my_name_entry() */
break ;
}
case DOMAIN_WAIT :
{
work - > dom_state = DOMAIN_MST ; /* ... become domain master */
DEBUG ( 3 , ( " become_domain_master: first stage - register as domain member \n " ) ) ;
/* update our server status */
work - > ServerType | = SV_TYPE_NT | SV_TYPE_DOMAIN_MASTER ;
add_server_entry ( d , work , myname , work - > ServerType | SV_TYPE_LOCAL_LIST_ONLY ,
0 , lp_serverstring ( ) , True ) ;
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
DEBUG ( 0 , ( " Samba is now a domain master browser for workgroup %s on subnet %s \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
if ( d = = wins_subnet )
{
/* ok! we successfully registered by unicast with the
WINS server . we now expect to become the domain
master on the local subnets . if this fails , it ' s
probably a 1.9 .16 p2 to 1.9 .16 p11 server ' s fault .
this is a configuration issue that should be addressed
by the network administrator - you shouldn ' t have
several machines configured as a domain master browser
for the same WINS scope ( except if they are 1.9 .17 or
greater , and you know what you ' re doing .
see DOMAIN . txt .
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
*/
add_domain_master_bcast ( ) ;
}
break ;
}
case DOMAIN_MST :
{
/* don't have to do anything: just report success */
DEBUG ( 3 , ( " domain second stage: there isn't one! \n " ) ) ;
break ;
}
}
}
/*******************************************************************
become a logon server .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void become_logon_server ( struct subnet_record * d , struct work_record * work )
{
if ( ! work | | ! d ) return ;
if ( ! lp_domain_logons ( ) )
{
DEBUG ( 0 , ( " samba not configured as a logon master. \n " ) ) ;
return ;
}
DEBUG ( 2 , ( " Becoming logon server for %s %s (currently at stage %d) \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) , work - > log_state ) ) ;
switch ( work - > log_state )
{
case LOGON_NONE : /* while we were nothing but a server... */
{
DEBUG ( 3 , ( " go to first stage: register <1c> name \n " ) ) ;
work - > log_state = LOGON_WAIT ;
/* XXXX the 0x1c is apparently something to do with domain logons */
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
add_my_name_entry ( d , myworkgroup , 0x1c , nb_type | NB_ACTIVE | NB_GROUP ) ;
/* DON'T do anything else after calling add_my_name_entry() */
break ;
}
case LOGON_WAIT :
{
work - > log_state = LOGON_SRV ; /* ... become logon server */
DEBUG ( 3 , ( " logon second stage: register \n " ) ) ;
/* update our server status */
work - > ServerType | = SV_TYPE_NT | SV_TYPE_DOMAIN_MEMBER ;
add_server_entry ( d , work , myname , work - > ServerType | SV_TYPE_LOCAL_LIST_ONLY
, 0 , lp_serverstring ( ) , True ) ;
/* DON'T do anything else after calling add_my_name_entry() */
break ;
}
case LOGON_SRV :
{
DEBUG ( 3 , ( " logon third stage: there isn't one! \n " ) ) ;
break ;
}
}
}
/*******************************************************************
unbecome the local master browser . initates removal of necessary netbios
names , and tells the world that we are no longer a master browser .
XXXX this _should_ be used to demote to a backup master browser , without
going straight to non - master browser . another time .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void unbecome_local_master ( struct subnet_record * d , struct work_record * work ,
int remove_type )
{
int new_server_type = work - > ServerType ;
/* can only remove master types with this function */
remove_type & = SV_TYPE_MASTER_BROWSER ;
new_server_type & = ~ remove_type ;
if ( remove_type )
{
DEBUG ( 2 , ( " Becoming local non-master for %s \n " , work - > work_group ) ) ;
/* no longer a master browser of any sort */
work - > ServerType | = SV_TYPE_POTENTIAL_BROWSER ;
work - > ElectionCriterion & = ~ 0x4 ;
work - > mst_state = MST_POTENTIAL ;
/* announce ourselves as no longer active as a master browser. */
announce_server ( d , work , work - > work_group , myname , 0 , 0 ) ;
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
remove_name_entry ( d , MSBROWSE , 0x01 ) ;
remove_name_entry ( d , work - > work_group , 0x1d ) ;
}
}
/*******************************************************************
unbecome the domain master browser . initates removal of necessary netbios
names , and tells the world that we are no longer a domain browser .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void unbecome_domain_master ( struct subnet_record * d , struct work_record * work ,
int remove_type )
{
int new_server_type = work - > ServerType ;
DEBUG ( 2 , ( " Becoming domain non-master for %s \n " , work - > work_group ) ) ;
/* can only remove master or domain types with this function */
remove_type & = SV_TYPE_DOMAIN_MASTER ;
new_server_type & = ~ remove_type ;
if ( remove_type )
{
/* no longer a domain master browser of any sort */
work - > dom_state = DOMAIN_NONE ;
/* announce ourselves as no longer active as a master browser on
all our local subnets . */
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
{
work = find_workgroupstruct ( d , myworkgroup , False ) ;
/* Remove the name entry without any NetBIOS traffic as that's
how it was registered . */
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
remove_name_entry ( d , work - > work_group , 0x1b ) ;
}
/* Unregister the 1b name from the WINS server. */
if ( wins_subnet ! = NULL )
remove_name_entry ( wins_subnet , myworkgroup , 0x1b ) ;
}
}
/*******************************************************************
unbecome the logon server . initates removal of necessary netbios
names , and tells the world that we are no longer a logon server .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void unbecome_logon_server ( struct subnet_record * d , struct work_record * work ,
int remove_type )
{
int new_server_type = work - > ServerType ;
DEBUG ( 2 , ( " Becoming logon non-server for %s \n " , work - > work_group ) ) ;
/* can only remove master or domain types with this function */
remove_type & = SV_TYPE_DOMAIN_MEMBER ;
new_server_type & = ~ remove_type ;
if ( remove_type )
{
/* no longer a master browser of any sort */
work - > log_state = LOGON_NONE ;
nameserv.c: split add_domain_names() into three functions:
add_domain_logon_names() - adds <1c> names on WINS and broadcast.
add_domain_master_wins() - adds <1b> name only with WINS server
add_domain_master_bcast() - adds <1b> names only by bcast.
: made add_domain_names() add <1c> names, unconditionally, and
add <1b> name with the WINS server if using a WINS server, or
add <1b> name by broadcast if _not_ using a WINS server, but
_not_ both.
: removed the direct parameter from remove_name_entry() and
add_my_name_entry().
nameelect.c: made become_domain_master(), on successful registration of
the <1b> name with the WINS server, go ahead and register
the <1b> names by broadcast. if the <1b> name is _not_
successfully registered with the WINS server, the broadcast
registration of <1b> names will _not_ proceed.
namedbsubnet.c: sorted out calls to add_my_name_entry() and remove_my_name()
which no longer has a direct parameter.
this is all added because...
in order to fix a compatibility bug with 1.9.16p2->p11, jeremy had added a
feature that got the <1b> broadcast registered names _directly_ into the nmbd
netbios lists, undefended. the aim was to get round the aggressive netbios
registration of <1b> names of 1.9.16p2->p11.
however, because 1.9.16p2->p11 don't properly _provide_ netlogon services,
it is better that an error message appears in 1.9.17 logs, and that
administrators are made aware of the problems with 1.9.16p2->p11, and replace
1.9.16p2->p11 servers, rather than attempt to run 1.9.16 alonside 1.9.17.
(these warning messages will need to be added...)
in _addition_, they shouldn't _be_ getting two samba servers to provide
domain logon / domain master services for the same workgroup in the same
WINS scope!
lkcl
-
remove_name_entry ( d , work - > work_group , 0x1c ) ;
}
}
/*******************************************************************
run the election
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void run_elections ( time_t t )
{
static time_t lastime = 0 ;
struct subnet_record * d ;
/* send election packets once a second */
if ( lastime & & t - lastime < = 0 ) return ;
lastime = t ;
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
{
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
if ( work - > RunningElection )
{
send_election ( d , work - > work_group , work - > ElectionCriterion ,
t - StartupTime , myname ) ;
if ( work - > ElectionCount + + > = 4 )
{
/* I won! now what :-) */
DEBUG ( 2 , ( " >>> Won election on %s %s <<< \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
work - > RunningElection = False ;
work - > mst_state = MST_POTENTIAL ;
become_local_master ( d , work ) ;
}
}
}
}
}
/*******************************************************************
work out if I win an election
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL win_election ( struct work_record * work , int version , uint32 criterion ,
int timeup , char * name )
{
int mytimeup = time ( NULL ) - StartupTime ;
uint32 mycriterion = work - > ElectionCriterion ;
/* If local master is false then never win
in election broadcasts . */
if ( ! lp_local_master ( ) )
{
DEBUG ( 3 , ( " win_election: Losing election as local master == False \n " ) ) ;
return False ;
}
DEBUG ( 4 , ( " election comparison: %x:%x %x:%x %d:%d %s:%s \n " ,
version , ELECTION_VERSION ,
criterion , mycriterion ,
timeup , mytimeup ,
name , myname ) ) ;
if ( version > ELECTION_VERSION ) return ( False ) ;
if ( version < ELECTION_VERSION ) return ( True ) ;
if ( criterion > mycriterion ) return ( False ) ;
if ( criterion < mycriterion ) return ( True ) ;
if ( timeup > mytimeup ) return ( False ) ;
if ( timeup < mytimeup ) return ( True ) ;
if ( strcasecmp ( myname , name ) > 0 ) return ( False ) ;
return ( True ) ;
}
/*******************************************************************
process a election packet
An election dynamically decides who will be the master .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void process_election ( struct packet_struct * p , char * buf )
{
struct dgram_packet * dgram = & p - > packet . dgram ;
struct in_addr ip = dgram - > header . source_ip ;
struct subnet_record * d = find_subnet ( ip ) ;
int version = CVAL ( buf , 0 ) ;
uint32 criterion = IVAL ( buf , 1 ) ;
int timeup = IVAL ( buf , 5 ) / 1000 ;
char * name = buf + 13 ;
struct work_record * work ;
if ( ! d ) return ;
if ( ip_equal ( d - > bcast_ip , wins_ip ) )
{
DEBUG ( 0 , ( " Unexpected election request from %s %s on WINS net \n " ,
name , inet_ntoa ( p - > ip ) ) ) ;
return ;
}
name [ 15 ] = 0 ;
DEBUG ( 3 , ( " Election request from %s %s vers=%d criterion=%08x timeup=%d \n " ,
name , inet_ntoa ( p - > ip ) , version , criterion , timeup ) ) ;
if ( same_context ( dgram ) ) return ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
if ( ! strequal ( work - > work_group , myworkgroup ) )
continue ;
if ( win_election ( work , version , criterion , timeup , name ) )
{
if ( ! work - > RunningElection )
{
work - > needelection = True ;
work - > ElectionCount = 0 ;
work - > mst_state = MST_POTENTIAL ;
}
}
else
{
work - > needelection = False ;
if ( work - > RunningElection | | AM_MASTER ( work ) )
{
work - > RunningElection = False ;
DEBUG ( 3 , ( " >>> Lost election on %s %s <<< \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
if ( AM_MASTER ( work ) )
{
unbecome_local_master ( d , work , SV_TYPE_MASTER_BROWSER ) ;
}
}
}
}
}
/****************************************************************************
checks whether a browser election is to be run on any workgroup
this function really ought to return the time between election
packets ( which depends on whether samba intends to be a domain
master or a master browser ) in milliseconds .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL check_elections ( void )
{
struct subnet_record * d ;
BOOL run_any_election = False ;
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
{
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
run_any_election | = work - > RunningElection ;
if ( work - > needelection & & ! work - > RunningElection )
{
DEBUG ( 3 , ( " >>> Starting election on %s %s <<< \n " ,
work - > work_group , inet_ntoa ( d - > bcast_ip ) ) ) ;
work - > ElectionCount = 0 ;
work - > RunningElection = True ;
work - > needelection = False ;
}
}
}
return run_any_election ;
}