mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
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.
This commit is contained in:
parent
deedac6523
commit
a82476eee2
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
/* Try and find our workgroup on this subnet */
|
||||
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), 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);
|
||||
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
|
||||
|
@ -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 (!(work = find_workgroupstruct(d, b->group, False))) return;
|
||||
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;
|
||||
}
|
||||
|
||||
/* only sync if we are the master */
|
||||
if (AM_MASTER(work)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* first check whether the group we intend to sync with exists. if it
|
||||
doesn't, the server must have died. o dear. */
|
||||
/* 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)) {
|
||||
|
||||
/* 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);
|
||||
DEBUG(4, ("start_sync_browse_entry: Initiating %s sync with %s<0x20>, \
|
||||
workgroup %s\n",
|
||||
b->local ? "local" : "remote", b->name, b->group));
|
||||
|
||||
/* 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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
|
||||
{
|
||||
if (!ip_equal(d->bcast_ip, wins_ip))
|
||||
{
|
||||
return d;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
}
|
||||
else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
|
||||
{
|
||||
if (!ip_equal(d->bcast_ip, wins_ip))
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* add the interface into our subnet database */
|
||||
if (!find_subnet(i->bcast))
|
||||
{
|
||||
make_subnet(i->bcast,i->nmask);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
|
||||
if (lp_wins_support() || (*lp_wins_server()))
|
||||
/* loop on all local interfaces */
|
||||
for (i = local_interfaces; i; i = i->next)
|
||||
{
|
||||
struct in_addr wins_bcast = ipgrp;
|
||||
struct in_addr wins_nmask = ipzero;
|
||||
make_subnet(wins_bcast, wins_nmask);
|
||||
/* add the interface into our subnet database */
|
||||
if (!find_subnet(i->bcast))
|
||||
{
|
||||
make_subnet(i->bcast,i->nmask);
|
||||
}
|
||||
}
|
||||
|
||||
/* add the pseudo-ip interface for WINS: 255.255.255.255 */
|
||||
if (lp_wins_support() || (*lp_wins_server()))
|
||||
{
|
||||
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)))
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
code = SVAL(buf,0);
|
||||
switch (code)
|
||||
{
|
||||
case 0:
|
||||
if (!lp_domain_logons())
|
||||
{
|
||||
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:
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False)))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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:
|
||||
{
|
||||
/* 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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* 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 */
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* nothing to do but delete the dead expected-response structure */
|
||||
/* this is normal. */
|
||||
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 (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 */
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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)));
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
/* someone gave us the wrong name as a reply. oops. */
|
||||
DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
|
||||
return;
|
||||
}
|
||||
|
||||
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)));
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
/* 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)));
|
||||
|
||||
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
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user