1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +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 used to be commit a82476eee2c521e5eed092bc367da0a7cef23de1)
This commit is contained in:
Samba Release Account 1997-04-09 01:19:25 +00:00
parent 02e610b927
commit 20b5dea237
23 changed files with 814 additions and 652 deletions

View File

@ -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>

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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,7 +309,7 @@ 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)
{
@ -364,7 +364,7 @@ void announce_host(time_t t)
/****************************************************************************
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
@ -394,85 +394,76 @@ 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;
/* Try and find our workgroup on this subnet */
struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
/* all DOMs (which should also be master browsers) */
if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
if (work)
{
/* check the existence of a pdc for this workgroup, and if
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 */
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() &&
ip_equal(d->bcast_ip, wins_ip))
{
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,
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
{
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);
}
}
}
}
}
DEBUG(4, ("Local Announce: find %s<%02x> on %s\n",
name, type, inet_ntoa(d->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);
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

View File

@ -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,20 +167,47 @@ 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
/* 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)) {
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->group,0x20,0,0,0,NULL,NULL,
b->name,0x20,0,0,0,NULL,b->group,
False,False,b->ip,b->ip);
}
@ -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"));
}
}

View File

@ -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;
}
@ -186,7 +187,7 @@ struct name_record *find_name_search(struct subnet_record **d,
if (!(search & FIND_WINS)) return NULL;
/* find WINS subnet record. */
*d = find_subnet(ipgrp);
*d = find_subnet(wins_ip);
if (*d == NULL) return NULL;
@ -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;

View File

@ -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 */

View File

@ -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,7 +86,6 @@ 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
@ -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
@ -172,7 +186,7 @@ void add_subnet_interfaces(void)
/* 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_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)))
{

View File

@ -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;
}

View File

@ -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;

View File

@ -47,7 +47,7 @@ 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;
@ -58,16 +58,26 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
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 (!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)
{

View File

@ -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;
@ -323,6 +323,8 @@ 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);
@ -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];

View File

@ -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;
/***************************************************************************
@ -62,7 +62,7 @@ static void dead_netbios_entry(struct subnet_record *d,
if ((!NAME_GROUP(n->nb_flags)))
{
struct subnet_record *d1 = find_subnet(ipgrp);
struct subnet_record *d1 = find_subnet(wins_ip);
if (d1)
{
/* remove the name that had been registered with us,
@ -303,7 +303,6 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
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;

View File

@ -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;

View File

@ -36,7 +36,7 @@ extern int ClientNMB;
extern int DEBUGLEVEL;
extern struct in_addr ipgrp;
extern struct in_addr wins_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)));

View File

@ -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"));
}
}
@ -440,7 +449,12 @@ static void response_name_query_sync(struct nmb_packet *nmb,
n->state == NAME_QUERY_SYNC_REMOTE)
{
struct work_record *work = NULL;
if ((work = find_workgroupstruct(d, ans_name->name, False)))
/* 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;
@ -498,7 +512,7 @@ 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;
@ -512,7 +526,7 @@ void debug_state_type(int state)
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;
@ -559,22 +573,27 @@ static BOOL response_problem_check(struct response_record *n,
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
/* 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
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 */
/* 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 */
/* query for ^1^2__MSBROWSE__^2^1 expect
lots of responses */
return False;
}
case NAME_QUERY_ANNOUNCE_HOST:
@ -584,7 +603,8 @@ static BOOL response_problem_check(struct response_record *n,
{
if (!strequal(ans_name,n->name.name))
{
/* one subnet, one master browser per workgroup */
/* one subnet, one master browser
per workgroup */
/* XXXX force an election? */
DEBUG(3,("more than one master browser replied!\n"));
@ -600,8 +620,10 @@ static BOOL response_problem_check(struct response_record *n,
}
else
{
/* we have received a negative reply, having already received
at least one response (pos/neg). something's really wrong! */
/* 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;
@ -810,5 +832,3 @@ void response_netbios_packet(struct packet_struct *p)
/* now deal with the current state */
response_process(d, p, n, nmb, bcast, ans_name);
}

View File

@ -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,7 +638,12 @@ 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)
{
@ -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;
}

View File

@ -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);

View File

@ -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();

View File

@ -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;