summaryrefslogtreecommitdiff
path: root/source3/nameannounce.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nameannounce.c')
-rw-r--r--source3/nameannounce.c190
1 files changed, 119 insertions, 71 deletions
diff --git a/source3/nameannounce.c b/source3/nameannounce.c
index 8f2005a73d..b46436168c 100644
--- a/source3/nameannounce.c
+++ b/source3/nameannounce.c
@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1995
+ 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
@@ -47,7 +47,7 @@ extern int workgroup_count;
extern struct in_addr wins_ip;
-
+extern pstring scope;
/****************************************************************************
send a announce request to the local net
@@ -119,12 +119,13 @@ void do_announce_request(char *info, char *to_name, int announce_type,
**************************************************************************/
void sync_server(enum state_type state, char *serv_name, char *work_name,
int name_type,
+ struct subnet_record *d,
struct in_addr ip)
{
/* with a domain master we can get the whole list (not local only list) */
BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
- add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
+ add_browser_entry(serv_name, name_type, work_name, 0, d, ip, local_only);
if (state == NAME_STATUS_DOM_SRV_CHK)
{
@@ -189,7 +190,7 @@ void do_announce_host(int command,
void remove_my_servers(void)
{
struct subnet_record *d;
- for (d = subnetlist; d; d = d->next)
+ for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
@@ -228,7 +229,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
if (!lp_wins_support() && *lp_wins_server())
{
/* look up the domain master with the WINS server */
- queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
+ queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
NAME_QUERY_ANNOUNCE_HOST,
work->work_group,0x1b,0,ttl*1000,
server_type,name,comment,
@@ -305,12 +306,10 @@ void announce_host(time_t t)
my_name = *myname ? myname : "NoName";
- for (d = subnetlist; d; d = d->next)
+ for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
{
struct work_record *work;
- if (ip_equal(d->bcast_ip, wins_ip)) continue;
-
for (work = d->workgrouplist; work; work = work->next)
{
uint32 stype = work->ServerType;
@@ -362,6 +361,19 @@ void announce_host(time_t t)
}
}
+/* Announce timer. Moved into global static so it can be reset
+ when a machine becomes a master browser. */
+static time_t announce_timer_last=0;
+
+/****************************************************************************
+ Reset the announce_timer so that a master browser announce will be done
+ immediately.
+ ****************************************************************************/
+
+void reset_announce_timer()
+{
+ announce_timer_last = 0;
+}
/****************************************************************************
announce myself as a master to all other domain master browsers.
@@ -373,16 +385,26 @@ void announce_host(time_t t)
void announce_master(time_t t)
{
struct subnet_record *d;
- static time_t last=0;
+ struct work_record *work;
BOOL am_master = False; /* are we a master of some sort? :-) */
- if (!last) last = t;
- if (t-last < CHECK_TIME_MST_ANNOUNCE * 60)
- return;
+ if (!announce_timer_last) announce_timer_last = t;
+ if (t-announce_timer_last < CHECK_TIME_MST_ANNOUNCE * 60)
+ {
+ DEBUG(10,("announce_master: t (%d) - last(%d) < %d\n",
+ t, announce_timer_last, CHECK_TIME_MST_ANNOUNCE * 60 ));
+ return;
+ }
+
+ if(wins_subnet == 0)
+ {
+ DEBUG(10,("announce_master: no wins subnet, ignoring.\n"));
+ return;
+ }
- last = t;
+ announce_timer_last = t;
- for (d = subnetlist; d; d = d->next)
+ for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
{
struct work_record *work;
for (work = d->workgrouplist; work; work = work->next)
@@ -398,69 +420,95 @@ void announce_master(time_t t)
if (!am_master) return; /* only proceed if we are a master browser */
- /* Note that we don't do this if we are domain master browser. */
+ /* Note that we don't do this if we are domain master browser
+ and that we *only* do this on the WINS subnet. */
+
+ /* Try and find our workgroup on the WINS subnet */
+ work = find_workgroupstruct(wins_subnet, lp_workgroup(), False);
- for (d = subnetlist; d; d = d->next)
+ if (work)
{
- /* Try and find our workgroup on this subnet */
- struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
+ char *name;
+ int type;
- if (work)
+ if (*lp_domain_controller())
{
- char *name;
- int type;
-
- if (*lp_domain_controller())
- {
- /* the domain controller option is used to manually specify
- the domain master browser to sync with
- */
-
- /* XXXX i'm not sure we should be using the domain controller
- option for this purpose.
- */
-
- name = lp_domain_controller();
- type = 0x20;
- }
- else
- {
- /* assume that the domain master browser we want to sync
- with is our own domain.
- */
- name = work->work_group;
- type = 0x1b;
- }
-
- /* check the existence of a dmb for this workgroup, and if
- one exists at the specified ip, sync with it and announce
- ourselves as a master browser to it
+ /* the domain controller option is used to manually specify
+ the domain master browser to sync with
*/
- if (!lp_wins_support() && *lp_wins_server() &&
- ip_equal(d->bcast_ip, wins_ip))
- {
- DEBUG(4, ("Local Announce: find %s<%02x> from WINS server %s\n",
- name, type, lp_wins_server()));
-
- queue_netbios_pkt_wins(d,ClientNMB,
- NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
- name, type, 0,0,0,
- work->work_group,NULL,
- False, False, ipzero, ipzero);
- }
- else
- {
- DEBUG(4, ("Local Announce: find %s<%02x> on %s\n",
- name, type, inet_ntoa(d->bcast_ip)));
-
- queue_netbios_packet(d,ClientNMB,
- NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
- name, type, 0,0,0,
- work->work_group,NULL,
- True, False, d->bcast_ip, d->bcast_ip);
- }
- }
+ /* XXXX i'm not sure we should be using the domain controller
+ option for this purpose.
+ */
+
+ name = lp_domain_controller();
+ type = 0x20;
+ }
+ else
+ {
+ /* assume that the domain master browser we want to sync
+ with is our own domain.
+ */
+ name = work->work_group;
+ type = 0x1b;
+ }
+
+ /* check the existence of a dmb for this workgroup, and if
+ one exists at the specified ip, sync with it and announce
+ ourselves as a master browser to it
+ */
+
+ if (!lp_wins_support() && *lp_wins_server() )
+ {
+ DEBUG(4, ("Local Announce: find %s<%02x> from WINS server %s\n",
+ name, type, lp_wins_server()));
+
+ queue_netbios_pkt_wins(ClientNMB,
+ NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
+ name, type, 0,0,0,
+ work->work_group,NULL,
+ False, False, ipzero, ipzero);
+ }
+ else if(lp_wins_support())
+ {
+ /* We are the WINS server - query ourselves for the dmb name. */
+
+ struct nmb_name netb_name;
+ struct subnet_record *d = 0;
+ struct name_record *nr = 0;
+
+ make_nmb_name(&netb_name, name, type, scope);
+
+ if ((nr = find_name_search(&d, &netb_name, FIND_WINS, ipzero)) == 0)
+ {
+ DEBUG(0, ("announce_master: unable to find domain master browser for workgroup %s \
+in our own WINS database.\n", work->work_group));
+ return;
+ }
+
+ /* Check that this isn't one of our addresses (ie. we are not domain master
+ ourselves) */
+ if(ismyip(nr->ip_flgs[0].ip))
+ {
+ DEBUG(4, ("announce_master: domain master ip found (%s) for workgroup %s \
+is one of our interfaces.\n", work->work_group, inet_ntoa(nr->ip_flgs[0].ip) ));
+ return;
+ }
+
+ /* Issue a NAME_STATUS_DOM_SRV_CHK immediately - short circuit the
+ NAME_QUERY_DOM_SRV_CHK which is done only if we are talking to a
+ remote WINS server. */
+
+ DEBUG(4, ("announce_master: doing name status for %s<%02x> to domain master ip %s \
+for workgroup %s\n", name, type, inet_ntoa(nr->ip_flgs[0].ip), work->work_group ));
+
+ queue_netbios_packet(wins_subnet, ClientNMB,
+ NMB_QUERY,NAME_STATUS_DOM_SRV_CHK,
+ name, type, 0,0,0,
+ work->work_group,NULL,
+ False, False, nr->ip_flgs[0].ip, nr->ip_flgs[0].ip);
+ }
+
}
}