summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamba Release Account <samba-bugs@samba.org>1997-04-09 01:19:25 +0000
committerSamba Release Account <samba-bugs@samba.org>1997-04-09 01:19:25 +0000
commita82476eee2c521e5eed092bc367da0a7cef23de1 (patch)
tree36f68ea5347de58b161e6231fa1f0252c246bffc
parentdeedac6523cdc435a1a26ad0c13d7a53042aafb6 (diff)
downloadsamba-a82476eee2c521e5eed092bc367da0a7cef23de1.tar.gz
samba-a82476eee2c521e5eed092bc367da0a7cef23de1.tar.xz
samba-a82476eee2c521e5eed092bc367da0a7cef23de1.zip
Large changes from jra@cygnus.com. Mainly browser updates.
access.c: Fixed crash if yp domain unavailable. includes.h: Moved ifdefs for minor platform. interface.c: Changed name of ipgrp to wins_ip to make it clearer. loadparm.c: Changed default of wins support to 'no'. nameannounce.c: Many changes to fix cross subnet browsing. namebrowse.c: Many changes to fix cross subnet browsing. namedbname.c: Many changes to fix cross subnet browsing. namedbresp.c: Many changes to fix cross subnet browsing. namedbsubnet.c: Many changes to fix cross subnet browsing. namedbwork.c: Many changes to fix cross subnet browsing. nameelect.c: Many changes to fix cross subnet browsing. namelogon.c: Many changes to fix cross subnet browsing. namepacket.c: Many changes to fix cross subnet browsing. nameresp.c: Many changes to fix cross subnet browsing. nameserv.c: Many changes to fix cross subnet browsing. nameserv.h: Many changes to fix cross subnet browsing. nameservreply.c: Many changes to fix cross subnet browsing. nameservresp.c: Many changes to fix cross subnet browsing. namework.c: Many changes to fix cross subnet browsing. nmbd.c: Change to search wins subnet. nmbsync.c: Change to check if we are any master before proceeding. proto.h: Added find_subnet_all() and check_work_servertype(). util.c: Moved 'done' settings on name resolution.
-rw-r--r--source/include/includes.h2
-rw-r--r--source/include/nameserv.h7
-rw-r--r--source/include/proto.h5
-rw-r--r--source/lib/access.c4
-rw-r--r--source/lib/interface.c4
-rw-r--r--source/lib/util.c6
-rw-r--r--source/nameannounce.c167
-rw-r--r--source/namebrowse.c66
-rw-r--r--source/namedbname.c50
-rw-r--r--source/namedbresp.c12
-rw-r--r--source/namedbsubnet.c76
-rw-r--r--source/namedbwork.c43
-rw-r--r--source/nameelect.c21
-rw-r--r--source/namelogon.c164
-rw-r--r--source/namepacket.c13
-rw-r--r--source/nameresp.c257
-rw-r--r--source/nameserv.c20
-rw-r--r--source/nameservreply.c36
-rw-r--r--source/nameservresp.c420
-rw-r--r--source/namework.c39
-rw-r--r--source/nmbd/nmbd.c2
-rw-r--r--source/nmbsync.c2
-rw-r--r--source/param/loadparm.c2
23 files changed, 790 insertions, 628 deletions
diff --git a/source/include/includes.h b/source/include/includes.h
index a8653d09788..249e4940a91 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -344,6 +344,7 @@ char *getwd(char *);
#endif
#ifdef SGI5
+#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/statvfs.h>
#include <string.h>
@@ -427,6 +428,7 @@ char *mktemp(char *); /* No standard include */
#define SIGNAL_CAST ( void (*) (int) )
#define STATFS3
#define USE_F_FSIZE
+#define USE_SETSID
#include <netinet/tcp.h>
#ifdef OSF1_ENH_SEC
#include <pwd.h>
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 027931f9e63..17ae085bc62 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -75,6 +75,8 @@
#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
#define AM_DOMMST(work) (work->ServerType & SV_TYPE_DOMAIN_MASTER)
#define AM_DOMMEM(work) (work->ServerType & SV_TYPE_DOMAIN_MEMBER)
+#define AM_ANY_MASTER(work) (check_work_servertype(work->work_group, \
+SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER))
/* microsoft browser NetBIOS name */
#define MSBROWSE "\001\002__MSBROWSE__\002"
@@ -124,7 +126,7 @@ enum state_type
NAME_QUERY_SRV_CHK,
NAME_QUERY_FIND_MST,
NAME_QUERY_MST_CHK,
- NAME_QUERY_DOMAIN,
+ NAME_QUERY_DOMAIN
};
/* a netbios name structure */
@@ -401,7 +403,8 @@ struct packet_struct
#define CHECK_TIME_MAX_HOST_ANNCE 12
/* announce as master to WINS server and any Primary Domain Controllers */
-#define CHECK_TIME_MST_ANNOUNCE 15
+/* ORIGINAL - changed for test by JRA #define CHECK_TIME_MST_ANNOUNCE 15 */
+#define CHECK_TIME_MST_ANNOUNCE 1
/* do all remote announcements this often */
#define REMOTE_ANNOUNCE_INTERVAL 180
diff --git a/source/include/proto.h b/source/include/proto.h
index bbfcad78f94..cfc05c1c6b4 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -386,11 +386,9 @@ void expire_servers(time_t t);
struct subnet_record *find_subnet(struct in_addr bcast_ip);
struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
+struct subnet_record *find_subnet_all(struct in_addr bcast_ip);
void add_subnet_interfaces(void);
void add_my_subnets(char *group);
-struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
- struct in_addr mask_ip,
- char *name, BOOL add, BOOL lmhosts);
void write_browse_list(time_t t);
/*The following definitions come from namedbwork.c */
@@ -401,6 +399,7 @@ struct work_record *remove_workgroup(struct subnet_record *d,
struct work_record *find_workgroupstruct(struct subnet_record *d,
fstring name, BOOL add);
void dump_workgroups(void);
+int check_work_servertype(const char *work_name, int type_mask);
/*The following definitions come from nameelect.c */
diff --git a/source/lib/access.c b/source/lib/access.c
index 31a48d09d3c..599cb5ca7e3 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -209,6 +209,10 @@ static int string_match(char *tok,char *s)
if (!mydomain) yp_get_default_domain(&mydomain);
+ if (!mydomain) {
+ DEBUG(0,("Unable to get default yp domain.\n"));
+ return NO;
+ }
if (!(hostname = strdup(s))) {
DEBUG(1,("out of memory for strdup!\n"));
return NO;
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 1c41293cf77..0e2a13e7b93 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -24,7 +24,7 @@
extern int DEBUGLEVEL;
struct in_addr ipzero;
-struct in_addr ipgrp;
+struct in_addr wins_ip;
static struct in_addr default_ip;
static struct in_addr default_bcast;
static struct in_addr default_nmask;
@@ -261,7 +261,7 @@ static void interpret_interfaces(char *s, struct interface **interfaces,
struct in_addr ip;
ipzero = *interpret_addr2("0.0.0.0");
- ipgrp = *interpret_addr2("255.255.255.255");
+ wins_ip = *interpret_addr2("255.255.255.255");
while (next_token(&ptr,token,NULL)) {
/* parse it into an IP address/netmasklength pair */
diff --git a/source/lib/util.c b/source/lib/util.c
index 643c2fb7a50..53b24173d51 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -3090,12 +3090,10 @@ char *client_name(void)
if (done)
return name_buf;
- done = True;
strcpy(name_buf,"UNKNOWN");
if (getpeername(Client, &sa, &length) < 0) {
DEBUG(0,("getpeername failed\n"));
- done = False;
return name_buf;
}
@@ -3105,7 +3103,6 @@ char *client_name(void)
AF_INET)) == 0) {
DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
- done = False;
} else {
StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
if (!matchname(name_buf, sockin->sin_addr)) {
@@ -3113,6 +3110,7 @@ char *client_name(void)
strcpy(name_buf,"UNKNOWN");
}
}
+ done = True;
return name_buf;
}
@@ -3129,7 +3127,6 @@ char *client_addr(void)
if (done)
return addr_buf;
- done = True;
strcpy(addr_buf,"0.0.0.0");
if (getpeername(Client, &sa, &length) < 0) {
@@ -3139,6 +3136,7 @@ char *client_addr(void)
strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
+ done = True;
return addr_buf;
}
diff --git a/source/nameannounce.c b/source/nameannounce.c
index 8dc0668f4ed..a1eae127a2a 100644
--- a/source/nameannounce.c
+++ b/source/nameannounce.c
@@ -45,7 +45,7 @@ extern struct subnet_record *subnetlist;
extern int updatecount;
extern int workgroup_count;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
@@ -216,7 +216,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
(SV_TYPE_SERVER_UNIX, for example)
*/
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
- BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
+ BOOL wins_iface = ip_equal(d->bcast_ip, wins_ip);
if (wins_iface && server_type != 0)
{
@@ -261,7 +261,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
do_announce_host(ANN_LocalMasterAnnouncement,
name , 0x00, d->myip,
work->work_group, 0x1e, d->bcast_ip,
- ttl*1000,
+ ttl,
name, server_type, comment);
DEBUG(3,("sending domain announce to %s for %s\n",
@@ -273,7 +273,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
do_announce_host(ANN_DomainAnnouncement,
name , 0x00, d->myip,
MSBROWSE, 0x01, d->bcast_ip,
- ttl*1000,
+ ttl,
work->work_group, server_type ? domain_type : 0,
name);
}
@@ -286,7 +286,7 @@ void announce_server(struct subnet_record *d, struct work_record *work,
do_announce_host(ANN_HostAnnouncement,
name , 0x00, d->myip,
work->work_group, 0x1d, d->bcast_ip,
- ttl*1000,
+ ttl,
name, server_type, comment);
}
}
@@ -309,24 +309,24 @@ void announce_host(time_t t)
{
struct work_record *work;
- if (ip_equal(d->bcast_ip, ipgrp)) continue;
-
+ if (ip_equal(d->bcast_ip, wins_ip)) continue;
+
for (work = d->workgrouplist; work; work = work->next)
{
uint32 stype = work->ServerType;
struct server_record *s;
BOOL announce = False;
- /* must work on the code that does announcements at up to
- 30 seconds later if a master browser sends us a request
- announce.
- */
+ /* must work on the code that does announcements at up to
+ 30 seconds later if a master browser sends us a request
+ announce.
+ */
if (work->needannounce) {
/* drop back to a max 3 minute announce - this is to prevent a
single lost packet from stuffing things up for too long */
work->announce_interval = MIN(work->announce_interval,
- CHECK_TIME_MIN_HOST_ANNCE*60);
+ CHECK_TIME_MIN_HOST_ANNCE*60);
work->lastannounce_time = t - (work->announce_interval+1);
}
@@ -339,7 +339,7 @@ void announce_host(time_t t)
work->announce_interval += 60;
work->lastannounce_time = t;
-
+
for (s = work->serverlist; s; s = s->next) {
if (strequal(myname, s->serv.name)) {
announce = True;
@@ -353,18 +353,18 @@ void announce_host(time_t t)
}
if (work->needannounce)
- {
+ {
work->needannounce = False;
break;
/* sorry: can't do too many announces. do some more later */
- }
+ }
}
- }
+ }
}
/****************************************************************************
- announce myself as a master to all other primary domain conrollers.
+ announce myself as a master to all other domain master browsers.
this actually gets done in search_and_sync_workgroups() via the
NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
@@ -393,86 +393,77 @@ void announce_master(time_t t)
}
}
}
-
+
+ DEBUG(4,( "announce_master: am_master = %d for workgroup %s\n", am_master, lp_workgroup()));
+
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. */
+
for (d = subnetlist; d; d = d->next)
{
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- struct server_record *s;
- for (s = work->serverlist; s; s = s->next)
- {
- if (strequal(s->serv.name, myname)) continue;
-
- /* all DOMs (which should also be master browsers) */
- if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
- {
- /* check the existence of a pdc 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_domain_controller() ||
- !strequal(lp_domain_controller(), s->serv.name))
- {
- if (!lp_wins_support() && *lp_wins_server())
- {
- queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
- NAME_QUERY_DOM_SRV_CHK,
- work->work_group,0x1b,0,0,0,NULL,NULL,
- False, False, ipzero, ipzero);
- }
- else
- {
- struct subnet_record *d2;
- for (d2 = subnetlist; d2; d2 = d2->next)
- {
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- NAME_QUERY_DOM_SRV_CHK,
- work->work_group,0x1b,0,0,0,NULL,NULL,
- True, False, d2->bcast_ip, d2->bcast_ip);
- }
- }
- }
- }
- }
-
- /* now do primary domain controller - the one that's not
- necessarily in our browse lists, although it ought to be
- this pdc is the one that we get TOLD about through smb.conf.
- basically, if it's on a subnet that we know about, it may end
- up in our browse lists (which is why it's explicitly excluded
- in the code above) */
-
- if (*lp_domain_controller())
- {
- struct in_addr ip;
- BOOL bcast = False;
-
- ip = *interpret_addr2(lp_domain_controller());
-
- if (zero_ip(ip)) {
- ip = d->bcast_ip;
- bcast = True;
- }
-
- DEBUG(2, ("Searching for DOM %s at %s\n",
- lp_domain_controller(), inet_ntoa(ip)));
-
- /* check the existence of a pdc for this workgroup, and if
- one exists at the specified ip, sync with it and announce
- ourselves as a master browser to it */
- queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
- work->work_group,0x1b,0,0,0,NULL,NULL,
- bcast, False, ip, ip);
+ /* Try and find our workgroup on this subnet */
+ struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
+
+ if (work)
+ {
+ 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
+ */
+
+ 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);
}
}
}
}
-
-
/****************************************************************************
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
diff --git a/source/namebrowse.c b/source/namebrowse.c
index 3bc4f9f82aa..b87ea9fec34 100644
--- a/source/namebrowse.c
+++ b/source/namebrowse.c
@@ -32,6 +32,8 @@ extern int ClientNMB;
extern int DEBUGLEVEL;
+extern struct in_addr wins_ip;
+
/* this is our browse master/backup cache database */
static struct browse_cache_record *browserlist = NULL;
@@ -89,7 +91,6 @@ void expire_browse_cache(time_t t)
}
}
-
/****************************************************************************
add a browser entry
****************************************************************************/
@@ -166,21 +167,48 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
struct subnet_record *d;
struct work_record *work;
- if (!(d = find_subnet(b->ip))) return;
+ /* Look for the workgroup first on the local subnet. If this
+ fails try WINS - we may need to sync with the domain master,
+ or we may be the domain master and need to sync with subnet
+ masters.
+ */
+
+ if (!(d = find_subnet_all(b->ip))) {
+ DEBUG(0, ("start_sync_browse_entry: failed to get a \
+subnet for a browse cache entry workgroup %s, server %s\n",
+ b->group, b->name));
+ return;
+ }
- if (!(work = find_workgroupstruct(d, b->group, False))) return;
+ if (!(work = find_workgroupstruct(d, b->group, False))) {
+ DEBUG(0, ("start_sync_browse_entry: failed to get a \
+workgroup for a browse cache entry workgroup %s, server %s\n",
+ b->group, b->name));
+ return;
+ }
- /* only sync if we are the master */
- if (AM_MASTER(work)) {
+ /* only sync if we are a subnet master or domain master - but
+ we sync if we are a master for this workgroup on *any*
+ of our interfaces. */
+ if (AM_MASTER(work) || AM_DOMMST(work) || AM_ANY_MASTER(work)) {
- /* first check whether the group we intend to sync with exists. if it
- doesn't, the server must have died. o dear. */
+ DEBUG(4, ("start_sync_browse_entry: Initiating %s sync with %s<0x20>, \
+workgroup %s\n",
+ b->local ? "local" : "remote", b->name, b->group));
- /* see response_netbios_packet() or expire_netbios_response_entries() */
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
- b->group,0x20,0,0,0,NULL,NULL,
- False,False,b->ip,b->ip);
+ /* first check whether the server we intend to sync with exists. if it
+ doesn't, the server must have died. o dear. */
+
+ /* see response_netbios_packet() or expire_netbios_response_entries() */
+ /* We cheat here by using the my_comment field of the response_record
+ struct as the workgroup name we are going to do the sync for.
+ This is because the reply packet doesn't include the workgroup, but
+ we need it when the reply comes back.
+ */
+ queue_netbios_packet(d,ClientNMB,NMB_QUERY,
+ b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
+ b->name,0x20,0,0,0,NULL,b->group,
+ False,False,b->ip,b->ip);
}
b->synced = True;
@@ -195,10 +223,14 @@ void do_browser_lists(time_t t)
struct browse_cache_record *b;
static time_t last = 0;
- if (t-last < 20) return; /* don't do too many of these at once! */
+ if (t-last < 20)
+ {
+ DEBUG(9,("do_browser_lists: returning due to t(%d) - last(%d) < 20\n",
+ t, last));
+ return; /* don't do too many of these at once! */
/* XXXX equally this period should not be too long
the server may die in the intervening gap */
-
+ }
last = t;
/* pick any entry in the list, preferably one whose time is up */
@@ -210,9 +242,15 @@ void do_browser_lists(time_t t)
if (b && !b->synced)
{
/* sync with the selected entry then remove some dead entries */
+ DEBUG(4,("do_browser_lists: Initiating sync with %s, workgroup %s\n",
+ b->name, b->group));
start_sync_browse_entry(b);
expire_browse_cache(t - 60);
}
+ else
+ {
+ DEBUG(9, ("do_browser_lists: no entries to sync.\n"));
+ }
}
diff --git a/source/namedbname.c b/source/namedbname.c
index 2e8c8d589ae..d27bcf81586 100644
--- a/source/namedbname.c
+++ b/source/namedbname.c
@@ -35,7 +35,7 @@ extern int DEBUGLEVEL;
extern pstring scope;
extern struct in_addr ipzero;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
extern struct subnet_record *subnetlist;
@@ -153,10 +153,11 @@ struct name_record *find_name(struct name_record *n,
{
continue;
}
-
+ DEBUG(9,("find_name: found name %s\n", name->name));
return ret;
}
}
+ DEBUG(9,("find_name: name %s NOT FOUND\n", name->name));
return NULL;
}
@@ -172,27 +173,27 @@ struct name_record *find_name_search(struct subnet_record **d,
struct nmb_name *name,
int search, struct in_addr ip)
{
- if (d == NULL) return NULL; /* bad error! */
+ if (d == NULL) return NULL; /* bad error! */
- if (search & FIND_LOCAL) {
- if (*d != NULL) {
- struct name_record *n = find_name((*d)->namelist, name, search);
- DEBUG(4,("find_name on local: %s %s search %x\n",
- namestr(name),inet_ntoa(ip), search));
- if (n) return n;
- }
+ if (search & FIND_LOCAL) {
+ if (*d != NULL) {
+ struct name_record *n = find_name((*d)->namelist, name, search);
+ DEBUG(4,("find_name on local: %s %s search %x\n",
+ namestr(name),inet_ntoa(ip), search));
+ if (n) return n;
}
+ }
- if (!(search & FIND_WINS)) return NULL;
+ if (!(search & FIND_WINS)) return NULL;
- /* find WINS subnet record. */
- *d = find_subnet(ipgrp);
-
- if (*d == NULL) return NULL;
-
- DEBUG(4,("find_name on WINS: %s %s search %x\n",
- namestr(name),inet_ntoa(ip), search));
- return find_name((*d)->namelist, name, search);
+ /* find WINS subnet record. */
+ *d = find_subnet(wins_ip);
+
+ if (*d == NULL) return NULL;
+
+ DEBUG(4,("find_name on WINS: %s %s search %x\n",
+ namestr(name),inet_ntoa(ip), search));
+ return find_name((*d)->namelist, name, search);
}
@@ -245,7 +246,7 @@ void dump_names(void)
}
DEBUG(4,("\n"));
- if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
+ if (f && ip_equal(d->bcast_ip, wins_ip) && n->source == REGISTER)
{
/* XXXX i have little imagination as to how to output nb_flags as
anything other than as a hexadecimal number :-) */
@@ -281,7 +282,7 @@ void dump_names(void)
****************************************************************************/
void load_netbios_names(void)
{
- struct subnet_record *d = find_subnet(ipgrp);
+ struct subnet_record *d = find_subnet(wins_ip);
fstring fname;
FILE *f;
@@ -466,8 +467,9 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
if (!n2) add_name(d,n);
- DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
- namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
+ DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x to interface %s\n",
+ namestr(&n->name),inet_ntoa(ip),ttl,nb_flags,
+ ip_equal(d->bcast_ip, wins_ip) ? "WINS" : inet_ntoa(d->bcast_ip)));
return(n);
}
@@ -520,7 +522,7 @@ struct name_record *dns_name_search(struct nmb_name *question, int Time)
char *r;
BOOL dns_type = (name_type == 0x20 || name_type == 0);
struct in_addr dns_ip;
- struct subnet_record *d = find_subnet(ipgrp);
+ struct subnet_record *d = find_subnet(wins_ip);
if (d == NULL) return NULL;
diff --git a/source/namedbresp.c b/source/namedbresp.c
index d89bfe8ae84..6755de6534b 100644
--- a/source/namedbresp.c
+++ b/source/namedbresp.c
@@ -34,7 +34,6 @@ extern int DEBUGLEVEL;
extern pstring scope;
extern pstring myname;
extern struct in_addr ipzero;
-extern struct in_addr ipgrp;
int num_response_packets = 0;
@@ -117,9 +116,14 @@ struct response_record *make_response_queue_record(enum state_type state,
n->recurse = recurse;
n->send_ip = send_ip;
n->reply_to_ip = reply_to_ip;
- StrnCpy(my_name , n->my_name , sizeof(n->my_name )-1);
- StrnCpy(my_comment, n->my_comment, sizeof(n->my_comment)-1);
-
+ if(my_name)
+ StrnCpy(n->my_name, my_name, sizeof(n->my_name)-1);
+ else
+ *n->my_name = 0;
+ if(my_comment)
+ StrnCpy(n->my_comment, my_comment, sizeof(n->my_comment)-1);
+ else
+ *n->my_comment = 0;
n->repeat_interval = 1; /* XXXX should be in ms */
n->repeat_count = 3; /* 3 retries */
n->repeat_time = time(NULL) + n->repeat_interval; /* initial retry time */
diff --git a/source/namedbsubnet.c b/source/namedbsubnet.c
index 367179b6c61..144729e1e17 100644
--- a/source/namedbsubnet.c
+++ b/source/namedbsubnet.c
@@ -36,7 +36,7 @@ extern int ClientDGRAM;
extern int DEBUGLEVEL;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
extern struct in_addr ipzero;
extern pstring myname;
@@ -52,6 +52,11 @@ struct subnet_record *subnetlist = NULL;
extern uint16 nb_type; /* samba's NetBIOS name type */
+/* Forward references. */
+static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
+ struct in_addr mask_ip,
+ char *name, BOOL add, BOOL lmhosts);
+
/****************************************************************************
add a domain into the list
**************************************************************************/
@@ -81,31 +86,30 @@ static void add_subnet(struct subnet_record *d)
struct subnet_record *find_subnet(struct in_addr bcast_ip)
{
struct subnet_record *d;
- struct in_addr wins_ip = ipgrp;
/* search through subnet list for broadcast/netmask that matches
the source ip address. a subnet 255.255.255.255 represents the
WINS list. */
- for (d = subnetlist; d; d = d->next)
+ for (d = subnetlist; d; d = d->next)
{
- if (ip_equal(bcast_ip, wins_ip))
+ if (ip_equal(bcast_ip, wins_ip))
+ {
+ if (ip_equal(bcast_ip, d->bcast_ip))
{
- if (ip_equal(bcast_ip, d->bcast_ip))
- {
- return d;
- }
+ return d;
+ }
}
- else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
+ else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
+ {
+ if (!ip_equal(d->bcast_ip, wins_ip))
{
- if (!ip_equal(d->bcast_ip, wins_ip))
- {
- return d;
- }
+ return d;
}
+ }
}
- return (NULL);
+ return (NULL);
}
@@ -122,9 +126,19 @@ struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
return find_subnet(*iface_bcast(ip));
}
/* find the subnet under the pseudo-ip of 255.255.255.255 */
- return find_subnet(ipgrp);
+ return find_subnet(wins_ip);
}
+/****************************************************************************
+ find a subnet in the subnetlist - if the subnet is not found
+ then return the WINS subnet.
+ **************************************************************************/
+struct subnet_record *find_subnet_all(struct in_addr bcast_ip)
+{
+ struct subnet_record *d = find_subnet(bcast_ip);
+ if(!d)
+ return find_subnet( wins_ip);
+}
/****************************************************************************
create a domain entry
@@ -157,24 +171,24 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
****************************************************************************/
void add_subnet_interfaces(void)
{
- struct interface *i;
+ struct interface *i;
- /* loop on all local interfaces */
- for (i = local_interfaces; i; i = i->next)
+ /* loop on all local interfaces */
+ for (i = local_interfaces; i; i = i->next)
+ {
+ /* add the interface into our subnet database */
+ if (!find_subnet(i->bcast))
{
- /* add the interface into our subnet database */
- if (!find_subnet(i->bcast))
- {
- make_subnet(i->bcast,i->nmask);
- }
+ make_subnet(i->bcast,i->nmask);
}
+ }
- /* add the pseudo-ip interface for WINS: 255.255.255.255 */
- if (lp_wins_support() || (*lp_wins_server()))
+ /* add the pseudo-ip interface for WINS: 255.255.255.255 */
+ if (lp_wins_support() || (*lp_wins_server()))
{
- struct in_addr wins_bcast = ipgrp;
- struct in_addr wins_nmask = ipzero;
- make_subnet(wins_bcast, wins_nmask);
+ struct in_addr wins_bcast = wins_ip;
+ struct in_addr wins_nmask = ipzero;
+ make_subnet(wins_bcast, wins_nmask);
}
}
@@ -205,7 +219,7 @@ void add_my_subnets(char *group)
add a domain entry. creates a workgroup, if necessary, and adds the domain
to the named a workgroup.
****************************************************************************/
-struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
+static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
struct in_addr mask_ip,
char *name, BOOL add, BOOL lmhosts)
{
@@ -215,7 +229,7 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
in the DEBUG comment. i assume that the DEBUG comment below actually
intends to refer to bcast_ip? i don't know.
- struct in_addr ip = ipgrp;
+ struct in_addr ip = wins_ip;
*/
@@ -223,6 +237,8 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
bcast_ip = *iface_bcast(bcast_ip);
/* add the domain into our domain database */
+ /* Note that we never add into the WINS subnet as add_subnet_entry
+ is only called to add our local interfaces. */
if ((d = find_subnet(bcast_ip)) ||
(d = make_subnet(bcast_ip, mask_ip)))
{
diff --git a/source/namedbwork.c b/source/namedbwork.c
index 0cfc47c41a8..80a670fea84 100644
--- a/source/namedbwork.c
+++ b/source/namedbwork.c
@@ -38,7 +38,7 @@ extern int DEBUGLEVEL;
/* this is our domain/workgroup/server database */
extern struct subnet_record *subnetlist;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
int workgroup_count = 0; /* unique index key: one for each workgroup */
@@ -201,7 +201,7 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
if ((work = make_workgroup(name)))
{
- if (!ip_equal(d->bcast_ip, ipgrp) &&
+ if (!ip_equal(d->bcast_ip, wins_ip) &&
lp_preferred_master() &&
strequal(lp_workgroup(), name))
{
@@ -248,3 +248,42 @@ void dump_workgroups(void)
}
}
}
+
+/****************************************************************************
+ check to see if a ServerType bit is set in any workgroup on any interface
+ except WINS. Used to determine if a nmbd is a master browser or domain
+ master browser in a particular workgroup on any subnet.
+ **************************************************************************/
+int check_work_servertype(const char *work_name, int type_mask)
+{
+ struct subnet_record *d;
+
+ for (d = subnetlist; d; d = d->next)
+ {
+ if(ip_equal(d->bcast_ip, wins_ip))
+ {
+ /* WINS ip */
+ DEBUG(10,("check_work_servertype: ignoring WINS subnet\n"));
+ continue;
+ }
+ if (d->workgrouplist)
+ {
+ struct work_record *work;
+
+ for (work = d->workgrouplist; work; work = work->next)
+ {
+ if(strequal(work->work_group, (char *)work_name) &&
+ (type_mask & work->ServerType) != 0)
+ {
+ DEBUG(10, ("check_work_servertype: Workgroup %s has \
+ServerType %x - match for type_mask %x\n", work_name, work->ServerType,
+ type_mask));
+ return 1;
+ }
+ }
+ }
+ }
+ DEBUG(10, ("check_work_servertype: Workgroup %s has no match for \
+type mask %x\n", work_name, type_mask));
+ return 0;
+}
diff --git a/source/nameelect.c b/source/nameelect.c
index c33206083ec..a11d0fb7867 100644
--- a/source/nameelect.c
+++ b/source/nameelect.c
@@ -41,7 +41,7 @@ extern pstring scope;
extern pstring myname;
extern struct in_addr ipzero;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
/* here are my election parameters */
@@ -71,6 +71,10 @@ void check_master_browser(time_t t)
{
struct work_record *work;
+ /* don't do election stuff on the WINS subnet */
+ if (ip_equal(d->bcast_ip,wins_ip))
+ continue;
+
for (work = d->workgrouplist; work; work = work->next)
{
if (!AM_MASTER(work))
@@ -116,7 +120,7 @@ void browser_gone(char *work_name, struct in_addr ip)
if (!work || !d) return;
/* don't do election stuff on the WINS subnet */
- if (ip_equal(d->bcast_ip,ipgrp))
+ if (ip_equal(d->bcast_ip,wins_ip))
return;
if (strequal(work->work_group, lp_workgroup()))
@@ -350,6 +354,9 @@ void become_local_master(struct subnet_record *d, struct work_record *work)
/* 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,0,lp_serverstring(),True);
if (work->serverlist == NULL) /* no servers! */
@@ -638,6 +645,14 @@ void run_elections(time_t t)
for (d = subnetlist; d; d = d->next)
{
struct work_record *work;
+
+ if(ip_equal(d->bcast_ip, wins_ip))
+ {
+ /* WINS ip */
+ DEBUG(10,("run_elections: ignoring WINS subnet\n"));
+ continue;
+ }
+
for (work = d->workgrouplist; work; work = work->next)
{
if (work->RunningElection)
@@ -710,7 +725,7 @@ void process_election(struct packet_struct *p,char *buf)
if (!d) return;
- if (ip_equal(d->bcast_ip,ipgrp)) {
+ if (ip_equal(d->bcast_ip,wins_ip)) {
DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
name, inet_ntoa(p->ip)));
return;
diff --git a/source/namelogon.c b/source/namelogon.c
index 3fab49cedd6..1ea09ee2bb6 100644
--- a/source/namelogon.c
+++ b/source/namelogon.c
@@ -47,104 +47,114 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
{
struct dgram_packet *dgram = &p->packet.dgram;
struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip);
+ struct subnet_record *d = find_subnet_all(ip);
char *logname,*q;
fstring reply_name;
BOOL add_slashes = False;
pstring outbuf;
int code,reply_code;
struct work_record *work;
- char unknown_byte = 0;
- uint16 request_count = 0;
- uint16 token = 0;
+ char unknown_byte = 0;
+ uint16 request_count = 0;
+ uint16 token = 0;
- if (!d) return;
-
- if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) return;
+ if (!lp_domain_logons())
+ {
+ DEBUG(3,("No domain logons\n"));
+ return;
+ }
- if (!lp_domain_logons())
- {
- DEBUG(3,("No domain logons\n"));
- return;
- }
+ if (!d)
+ {
+ DEBUG(0,("process_logon_packet: Cannot find subnet for logon request from %s\n",
+ inet_ntoa(p->ip) ));
+ return;
+ }
- code = SVAL(buf,0);
- switch (code)
- {
- case 0:
+ if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
{
- char *machine = buf+2;
- char *user = skip_string(machine,1);
- char *tmp;
- logname = skip_string(user,1);
- tmp = skip_string(logname,1);
- unknown_byte = CVAL(tmp,0);
- request_count = SVAL(tmp,1);
- token = SVAL(tmp,3);
-
- reply_code = 0x6;
- strcpy(reply_name,myname);
- strupper(reply_name);
- add_slashes = True;
- DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
- machine,inet_ntoa(p->ip),user,token));
- break;
- }
- case 7:
+ DEBUG(0,("process_logon_packet: Cannot find WORKGROUP %s for logon request fomr %s\n",
+ dgram->dest_name.name, inet_ntoa(p->ip) ));
+ return;
+ }
+
+ code = SVAL(buf,0);
+ switch (code)
{
- char *machine = buf+2;
- logname = skip_string(machine,1);
- token = SVAL(skip_string(logname,1),0);
-
- strcpy(reply_name,lp_domain_controller());
- if (!*reply_name)
- {
- /* oo! no domain controller. must be us, then */
+ case 0:
+ {
+ char *machine = buf+2;
+ char *user = skip_string(machine,1);
+ char *tmp;
+ logname = skip_string(user,1);
+ tmp = skip_string(logname,1);
+ unknown_byte = CVAL(tmp,0);
+ request_count = SVAL(tmp,1);
+ token = SVAL(tmp,3);
+
+ reply_code = 0x6;
strcpy(reply_name,myname);
- reply_code = 0xC;
+ strupper(reply_name);
+ add_slashes = True;
+ DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
+ machine,inet_ntoa(p->ip),user,token));
+ break;
+ }
+ case 7:
+ {
+ char *machine = buf+2;
+ logname = skip_string(machine,1);
+ token = SVAL(skip_string(logname,1),0);
+
+ strcpy(reply_name,lp_domain_controller());
+ if (!*reply_name)
+ {
+ /* oo! no domain controller. must be us, then */
+ strcpy(reply_name,myname);
+ reply_code = 0xC;
+ }
+ else
+ {
+ /* refer logon request to the domain controller */
+ reply_code = 0x7;
+ }
+
+ strupper(reply_name);
+ DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
+ machine,inet_ntoa(p->ip), reply_name, reply_code,token));
+ break;
+ }
+ default:
+ {
+ DEBUG(3,("Unknown domain request %d\n",code));
+ return;
}
- else
- {
- /* refer logon request to the domain controller */
- reply_code = 0x7;
}
-
- strupper(reply_name);
- DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
- machine,inet_ntoa(p->ip), reply_name, reply_code,token));
- break;
- }
- default:
- {
- DEBUG(3,("Unknown domain request %d\n",code));
- return;
- }
- }
bzero(outbuf,sizeof(outbuf));
q = outbuf;
SSVAL(q,0,reply_code);
q += 2;
-
- if (token == 0xffff || /* LM 2.0 or later */
- token == 0xfffe) /* WfWg networking */
+
+ if (token == 0xffff || /* LM 2.0 or later */
+ token == 0xfffe) /* WfWg networking */
+ {
+ if (add_slashes)
{
- if (add_slashes)
- {
- strcpy(q,"\\\\");
- q += 2;
- }
- strcpy(q, reply_name);
- strupper(q);
- q = skip_string(q,1);
-
- if (token == 0xffff) /* LM 2.0 or later */
- {
- SSVAL(q,0,token);
- q += 2;
- }
+ strcpy(q,"\\\\");
+ q += 2;
}
-
+ strcpy(q, reply_name);
+ strupper(q);
+ q = skip_string(q,1);
+
+ if (token == 0xffff) /* LM 2.0 or later */
+ {
+ SSVAL(q,0,token);
+ q += 2;
+ }
+ }
+
SSVAL(q,0,0xFFFF);
q += 2;
diff --git a/source/namepacket.c b/source/namepacket.c
index 043e2c02f0f..09ee5dd79e2 100644
--- a/source/namepacket.c
+++ b/source/namepacket.c
@@ -36,7 +36,7 @@ extern int num_response_packets;
BOOL CanRecurse = True;
extern pstring scope;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
static uint16 name_trn_id=0;
@@ -91,9 +91,9 @@ static void update_name_trn_id(void)
initiate a netbios packet
****************************************************************************/
void initiate_netbios_packet(uint16 *id,
- int fd,int quest_type,char *name,int name_type,
- int nb_flags,BOOL bcast,BOOL recurse,
- struct in_addr to_ip)
+ int fd,int quest_type,char *name,int name_type,
+ int nb_flags,BOOL bcast,BOOL recurse,
+ struct in_addr to_ip)
{
struct packet_struct p;
struct nmb_packet *nmb = &p.packet.nmb;
@@ -323,8 +323,10 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *n)
struct subnet_record *d;
struct name_record *n1;
+ /* We explicitly don't search WINS here - this will be done
+ in find_name_search is it was a packet from a non-local subnet. */
d = find_subnet(p->ip);
-
+
n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
return (n1 != NULL);
@@ -565,7 +567,6 @@ BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,ch
{
struct packet_struct p;
struct dgram_packet *dgram = &p.packet.dgram;
- struct in_addr wins_ip = ipgrp;
char *ptr,*p2;
char tmp[4];
diff --git a/source/nameresp.c b/source/nameresp.c
index b920742c765..fab16038ce0 100644
--- a/source/nameresp.c
+++ b/source/nameresp.c
@@ -33,7 +33,7 @@ extern int DEBUGLEVEL;
extern pstring scope;
extern struct in_addr ipzero;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
/***************************************************************************
@@ -51,146 +51,146 @@ static void dead_netbios_entry(struct subnet_record *d,
{
case NAME_QUERY_CONFIRM:
{
- if (!lp_wins_support()) return; /* only if we're a WINS server */
-
- if (n->num_msgs == 0)
+ if (!lp_wins_support()) return; /* only if we're a WINS server */
+
+ if (n->num_msgs == 0)
{
- /* oops. name query had no response. check that the name is
- unique and then remove it from our WINS database */
-
- /* IMPORTANT: see query_refresh_names() */
-
- if ((!NAME_GROUP(n->nb_flags)))
- {
- struct subnet_record *d1 = find_subnet(ipgrp);
- if (d1)
- {
- /* remove the name that had been registered with us,
- and we're now getting no response when challenging.
- see rfc1001.txt 15.5.2
- */
- remove_netbios_name(d1, n->name.name, n->name.name_type,
- REGISTER, n->send_ip);
- }
- }
+ /* oops. name query had no response. check that the name is
+ unique and then remove it from our WINS database */
+
+ /* IMPORTANT: see query_refresh_names() */
+
+ if ((!NAME_GROUP(n->nb_flags)))
+ {
+ struct subnet_record *d1 = find_subnet(wins_ip);
+ if (d1)
+ {
+ /* remove the name that had been registered with us,
+ and we're now getting no response when challenging.
+ see rfc1001.txt 15.5.2
+ */
+ remove_netbios_name(d1, n->name.name, n->name.name_type,
+ REGISTER, n->send_ip);
}
- break;
+ }
+ }
+ break;
}
-
- case NAME_QUERY_MST_CHK:
+
+ case NAME_QUERY_MST_CHK:
+ {
+ /* if no response received, the master browser must have gone
+ down on that subnet, without telling anyone. */
+
+ /* IMPORTANT: see response_netbios_packet() */
+
+ if (n->num_msgs == 0)
+ browser_gone(n->name.name, n->send_ip);
+ break;
+ }
+
+ case NAME_RELEASE:
+ {
+ /* if no response received, it must be OK for us to release the
+ name. nobody objected (including a potentially dead or deaf
+ WINS server) */
+
+ /* IMPORTANT: see response_name_release() */
+
+ if (ismyip(n->send_ip))
{
- /* if no response received, the master browser must have gone
- down on that subnet, without telling anyone. */
-
- /* IMPORTANT: see response_netbios_packet() */
-
- if (n->num_msgs == 0)
- browser_gone(n->name.name, n->send_ip);
- break;
+ name_unregister_work(d,n->name.name,n->name.name_type);
}
-
- case NAME_RELEASE:
+ if (!n->bcast && n->num_msgs == 0)
{
- /* if no response received, it must be OK for us to release the
- name. nobody objected (including a potentially dead or deaf
- WINS server) */
-
- /* IMPORTANT: see response_name_release() */
-
- if (ismyip(n->send_ip))
- {
- name_unregister_work(d,n->name.name,n->name.name_type);
- }
- if (!n->bcast && n->num_msgs == 0)
- {
- DEBUG(0,("WINS server did not respond to name release!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
- break;
+ DEBUG(0,("WINS server did not respond to name release!\n"));
+ /* XXXX whoops. we have problems. must deal with this */
}
-
- case NAME_REGISTER_CHALLENGE:
- {
- /* name challenge: no reply. we can reply to the person that
- wanted the unique name and tell them that they can have it
- */
-
- add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
- n->nb_flags, GET_TTL(0),
- n->reply_to_ip, False, n->reply_to_ip);
-
- if (!n->bcast && n->num_msgs == 0)
- {
- DEBUG(1,("WINS server did not respond to name registration!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
break;
+ }
+
+ case NAME_REGISTER_CHALLENGE:
+ {
+ /* name challenge: no reply. we can reply to the person that
+ wanted the unique name and tell them that they can have it
+ */
+
+ add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
+ n->nb_flags, GET_TTL(0),
+ n->reply_to_ip, False, n->reply_to_ip);
+
+ if (!n->bcast && n->num_msgs == 0)
+ {
+ DEBUG(1,("WINS server did not respond to name registration!\n"));
+ /* XXXX whoops. we have problems. must deal with this */
}
-
- case NAME_REGISTER:
+ break;
+ }
+
+ case NAME_REGISTER:
+ {
+ /* if no response received, and we are using a broadcast registration
+ method, it must be OK for us to register the name: nobody objected
+ on that subnet. if we are using a WINS server, then the WINS
+ server must be dead or deaf.
+ */
+ if (n->num_msgs == 0)
{
- /* if no response received, and we are using a broadcast registration
- method, it must be OK for us to register the name: nobody objected
- on that subnet. if we are using a WINS server, then the WINS
- server must be dead or deaf.
- */
- if (n->num_msgs == 0)
- {
- if (n->bcast)
+ if (n->bcast)
{
- /* broadcast method: implicit acceptance of the name registration
- by not receiving any objections. */
-
- /* IMPORTANT: see response_name_reg() */
-
- name_register_work(d,n->name.name,n->name.name_type,
- n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+ /* broadcast method: implicit acceptance of the name registration
+ by not receiving any objections. */
+
+ /* IMPORTANT: see response_name_reg() */
+
+ name_register_work(d,n->name.name,n->name.name_type,
+ n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+ }
+ else
+ {
+ /* received no response. rfc1001.txt states that after retrying,
+ we should assume the WINS server is dead, and fall back to
+ broadcasting (see bits about M nodes: can't find any right
+ now) */
+
+ DEBUG(1,("WINS server did not respond to name registration!\n"));
+ /* XXXX whoops. we have problems. must deal with this */
}
- else
- {
- /* received no response. rfc1001.txt states that after retrying,
- we should assume the WINS server is dead, and fall back to
- broadcasting (see bits about M nodes: can't find any right
- now) */
-
- DEBUG(1,("WINS server did not respond to name registration!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
- }
- break;
}
-
- case NAME_QUERY_DOMAIN:
- {
- /* if no response received, there is no domain controller on
+ break;
+ }
+
+ case NAME_QUERY_DOMAIN:
+ {
+ /* if no response received, there is no domain controller on
this local subnet. it's ok for us to register
- */
-
- if (!n->bcast)
- {
- DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
- /* XXXX whoops. someone's using this to unicast a packet. this state
- should only be used for broadcast checks
- */
- break;
- }
- if (n->num_msgs == 0)
- {
- struct work_record *work = find_workgroupstruct(d,n->name.name,False);
- if (work && d)
- {
- become_domain_master(d,work);
- }
- }
+ */
+
+ if (!n->bcast)
+ {
+ DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
+ /* XXXX whoops. someone's using this to unicast a packet. this state
+ should only be used for broadcast checks
+ */
break;
}
-
- default:
+ if (n->num_msgs == 0)
{
- /* nothing to do but delete the dead expected-response structure */
- /* this is normal. */
- break;
+ struct work_record *work = find_workgroupstruct(d,n->name.name,False);
+ if (work && d)
+ {
+ become_domain_master(d,work);
+ }
}
+ break;
+ }
+
+ default:
+ {
+ /* nothing to do but delete the dead expected-response structure */
+ /* this is normal. */
+ break;
+ }
}
}
@@ -300,10 +300,9 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
int fd,int quest_type,enum state_type state,char *name,
int name_type,int nb_flags, time_t ttl,
int server_type, char *my_name, char *my_comment,
- BOOL bcast,BOOL recurse,
+ BOOL bcast,BOOL recurse,
struct in_addr send_ip, struct in_addr reply_to_ip)
{
- struct in_addr wins_ip = ipgrp;
struct response_record *n;
uint16 id = 0xffff;
@@ -311,7 +310,7 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
if (ip_equal(wins_ip, send_ip)) return NULL;
initiate_netbios_packet(&id, fd, quest_type, name, name_type,
- nb_flags, bcast, recurse, send_ip);
+ nb_flags, bcast, recurse, send_ip);
if (id == 0xffff) {
DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
@@ -319,9 +318,9 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
}
if ((n = make_response_queue_record(state,id,fd,
- quest_type,name,name_type,nb_flags,ttl,
- server_type,my_name, my_comment,
- bcast,recurse,send_ip,reply_to_ip)))
+ quest_type,name,name_type,nb_flags,ttl,
+ server_type,my_name, my_comment,
+ bcast,recurse,send_ip,reply_to_ip)))
{
add_response_record(d,n);
return n;
diff --git a/source/nameserv.c b/source/nameserv.c
index 77c39062422..ac2dac1683c 100644
--- a/source/nameserv.c
+++ b/source/nameserv.c
@@ -38,7 +38,7 @@ extern int DEBUGLEVEL;
extern pstring scope;
extern pstring myname;
extern struct in_addr ipzero;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
extern struct subnet_record *subnetlist;
@@ -80,7 +80,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
don't really own */
remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
- if (ip_equal(d->bcast_ip, ipgrp))
+ if (ip_equal(d->bcast_ip, wins_ip))
{
if (!lp_wins_support())
{
@@ -125,7 +125,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
regarding the point about M-nodes. */
- if (ip_equal(d->bcast_ip, ipgrp))
+ if (ip_equal(d->bcast_ip, wins_ip))
{
if (lp_wins_support())
{
@@ -194,10 +194,16 @@ void add_domain_names(time_t t)
if (lp_domain_master() && work && work->dom_state == DOMAIN_NONE)
{
+
+ DEBUG(0,("add_domain_names:Checking for domain master on workgroup %s\n", lp_workgroup()));
+
make_nmb_name(&n,lp_workgroup(),0x1b,scope);
if (!find_name(d->namelist, &n, FIND_SELF))
{
- if (ip_equal(d->bcast_ip,ipgrp))
+ DEBUG(0,("add_domain_names: attempting to become domain master browser on workgroup %s, bcast %s\n",
+ lp_workgroup(), inet_ntoa(d->bcast_ip)));
+
+ if (ip_equal(d->bcast_ip,wins_ip))
{
if (lp_wins_support())
{
@@ -221,6 +227,8 @@ void add_domain_names(time_t t)
NetBIOS name 0x1b.
*/
+ DEBUG(0,("add_domain_names:querying for domain master on workgroup %s\n", lp_workgroup()));
+
queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOMAIN,
lp_workgroup(), 0x1b,
0, 0,0,NULL,NULL,
@@ -246,7 +254,7 @@ void add_my_names(void)
for (d = subnetlist; d; d = d->next)
{
- BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,ipgrp);
+ BOOL wins = lp_wins_support() && ip_equal(d->bcast_ip,wins_ip);
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
@@ -339,7 +347,7 @@ void refresh_my_names(time_t t)
void query_refresh_names(time_t t)
{
struct name_record *n;
- struct subnet_record *d = find_subnet(ipgrp);
+ struct subnet_record *d = find_subnet(wins_ip);
static time_t lasttime = 0;
diff --git a/source/nameservreply.c b/source/nameservreply.c
index 544cbc62b44..001695b3fbd 100644
--- a/source/nameservreply.c
+++ b/source/nameservreply.c
@@ -36,7 +36,7 @@ extern int ClientNMB;
extern int DEBUGLEVEL;
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
/****************************************************************************
@@ -120,35 +120,35 @@ void reply_name_release(struct packet_struct *p)
namestr(&nmb->question.question_name)));
if (!(d = find_req_subnet(p->ip, bcast)))
- {
- DEBUG(3,("response packet: bcast %s not known\n",
- inet_ntoa(p->ip)));
- return;
- }
+ {
+ DEBUG(3,("response packet: bcast %s not known\n",
+ inet_ntoa(p->ip)));
+ return;
+ }
if (bcast)
- search |= FIND_LOCAL;
+ search |= FIND_LOCAL;
else
- search |= FIND_WINS;
+ search |= FIND_WINS;
n = find_name_search(&d, &nmb->question.question_name,
- search, ip);
+ search, ip);
/* XXXX under what conditions should we reject the removal?? */
if (n && n->ip_flgs[0].nb_flags == nb_flags)
- {
+ {
success = True;
remove_name(d,n);
n = NULL;
- }
+ }
if (bcast) return;
/* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
- success, False,
- &nmb->question.question_name, nb_flags, 0, ip);
+ success, False,
+ &nmb->question.question_name, nb_flags, 0, ip);
}
@@ -190,7 +190,7 @@ void reply_name_reg(struct packet_struct *p)
{
/* apparently we should return 255.255.255.255 for group queries
(email from MS) */
- ip = ipgrp;
+ ip = wins_ip;
}
if (!(d = find_req_subnet(p->ip, bcast)))
@@ -393,8 +393,8 @@ void reply_name_status(struct packet_struct *p)
if (!strequal(n->name.name,"*") &&
!strequal(n->name.name,"__SAMBA__") &&
- (name_type < 0x1b || name_type > 0x20 ||
- ques_type < 0x1b || ques_type > 0x20 ||
+ (name_type < 0x1b || name_type >= 0x20 ||
+ ques_type < 0x1b || ques_type >= 0x20 ||
strequal(qname, n->name.name)))
{
/* start with first bit of putting info in buffer: the name */
@@ -433,7 +433,7 @@ void reply_name_status(struct packet_struct *p)
/* end of this name list: add wins names too? */
struct subnet_record *w_d;
- if (!(w_d = find_subnet(ipgrp))) break;
+ if (!(w_d = find_subnet(wins_ip))) break;
if (w_d != d)
{
@@ -520,7 +520,7 @@ void reply_name_query(struct packet_struct *p)
}
else
{
- if (!(d = find_subnet(ipgrp)))
+ if (!(d = find_subnet(wins_ip)))
{
DEBUG(3,("name query: wins search %s not known\n",
inet_ntoa(p->ip)));
diff --git a/source/nameservresp.c b/source/nameservresp.c
index ce626976444..30541034b81 100644
--- a/source/nameservresp.c
+++ b/source/nameservresp.c
@@ -192,10 +192,13 @@ static void response_server_check(struct nmb_name *ans_name,
enum state_type cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
- /* initiate a name status check on the server that replied */
+ /* initiate a name status check on the server that replied
+ in addition, the workgroup being checked has been stored
+ in the response_record->my_name (see announce_master) we
+ also propagate this into the same field. */
queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
ans_name->name, ans_name->name_type,
- 0,0,0,NULL,NULL,
+ 0,0,0,n->my_name,NULL,
False,False,n->send_ip,n->reply_to_ip);
}
@@ -243,10 +246,12 @@ static BOOL interpret_node_status(struct subnet_record *d,
if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
if (NAME_HFLAG (nb_flags)) { strcat(flags,"H "); }
if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
- if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); add=True;}
+ if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); }
if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
-
+
+/* I don't think we should be messing with our namelist here... JRA */
+#if 0
/* might as well update our namelist while we're at it */
if (add)
{
@@ -262,9 +267,10 @@ static BOOL interpret_node_status(struct subnet_record *d,
}
add_netbios_entry(d,qname,type,nb_flags,2*60*60,src,nameip,True,bcast);
}
+#endif /* JRA */
/* we want the server name */
- if (serv_name && !*serv_name && !group && t == 0)
+ if (serv_name && !*serv_name && !group && type == 0x20)
{
StrnCpy(serv_name,qname,15);
serv_name[15] = 0;
@@ -275,8 +281,8 @@ static BOOL interpret_node_status(struct subnet_record *d,
{
/* take a guess at some of the name types we're going to ask for.
evaluate whether they are group names or no... */
- if (((t == 0x1b || t == 0x1d ) && !group) ||
- ((t == 0x20 || t == 0x1c || t == 0x1e) && group))
+ if (((t == 0x1b || t == 0x1d || t == 0x20 ) && !group) ||
+ ((t == 0x1c || t == 0x1e ) && group))
{
found = True;
make_nmb_name(name,qname,type,scope);
@@ -306,17 +312,20 @@ static void response_name_status_check(struct in_addr ip,
fstring serv_name;
if (interpret_node_status(d,nmb->answers->rdata,
- &name,name.name_type,serv_name,ip,bcast))
+ &name,0x20,serv_name,ip,bcast))
{
if (*serv_name)
{
+ /* response_record->my_name contains the
+ workgroup name to sync with. See
+ response_server_check() */
sync_server(n->state,serv_name,
- name.name,name.name_type, n->send_ip);
+ n->my_name,name.name_type, n->send_ip);
}
}
else
{
- DEBUG(1,("No 0x1d name type in interpret_node_status()\n"));
+ DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
}
}
@@ -409,69 +418,74 @@ static void response_name_query_sync(struct nmb_packet *nmb,
struct nmb_name *ans_name, BOOL bcast,
struct response_record *n, struct subnet_record *d)
{
- DEBUG(4, ("Name query at %s ip %s - ",
- namestr(&n->name), inet_ntoa(n->send_ip)));
-
- if (!name_equal(&n->name, ans_name))
- {
- /* someone gave us the wrong name as a reply. oops. */
- DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
- return;
- }
+ DEBUG(4, ("Name query at %s ip %s - ",
+ namestr(&n->name), inet_ntoa(n->send_ip)));
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ if (!name_equal(&n->name, ans_name))
{
- int nb_flags = nmb->answers->rdata[0];
- struct in_addr found_ip;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- if (!ip_equal(n->send_ip, found_ip))
- {
- /* someone gave us the wrong ip as a reply. oops. */
- DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
- DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
- return;
- }
-
- DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
+ /* someone gave us the wrong name as a reply. oops. */
+ DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+ return;
+ }
- if (n->state == NAME_QUERY_SYNC_LOCAL ||
- n->state == NAME_QUERY_SYNC_REMOTE)
- {
- struct work_record *work = NULL;
- if ((work = find_workgroupstruct(d, ans_name->name, False)))
- {
- BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ int nb_flags = nmb->answers->rdata[0];
+ struct in_addr found_ip;
+
+ putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+ if (!ip_equal(n->send_ip, found_ip))
+ {
+ /* someone gave us the wrong ip as a reply. oops. */
+ DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
+ DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
+ return;
+ }
- /* the server is there: sync quick before it (possibly) dies! */
- sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
- found_ip, local_list_only);
- }
- }
- else
- {
- /* update our netbios name list (re-register it if necessary) */
- add_netbios_entry(d, ans_name->name, ans_name->name_type,
- nb_flags,GET_TTL(0),REGISTER,
- found_ip,False,!bcast);
- }
+ DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
+
+ if (n->state == NAME_QUERY_SYNC_LOCAL ||
+ n->state == NAME_QUERY_SYNC_REMOTE)
+ {
+ struct work_record *work = NULL;
+ /* We cheat here as we know that the workgroup name has
+ been placed in the my_comment field of the
+ response_record struct by the code in
+ start_sync_browse_entry().
+ */
+ if ((work = find_workgroupstruct(d, n->my_comment, False)))
+ {
+ BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+
+ /* the server is there: sync quick before it (possibly) dies! */
+ sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
+ found_ip, local_list_only);
+ }
}
- else
+ else
{
- DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
- if (n->state == NAME_QUERY_CONFIRM)
- {
- /* XXXX remove_netbios_entry()? */
- /* lots of things we ought to do, here. if we get here,
- then we're in a mess: our name database doesn't match
- reality. sort it out
+ /* update our netbios name list (re-register it if necessary) */
+ add_netbios_entry(d, ans_name->name, ans_name->name_type,
+ nb_flags,GET_TTL(0),REGISTER,
+ found_ip,False,!bcast);
+ }
+ }
+ else
+ {
+ DEBUG(4, (" NEGATIVE RESPONSE!\n"));
+
+ if (n->state == NAME_QUERY_CONFIRM)
+ {
+ /* XXXX remove_netbios_entry()? */
+ /* lots of things we ought to do, here. if we get here,
+ then we're in a mess: our name database doesn't match
+ reality. sort it out
*/
- remove_netbios_name(d,n->name.name, n->name.name_type,
- REGISTER,n->send_ip);
- }
+ remove_netbios_name(d,n->name.name, n->name.name_type,
+ REGISTER,n->send_ip);
}
+ }
}
@@ -481,13 +495,13 @@ static void response_name_query_sync(struct nmb_packet *nmb,
static void debug_rr_type(int rr_type)
{
switch (rr_type)
- {
- case NMB_STATUS: DEBUG(3,("Name status ")); break;
- case NMB_QUERY : DEBUG(3,("Name query ")); break;
- case NMB_REG : DEBUG(3,("Name registration ")); break;
- case NMB_REL : DEBUG(3,("Name release ")); break;
- default : DEBUG(1,("wrong response packet type received")); break;
- }
+ {
+ case NMB_STATUS: DEBUG(3,("Name status ")); break;
+ case NMB_QUERY : DEBUG(3,("Name query ")); break;
+ case NMB_REG : DEBUG(3,("Name registration ")); break;
+ case NMB_REL : DEBUG(3,("Name release ")); break;
+ default : DEBUG(1,("wrong response packet type received")); break;
+ }
}
/****************************************************************************
@@ -497,8 +511,8 @@ void debug_state_type(int state)
{
/* report the state type to help debugging */
switch (state)
- {
- case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
+ {
+ case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
@@ -506,17 +520,17 @@ void debug_state_type(int state)
case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
-
+
case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
-
+
case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
-
- case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
+
+ case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
-
+
default: break;
- }
+ }
}
/****************************************************************************
@@ -528,87 +542,95 @@ static BOOL response_problem_check(struct response_record *n,
struct nmb_packet *nmb, char *ans_name)
{
switch (nmb->answers->rr_type)
- {
- case NMB_REL:
{
+ case NMB_REL:
+ {
if (n->num_msgs > 1)
- {
+ {
DEBUG(1,("more than one release name response received!\n"));
return True;
- }
+ }
break;
- }
+ }
case NMB_REG:
- {
+ {
if (n->num_msgs > 1)
- {
+ {
DEBUG(1,("more than one register name response received!\n"));
return True;
- }
+ }
break;
- }
-
+ }
+
case NMB_QUERY:
- {
- if (n->num_msgs > 1)
- {
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ if (n->num_msgs > 1)
+ {
+ if (nmb->header.rcode == 0 && nmb->answers->rdata)
+ {
+ int nb_flags = nmb->answers->rdata[0];
+
+ if ((!NAME_GROUP(nb_flags)))
{
- int nb_flags = nmb->answers->rdata[0];
-
- if ((!NAME_GROUP(nb_flags)))
+ /* oh dear. more than one person responded to a
+ unique name.
+ there is either a network problem, a
+ configuration problem
+ or a server is mis-behaving */
+
+ /* XXXX mark the name as in conflict, and then let the
+ person who just responded know that they
+ must also mark it
+ as in conflict, and therefore must NOT use it.
+ see rfc1001.txt 15.1.3.5 */
+
+ /* this may cause problems for some
+ early versions of nmbd */
+
+ switch (n->state)
+ {
+ case NAME_QUERY_FIND_MST:
{
- /* oh dear. more than one person responded to a unique name.
- there is either a network problem, a configuration problem
- or a server is mis-behaving */
-
- /* XXXX mark the name as in conflict, and then let the
- person who just responded know that they must also mark it
- as in conflict, and therefore must NOT use it.
- see rfc1001.txt 15.1.3.5 */
-
- /* this may cause problems for some early versions of nmbd */
-
- switch (n->state)
- {
- case NAME_QUERY_FIND_MST:
- {
- /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
- return False;
- }
- case NAME_QUERY_ANNOUNCE_HOST:
- case NAME_QUERY_DOM_SRV_CHK:
- case NAME_QUERY_SRV_CHK:
- case NAME_QUERY_MST_CHK:
- {
- if (!strequal(ans_name,n->name.name))
- {
- /* one subnet, one master browser per workgroup */
- /* XXXX force an election? */
-
- DEBUG(3,("more than one master browser replied!\n"));
- return True;
- }
- break;
- }
- default: break;
- }
- DEBUG(3,("Unique Name conflict detected!\n"));
- return True;
+ /* query for ^1^2__MSBROWSE__^2^1 expect
+ lots of responses */
+ return False;
}
+ case NAME_QUERY_ANNOUNCE_HOST:
+ case NAME_QUERY_DOM_SRV_CHK:
+ case NAME_QUERY_SRV_CHK:
+ case NAME_QUERY_MST_CHK:
+ {
+ if (!strequal(ans_name,n->name.name))
+ {
+ /* one subnet, one master browser
+ per workgroup */
+ /* XXXX force an election? */
+
+ DEBUG(3,("more than one master browser replied!\n"));
+ return True;
+ }
+ break;
+ }
+ default: break;
+ }
+ DEBUG(3,("Unique Name conflict detected!\n"));
+ return True;
}
- else
- {
- /* we have received a negative reply, having already received
- at least one response (pos/neg). something's really wrong! */
-
- DEBUG(3,("wierd name query problem detected!\n"));
- return True;
- }
- }
+ }
+ else
+ {
+ /* we have received a negative reply,
+ having already received
+ at least one response (pos/neg).
+ something's really wrong! */
+
+ DEBUG(3,("wierd name query problem detected!\n"));
+ return True;
+ }
+ }
+ }
}
- }
return False;
}
@@ -685,73 +707,73 @@ static BOOL response_compatible(struct response_record *n,
process the response packet received
****************************************************************************/
static void response_process(struct subnet_record *d, struct packet_struct *p,
- struct response_record *n, struct nmb_packet *nmb,
- BOOL bcast, struct nmb_name *ans_name)
+ struct response_record *n, struct nmb_packet *nmb,
+ BOOL bcast, struct nmb_name *ans_name)
{
switch (n->state)
- {
- case NAME_RELEASE:
{
+ case NAME_RELEASE:
+ {
response_name_release(ans_name, d, p);
break;
- }
+ }
case NAME_REGISTER:
- {
+ {
response_name_reg(ans_name, d, p);
break;
- }
+ }
case NAME_REGISTER_CHALLENGE:
- {
+ {
response_name_query_register(nmb, ans_name, n, d);
break;
- }
+ }
case NAME_QUERY_DOM_SRV_CHK:
case NAME_QUERY_SRV_CHK:
case NAME_QUERY_FIND_MST:
- {
- response_server_check(ans_name, n, d);
- break;
- }
-
+ {
+ response_server_check(ans_name, n, d);
+ break;
+ }
+
case NAME_STATUS_DOM_SRV_CHK:
case NAME_STATUS_SRV_CHK:
- {
- response_name_status_check(p->ip, nmb, bcast, n, d);
- break;
- }
-
+ {
+ response_name_status_check(p->ip, nmb, bcast, n, d);
+ break;
+ }
+
case NAME_QUERY_ANNOUNCE_HOST:
- {
- response_announce_host(ans_name, nmb, n, d);
- break;
- }
+ {
+ response_announce_host(ans_name, nmb, n, d);
+ break;
+ }
case NAME_QUERY_CONFIRM:
case NAME_QUERY_SYNC_LOCAL:
case NAME_QUERY_SYNC_REMOTE:
- {
- response_name_query_sync(nmb, ans_name, bcast, n, d);
- break;
- }
+ {
+ response_name_query_sync(nmb, ans_name, bcast, n, d);
+ break;
+ }
case NAME_QUERY_MST_CHK:
- {
- /* no action required here. it's when NO responses are received
- that we need to do something. see expire_name_query_entries() */
+ {
+ /* no action required here. it's when NO responses are received
+ that we need to do something. see expire_name_query_entries() */
- DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
- namestr(&n->name), inet_ntoa(n->send_ip)));
- break;
- }
-
+ DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
+ namestr(&n->name), inet_ntoa(n->send_ip)));
+ break;
+ }
+
default:
- {
- DEBUG(1,("unknown state type received in response_netbios_packet\n"));
- break;
+ {
+ DEBUG(1,("unknown state type received in response_netbios_packet\n"));
+ break;
+ }
}
- }
}
@@ -772,43 +794,41 @@ void response_netbios_packet(struct packet_struct *p)
}
if (!d)
- {
- DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
- return;
- }
+ {
+ DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
+ return;
+ }
/* args wrong way round: spotted by ccm@shentel.net */
if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
- {
- DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
- DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
- }
-
+ {
+ DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
+ DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
+ }
+
if (nmb->answers == NULL)
- {
+ {
/* hm. the packet received was a response, but with no answer. wierd! */
DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
inet_ntoa(p->ip), BOOLSTR(bcast)));
return;
- }
+ }
ans_name = &nmb->answers->rr_name;
DEBUG(3,("response for %s from %s (bcast=%s)\n",
namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
debug_rr_type(nmb->answers->rr_type);
-
+
n->num_msgs++; /* count number of responses received */
n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
-
+
debug_state_type(n->state);
-
+
/* problem checking: multiple responses etc */
if (response_problem_check(n, nmb, ans_name->name))
return;
-
+
/* now deal with the current state */
response_process(d, p, n, nmb, bcast, ans_name);
}
-
-
diff --git a/source/namework.c b/source/namework.c
index 20c1050597e..1d3ff9e0ee3 100644
--- a/source/namework.c
+++ b/source/namework.c
@@ -173,10 +173,10 @@ BOOL same_context(struct dgram_packet *dgram)
resources. We just have to pass it to smbd (via browser.dat) and let
the client choose using bit masks.
******************************************************************/
-static void process_announce(struct packet_struct *p,uint16 command,char *buf)
+static void process_localnet_announce(struct packet_struct *p,uint16 command,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
- struct subnet_record *d = find_subnet(p->ip);
+ struct subnet_record *d = find_subnet(p->ip); /* Explicitly exclude WINS - local nets only */
int update_count = CVAL(buf,0);
int ttl = IVAL(buf,1)/1000;
@@ -278,25 +278,33 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
static void process_master_announce(struct packet_struct *p,char *buf)
{
struct dgram_packet *dgram = &p->packet.dgram;
- struct subnet_record *d = find_subnet(p->ip);
+ struct subnet_record *d = find_subnet_all(p->ip); /* Explicitly include WINS */
char *name = buf;
struct work_record *work;
name[15] = 0;
- DEBUG(3,("Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
+ DEBUG(3,("process_master_announce: Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
if (same_context(dgram)) return;
- if (!d) return;
+ if (!d)
+ {
+ DEBUG(3,("process_master_announce: Cannot find interface\n"));
+ return;
+ }
- if (!lp_domain_master()) return;
+ if (!lp_domain_master())
+ {
+ DEBUG(3,("process_master_announce: Not configured as domain master - ignoring master announce.\n"));
+ return;
+ }
for (work = d->workgrouplist; work; work = work->next)
{
- if (AM_MASTER(work))
+ if (AM_MASTER(work) || AM_DOMMST(work) || AM_ANY_MASTER(work))
{
/* merge browse lists with them */
- add_browser_entry(name,0x1b, work->work_group,30,p->ip,True);
+ add_browser_entry(name,0x1d, work->work_group,30,p->ip,True);
}
}
}
@@ -612,13 +620,13 @@ static void process_announce_request(struct packet_struct *p,char *buf)
struct dgram_packet *dgram = &p->packet.dgram;
struct work_record *work;
struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip);
+ struct subnet_record *d = find_subnet(ip); /* Explicitly NO WINS */
int token = CVAL(buf,0);
char *name = buf+1;
name[15] = 0;
- DEBUG(3,("Announce request from %s to %s token=0x%X\n",
+ DEBUG(3,("process_announce_request: Announce request from %s to %s token=0x%X\n",
name,namestr(&dgram->dest_name), token));
if (strequal(dgram->source_name.name,myname)) return;
@@ -630,8 +638,13 @@ static void process_announce_request(struct packet_struct *p,char *buf)
if (strequal(dgram->dest_name, lp_workgroup()) return; ???
*/
- if (!d) return;
-
+ if (!d)
+ {
+ DEBUG(3,("process_announce_request: No local interface to announce to %s\n",
+ name));
+ return;
+ }
+
for (work = d->workgrouplist; work; work = work->next)
{
/* XXXX BUG: the destination name type should also be checked,
@@ -660,7 +673,7 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
case ANN_LocalMasterAnnouncement:
{
debug_browse_data(buf, len);
- process_announce(p,command,buf+1);
+ process_localnet_announce(p,command,buf+1);
break;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index e45facdc2e3..eefb4162f79 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -272,7 +272,7 @@ static void load_hosts_file(char *fname)
}
ipaddr = *interpret_addr2(ip);
- d = find_subnet(ipaddr);
+ d = find_subnet_all(ipaddr);
if (d) {
add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
diff --git a/source/nmbsync.c b/source/nmbsync.c
index 2efb364bcae..fa60b3ac35a 100644
--- a/source/nmbsync.c
+++ b/source/nmbsync.c
@@ -140,7 +140,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
{
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
- if (!d || !work || !AM_MASTER(work)) return;
+ if (!d || !work || !AM_ANY_MASTER(work)) return;
pid = getpid();
uid = getuid();
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 672f1fe5483..64dd01eeafa 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -600,7 +600,7 @@ static void init_globals(void)
Globals.bDomainMaster = False;
Globals.bDomainLogons = False;
Globals.bBrowseList = True;
- Globals.bWINSsupport = True;
+ Globals.bWINSsupport = False;
Globals.bWINSproxy = False;
Globals.ReadSize = 16*1024;