summaryrefslogtreecommitdiff
path: root/source3/nameelect.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nameelect.c')
-rw-r--r--source3/nameelect.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/source3/nameelect.c b/source3/nameelect.c
index 1832240a11..c841d9b7a6 100644
--- a/source3/nameelect.c
+++ b/source3/nameelect.c
@@ -42,8 +42,6 @@ extern pstring ServerComment;
extern time_t StartupTime;
-#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
-
#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
extern struct subnet_record *subnetlist;
@@ -61,7 +59,6 @@ void check_master_browser(void)
if (!lastrun) lastrun = t;
if (t < lastrun + CHECK_TIME_MST_BROWSE * 60)
return;
-
lastrun = t;
dump_workgroups();
@@ -77,8 +74,8 @@ void check_master_browser(void)
if (!AM_MASTER(work))
{
- queue_netbios_packet(ClientNMB,NMB_QUERY,CHECK_MASTER,
- work->work_group,0x1d,0,
+ queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
+ work->work_group,0x1d,0,0,
True,False,d->bcast_ip);
}
}
@@ -91,13 +88,13 @@ void check_master_browser(void)
******************************************************************/
void browser_gone(char *work_name, struct in_addr ip)
{
- struct subnet_record *d = find_domain(ip);
+ struct subnet_record *d = find_subnet(ip);
struct work_record *work = find_workgroupstruct(d, work_name, False);
if (!work || !d) return;
if (strequal(work->work_group, lp_workgroup()) &&
- d->my_interface)
+ ismybcast(d->bcast_ip))
{
DEBUG(2,("Forcing election on %s %s\n",
@@ -121,6 +118,7 @@ void browser_gone(char *work_name, struct in_addr ip)
}
}
+
/****************************************************************************
send an election packet
**************************************************************************/
@@ -169,15 +167,16 @@ static void become_master(struct subnet_record *d, struct work_record *work)
work->ElectionCriterion |= 0x5;
/* add browse, master and general names to database or register with WINS */
- add_name_entry(MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
- add_name_entry(work->work_group,0x1d,NB_ACTIVE );
+ add_my_name_entry(d,MSBROWSE ,0x01,NB_ACTIVE|NB_GROUP);
+ add_my_name_entry(d,work->work_group,0x1d,NB_ACTIVE );
if (lp_domain_master())
{
DEBUG(4,("Domain master: adding names...\n"));
/* add domain master and domain member names or register with WINS */
- add_name_entry(work->work_group,0x1b,NB_ACTIVE);
+ add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE );
+
work->ServerType |= SV_TYPE_DOMAIN_MASTER;
if (lp_domain_logons())
@@ -200,21 +199,44 @@ static void become_master(struct subnet_record *d, struct work_record *work)
/*******************************************************************
- unbecome the master browser
+ unbecome the master browser. initates removal of necessary netbios
+ names, and tells the world that we are no longer a master browser.
******************************************************************/
-void become_nonmaster(struct subnet_record *d, struct work_record *work)
+void become_nonmaster(struct subnet_record *d, struct work_record *work,
+ int remove_type)
{
+ int new_server_type = work->ServerType;
+
DEBUG(2,("Becoming non-master for %s\n",work->work_group));
- work->ServerType &= ~SV_TYPE_MASTER_BROWSER;
- work->ServerType &= ~SV_TYPE_DOMAIN_MASTER;
- work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
+ /* can only remove master or domain types with this function */
+ remove_type &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
+
+ /* unbecome a master browser; unbecome a domain master, too :-( */
+ if (remove_type & SV_TYPE_MASTER_BROWSER)
+ remove_type |= SV_TYPE_DOMAIN_MASTER;
+ new_server_type &= ~remove_type;
+
+ if (!(new_server_type & (SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER)))
+ {
+ /* no longer a master browser of any sort */
+
+ work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
work->ElectionCriterion &= ~0x4;
- remove_name_entry(work->work_group,0x1b);
- remove_name_entry(work->work_group,0x1d);
- remove_name_entry(MSBROWSE ,0x01);
+ /* announce ourselves as no longer active as a master browser. */
+ announce_server(d, work, work->work_group, myname, 0, 0);
+ remove_name_entry(d,MSBROWSE ,0x01);
+ }
+
+ work->ServerType = new_server_type;
+
+ if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
+ remove_name_entry(d,work->work_group,0x1b);
+
+ if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
+ remove_name_entry(d,work->work_group,0x1d);
}
@@ -292,7 +314,7 @@ 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_domain(ip);
+ struct subnet_record *d = find_subnet(ip);
int version = CVAL(buf,0);
uint32 criterion = IVAL(buf,1);
int timeup = IVAL(buf,5)/1000;
@@ -335,7 +357,8 @@ void process_election(struct packet_struct *p,char *buf)
/* if we are the master then remove our masterly names */
if (AM_MASTER(work))
{
- become_nonmaster(d, work);
+ become_nonmaster(d, work,
+ SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
}
}
}
@@ -355,10 +378,6 @@ BOOL check_elections(void)
for (d = subnetlist; d; d = d->next)
{
struct work_record *work;
-
- /* we only want to run elections on our own interfaces */
- if (!d->my_interface) continue;
-
for (work = d->workgrouplist; work; work = work->next)
{
run_any_election |= work->RunningElection;