mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
.cvsignore: Added make_smbcodepage
interface.c: Added is_local_net(). locking.c: Added Fix for zero length share files from Gerald Werner <wernerg@mfldclin.edu> plus a race condition fix for the fix. nameannounce.c: Made function static. namedbresp.c: extern int ClientDGRAM removed - not used. namedbserver.c: extern int ClientDGRAM removed - not used. namedbsubnet.c: Added code to make sockets per subnet. namepacket.c: Added code to read from all sockets & filter. nameresp.c: extern int ClientDGRAM removed - not used. nameserv.c: Indentation tidyup :-). nameserv.h: Added sockets to struct subnet. nameservresp.c: Improved debug message. nmbd.c: Changed to terminte on listen_for_packets exiting. nmbsync.c: extern int ClientDGRAM & ClientNMB removed - not used. proto.h: The usual. util.c: Fixed debug message. Jeremy (jallison@whistle.com)
This commit is contained in:
parent
92e7092af1
commit
6904c2de08
@ -1,6 +1,7 @@
|
||||
Makefile.RPM
|
||||
makefile
|
||||
makefile.sunos5
|
||||
make_smbcodepage
|
||||
nmbd
|
||||
nmblookup
|
||||
smbclient
|
||||
|
@ -291,6 +291,8 @@ struct subnet_record
|
||||
struct in_addr bcast_ip;
|
||||
struct in_addr mask_ip;
|
||||
struct in_addr myip;
|
||||
int nmb_sock; /* socket to listen for unicast 137. */
|
||||
int dgram_sock; /* socket to listen for unicast 138. */
|
||||
};
|
||||
|
||||
/* a resource record */
|
||||
|
@ -93,9 +93,9 @@ void CloseDir(void *p);
|
||||
char *ReadDirName(void *p);
|
||||
BOOL SeekDir(void *p,int pos);
|
||||
int TellDir(void *p);
|
||||
void DirCacheAdd(char *path,char *name,char *dname,int snum);
|
||||
char *DirCacheCheck(char *path,char *name,int snum);
|
||||
void DirCacheFlush(int snum);
|
||||
void DirCacheAdd( char *path, char *name, char *dname, int snum );
|
||||
char *DirCacheCheck( char *path, char *name, int snum );
|
||||
void DirCacheFlush( int snum );
|
||||
|
||||
/*The following definitions come from fault.c */
|
||||
|
||||
@ -111,6 +111,7 @@ void load_interfaces(void);
|
||||
void iface_set_default(char *ip,char *bcast,char *nmask);
|
||||
BOOL ismyip(struct in_addr ip);
|
||||
BOOL ismybcast(struct in_addr bcast);
|
||||
BOOL is_local_net(struct in_addr from);
|
||||
int iface_count(void);
|
||||
struct in_addr *iface_n_ip(int n);
|
||||
struct in_addr *iface_bcast(struct in_addr ip);
|
||||
@ -372,11 +373,6 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
|
||||
int name_type,
|
||||
struct subnet_record *d,
|
||||
struct in_addr ip);
|
||||
void do_announce_host(int command,
|
||||
char *from_name, int from_type, struct in_addr from_ip,
|
||||
char *to_name , int to_type , struct in_addr to_ip,
|
||||
time_t announce_interval,
|
||||
char *server_name, int server_type, char *server_comment);
|
||||
void announce_my_servers_removed(void);
|
||||
void announce_server(struct subnet_record *d, struct work_record *work,
|
||||
char *name, char *comment, time_t ttl, int server_type);
|
||||
@ -503,7 +499,7 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
|
||||
char *data,int len);
|
||||
void queue_packet(struct packet_struct *packet);
|
||||
void run_packet_queue();
|
||||
void listen_for_packets(BOOL run_election);
|
||||
BOOL listen_for_packets(BOOL run_election);
|
||||
BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
|
||||
char *dstname,int src_type,int dest_type,
|
||||
struct in_addr dest_ip,struct in_addr src_ip);
|
||||
@ -946,6 +942,9 @@ int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
|
||||
|
||||
/*The following definitions come from ubi_dLinkList.c */
|
||||
|
||||
|
||||
/*The following definitions come from ufc.c */
|
||||
|
||||
char *ufc_crypt(char *key,char *salt);
|
||||
|
@ -399,6 +399,18 @@ BOOL ismybcast(struct in_addr bcast)
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
check if a packet is from a local (known) net
|
||||
**************************************************************************/
|
||||
BOOL is_local_net(struct in_addr from)
|
||||
{
|
||||
struct interface *i;
|
||||
for (i=local_interfaces;i;i=i->next)
|
||||
if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
how many interfaces do we have
|
||||
**************************************************************************/
|
||||
|
@ -3284,8 +3284,8 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
|
||||
{
|
||||
if (port) {
|
||||
if (port == SMB_PORT || port == NMB_PORT)
|
||||
DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
|
||||
port,socket_addr,strerror(errno)));
|
||||
DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
|
||||
port,inet_ntoa(sock.sin_addr),strerror(errno)));
|
||||
close(res);
|
||||
|
||||
if (dlevel > 0 && port < 1000)
|
||||
|
@ -715,6 +715,31 @@ static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
|
||||
return(True);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Force a share file to be deleted.
|
||||
********************************************************************/
|
||||
|
||||
static int delete_share_file( int cnum, char *fname )
|
||||
{
|
||||
/* the share file could be owned by anyone, so do this as root */
|
||||
become_root(False);
|
||||
|
||||
if(unlink(fname) != 0)
|
||||
{
|
||||
DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
|
||||
fname, strerror(errno)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
|
||||
}
|
||||
|
||||
/* return to our previous privilage level */
|
||||
unbecome_root(False);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
lock a share mode file.
|
||||
******************************************************************/
|
||||
@ -820,6 +845,31 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok
|
||||
{
|
||||
int fd = (int)token;
|
||||
int ret = True;
|
||||
struct stat sb;
|
||||
pstring fname;
|
||||
|
||||
/* Fix for zero length share files from
|
||||
Gerald Werner <wernerg@mfldclin.edu> */
|
||||
|
||||
share_name(cnum, dev, inode, fname);
|
||||
|
||||
/* get the share mode file size */
|
||||
if(fstat((int)token, &sb) != 0)
|
||||
{
|
||||
DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
|
||||
fname, strerror(errno)));
|
||||
sb.st_size = 1;
|
||||
ret = False;
|
||||
}
|
||||
|
||||
/* If the file was zero length, we must delete before
|
||||
doing the unlock to avoid a race condition (see
|
||||
the code in lock_share_mode_entry for details.
|
||||
*/
|
||||
|
||||
/* remove the share file if zero length */
|
||||
if(sb.st_size == 0)
|
||||
delete_share_file(cnum, fname);
|
||||
|
||||
/* token is the fd of the open share mode file. */
|
||||
/* Unlock the first byte. */
|
||||
@ -834,31 +884,6 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Force a share file to be deleted.
|
||||
********************************************************************/
|
||||
|
||||
static int delete_share_file( int cnum, char *fname )
|
||||
{
|
||||
/* the share file could be owned by anyone, so do this as root */
|
||||
become_root(False);
|
||||
|
||||
if(unlink(fname) != 0)
|
||||
{
|
||||
DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
|
||||
fname, strerror(errno)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
|
||||
}
|
||||
|
||||
/* return to our previous privilage level */
|
||||
unbecome_root(False);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Read a share file into a buffer.
|
||||
********************************************************************/
|
||||
|
@ -67,7 +67,7 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
||||
work->needannounce = True;
|
||||
|
||||
DEBUG(2,("sending announce request to %s for workgroup %s\n",
|
||||
inet_ntoa(ip),work->work_group));
|
||||
inet_ntoa(ip),work->work_group));
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf;
|
||||
@ -84,9 +84,9 @@ void announce_request(struct work_record *work, struct in_addr ip)
|
||||
of 0x1e, then we could get the master browser to announce to
|
||||
us instead of the members of the workgroup. wha-hey! */
|
||||
|
||||
send_mailslot_reply(False, BROWSE_MAILSLOT,ClientDGRAM,
|
||||
outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
|
||||
send_mailslot_reply(False, BROWSE_MAILSLOT, ClientDGRAM,
|
||||
outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
|
||||
}
|
||||
|
||||
|
||||
@ -106,15 +106,15 @@ void do_announce_request(char *info, char *to_name, int announce_type,
|
||||
p++;
|
||||
|
||||
DEBUG(2,("sending announce type %d: info %s to %s - server %s(%x)\n",
|
||||
announce_type, info, inet_ntoa(dest_ip),to_name,to));
|
||||
announce_type, info, inet_ntoa(dest_ip),to_name,to));
|
||||
|
||||
StrnCpy(p,info,16);
|
||||
strupper(p);
|
||||
p = skip_string(p,1);
|
||||
|
||||
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
|
||||
outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
|
||||
send_mailslot_reply(False,BROWSE_MAILSLOT, ClientDGRAM,
|
||||
outbuf,PTR_DIFF(p,outbuf),
|
||||
myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
|
||||
}
|
||||
|
||||
|
||||
@ -144,48 +144,48 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
|
||||
/****************************************************************************
|
||||
send a host announcement packet
|
||||
**************************************************************************/
|
||||
void do_announce_host(int command,
|
||||
static void do_announce_host(int command,
|
||||
char *from_name, int from_type, struct in_addr from_ip,
|
||||
char *to_name , int to_type , struct in_addr to_ip,
|
||||
time_t announce_interval,
|
||||
char *server_name, int server_type, char *server_comment)
|
||||
{
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
pstring outbuf;
|
||||
char *p;
|
||||
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf+1;
|
||||
bzero(outbuf,sizeof(outbuf));
|
||||
p = outbuf+1;
|
||||
|
||||
/* command type */
|
||||
CVAL(outbuf,0) = command;
|
||||
/* command type */
|
||||
CVAL(outbuf,0) = command;
|
||||
|
||||
/* announcement parameters */
|
||||
CVAL(p,0) = updatecount;
|
||||
SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
|
||||
/* announcement parameters */
|
||||
CVAL(p,0) = updatecount;
|
||||
SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
|
||||
|
||||
StrnCpy(p+5,server_name,16);
|
||||
strupper(p+5);
|
||||
StrnCpy(p+5,server_name,16);
|
||||
strupper(p+5);
|
||||
|
||||
CVAL(p,21) = lp_major_announce_version(); /* major version */
|
||||
CVAL(p,22) = lp_minor_announce_version(); /* minor version */
|
||||
CVAL(p,21) = lp_major_announce_version(); /* major version */
|
||||
CVAL(p,22) = lp_minor_announce_version(); /* minor version */
|
||||
|
||||
SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
|
||||
/* browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT)*/
|
||||
SSVAL(p,27,BROWSER_ELECTION_VERSION);
|
||||
SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */
|
||||
SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
|
||||
/* browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT)*/
|
||||
SSVAL(p,27,BROWSER_ELECTION_VERSION);
|
||||
SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */
|
||||
|
||||
pstrcpy(p+31,server_comment);
|
||||
p += 31;
|
||||
p = skip_string(p,1);
|
||||
pstrcpy(p+31,server_comment);
|
||||
p += 31;
|
||||
p = skip_string(p,1);
|
||||
|
||||
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
|
||||
debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
|
||||
|
||||
/* send the announcement */
|
||||
send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
from_name, to_name,
|
||||
from_type, to_type,
|
||||
to_ip, from_ip);
|
||||
/* send the announcement */
|
||||
send_mailslot_reply(False,BROWSE_MAILSLOT, ClientDGRAM, outbuf,
|
||||
PTR_DIFF(p,outbuf),
|
||||
from_name, to_name,
|
||||
from_type, to_type,
|
||||
to_ip, from_ip);
|
||||
}
|
||||
|
||||
|
||||
@ -217,58 +217,58 @@ void announce_my_servers_removed(void)
|
||||
void announce_server(struct subnet_record *d, struct work_record *work,
|
||||
char *name, char *comment, time_t ttl, int server_type)
|
||||
{
|
||||
/* domain type cannot have anything in it that might confuse
|
||||
a client into thinking that the domain is in fact a server.
|
||||
(SV_TYPE_SERVER_UNIX, for example)
|
||||
*/
|
||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||
BOOL wins_iface = ip_equal(d->bcast_ip, wins_ip);
|
||||
/* domain type cannot have anything in it that might confuse
|
||||
a client into thinking that the domain is in fact a server.
|
||||
(SV_TYPE_SERVER_UNIX, for example)
|
||||
*/
|
||||
uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
|
||||
BOOL wins_iface = ip_equal(d->bcast_ip, wins_ip);
|
||||
|
||||
if(wins_iface)
|
||||
{
|
||||
DEBUG(0,("announce_server: error - announcement requested on WINS \
|
||||
if(wins_iface)
|
||||
{
|
||||
DEBUG(0,("announce_server: error - announcement requested on WINS \
|
||||
interface for workgroup %s, name %s\n", work->work_group, name));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only do domain announcements if we are a master and it's
|
||||
our name we're being asked to announce. */
|
||||
if (AM_MASTER(work) && strequal(myname,name))
|
||||
{
|
||||
DEBUG(3,("sending local master announce to %s for %s(1e)\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
do_announce_host(ANN_LocalMasterAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
work->work_group, 0x1e, d->bcast_ip,
|
||||
ttl,
|
||||
name, server_type, comment);
|
||||
|
||||
DEBUG(3,("sending domain announce to %s for %s\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
/* XXXX should we do a domain-announce-kill? */
|
||||
if (server_type != 0)
|
||||
{
|
||||
do_announce_host(ANN_DomainAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
MSBROWSE, 0x01, d->bcast_ip,
|
||||
ttl,
|
||||
work->work_group, server_type ? domain_type : 0,
|
||||
name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(3,("sending host announce to %s for %s(1d)\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
/* Only do domain announcements if we are a master and it's
|
||||
our name we're being asked to announce. */
|
||||
if (AM_MASTER(work) && strequal(myname,name))
|
||||
{
|
||||
DEBUG(3,("sending local master announce to %s for %s(1e)\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
do_announce_host(ANN_LocalMasterAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
work->work_group, 0x1e, d->bcast_ip,
|
||||
ttl,
|
||||
name, server_type, comment);
|
||||
|
||||
DEBUG(3,("sending domain announce to %s for %s\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
/* XXXX should we do a domain-announce-kill? */
|
||||
if (server_type != 0)
|
||||
{
|
||||
do_announce_host(ANN_DomainAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
MSBROWSE, 0x01, d->bcast_ip,
|
||||
ttl,
|
||||
work->work_group, server_type ? domain_type : 0,
|
||||
name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(3,("sending host announce to %s for %s(1d)\n",
|
||||
inet_ntoa(d->bcast_ip),work->work_group));
|
||||
|
||||
do_announce_host(ANN_HostAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
work->work_group, 0x1d, d->bcast_ip,
|
||||
ttl,
|
||||
name, server_type, comment);
|
||||
}
|
||||
do_announce_host(ANN_HostAnnouncement,
|
||||
name , 0x00, d->myip,
|
||||
work->work_group, 0x1d, d->bcast_ip,
|
||||
ttl,
|
||||
name, server_type, comment);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "includes.h"
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
|
||||
extern struct subnet_record *subnetlist;
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "smb.h"
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
extern int global_nmb_port;
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
@ -130,14 +131,60 @@ struct subnet_record *find_subnet_all(struct in_addr bcast_ip)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
create a domain entry
|
||||
create a subnet entry
|
||||
****************************************************************************/
|
||||
static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr mask_ip, BOOL add)
|
||||
static struct subnet_record *make_subnet(struct in_addr myip, struct in_addr bcast_ip,
|
||||
struct in_addr mask_ip, BOOL add)
|
||||
{
|
||||
struct subnet_record *d;
|
||||
struct subnet_record *d = NULL;
|
||||
int nmb_sock, dgram_sock;
|
||||
|
||||
/* Check if we are creating the WINS subnet - if so don't create
|
||||
sockets, use the ClientNMB and ClientDGRAM sockets instead.
|
||||
*/
|
||||
|
||||
if(ip_equal(bcast_ip, wins_ip))
|
||||
{
|
||||
nmb_sock = -1;
|
||||
dgram_sock = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Attempt to open the sockets on port 137/138 for this interface
|
||||
* and bind them.
|
||||
* Fail the subnet creation if this fails.
|
||||
*/
|
||||
|
||||
if((nmb_sock = open_socket_in(SOCK_DGRAM, global_nmb_port,0, myip.s_addr)) == -1)
|
||||
{
|
||||
DEBUG(0,("make_subnet: Failed to open nmb socket on interface %s \
|
||||
for port %d. Error was %s\n", inet_ntoa(myip), global_nmb_port, strerror(errno)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((dgram_sock = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3, myip.s_addr)) == -1)
|
||||
{
|
||||
DEBUG(0,("make_subnet: Failed to open dgram socket on interface %s \
|
||||
for port %d. Error was %s\n", inet_ntoa(myip), DGRAM_PORT, strerror(errno)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make sure we can broadcast from these sockets. */
|
||||
set_socket_options(nmb_sock,"SO_BROADCAST");
|
||||
set_socket_options(dgram_sock,"SO_BROADCAST");
|
||||
|
||||
}
|
||||
|
||||
d = (struct subnet_record *)malloc(sizeof(*d));
|
||||
|
||||
if (!d) return(NULL);
|
||||
if (!d)
|
||||
{
|
||||
DEBUG(0,("make_subnet: malloc fail !\n"));
|
||||
close(nmb_sock);
|
||||
close(dgram_sock);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
bzero((char *)d,sizeof(*d));
|
||||
|
||||
@ -146,6 +193,9 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
|
||||
|
||||
d->bcast_ip = bcast_ip;
|
||||
d->mask_ip = mask_ip;
|
||||
d->myip = myip;
|
||||
d->nmb_sock = nmb_sock;
|
||||
d->dgram_sock = dgram_sock;
|
||||
d->workgrouplist = NULL;
|
||||
|
||||
if(add)
|
||||
@ -158,7 +208,8 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
|
||||
add a domain entry. creates a workgroup, if necessary, and adds the domain
|
||||
to the named a workgroup.
|
||||
****************************************************************************/
|
||||
static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||
static struct subnet_record *add_subnet_entry(struct in_addr myip,
|
||||
struct in_addr bcast_ip,
|
||||
struct in_addr mask_ip, char *name,
|
||||
BOOL create_subnets, BOOL add)
|
||||
{
|
||||
@ -175,7 +226,7 @@ static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
|
||||
if(create_subnets == True)
|
||||
{
|
||||
/* Create new subnets. */
|
||||
if((d = make_subnet(bcast_ip, mask_ip, add)) == NULL)
|
||||
if((d = make_subnet(myip, bcast_ip, mask_ip, add)) == NULL)
|
||||
{
|
||||
DEBUG(0,("add_subnet_entry: Unable to create subnet %s\n",
|
||||
inet_ntoa(bcast_ip) ));
|
||||
@ -265,7 +316,7 @@ void add_my_subnets(char *group)
|
||||
*/
|
||||
for (i = local_interfaces; i; i = i->next)
|
||||
{
|
||||
add_subnet_entry(i->bcast,i->nmask,group, create_subnets, True);
|
||||
add_subnet_entry(i->ip, i->bcast,i->nmask,group, create_subnets, True);
|
||||
}
|
||||
|
||||
/* If we are using WINS, then we must add the workgroup to the WINS
|
||||
@ -278,7 +329,7 @@ void add_my_subnets(char *group)
|
||||
if (lp_wins_support() || lp_wins_server())
|
||||
{
|
||||
struct in_addr wins_nmask = ipzero;
|
||||
wins_subnet = add_subnet_entry(wins_ip, wins_nmask, group, create_subnets, False);
|
||||
wins_subnet = add_subnet_entry(ipzero, wins_ip, wins_nmask, group, create_subnets, False);
|
||||
}
|
||||
|
||||
/* Ensure we only create the subnets once. */
|
||||
|
@ -503,72 +503,198 @@ void run_packet_queue()
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Create an fd_set containing all the sockets in the subnet structures,
|
||||
plus the broadcast sockets.
|
||||
***************************************************************************/
|
||||
|
||||
static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
|
||||
{
|
||||
int *sock_array = NULL;
|
||||
struct subnet_record *d = NULL;
|
||||
int count = 0;
|
||||
int num = 0;
|
||||
fd_set *pset = (fd_set *)malloc(sizeof(fd_set));
|
||||
|
||||
if(pset == NULL)
|
||||
{
|
||||
DEBUG(0,("create_listen_fdset: malloc fail !\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Check that we can add all the fd's we need. */
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
count++;
|
||||
|
||||
if((count*2) + 2 > FD_SETSIZE)
|
||||
{
|
||||
DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
|
||||
only use %d.\n", (count*2) + 2, FD_SETSIZE));
|
||||
return True;
|
||||
}
|
||||
|
||||
if((sock_array = (int *)malloc(((count*2) + 2)*sizeof(int))) == NULL)
|
||||
{
|
||||
DEBUG(0,("create_listen_fdset: malloc fail for socket array.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
FD_ZERO(pset);
|
||||
|
||||
/* Add in the broadcast socket on 137. */
|
||||
FD_SET(ClientNMB,pset);
|
||||
sock_array[num++] = ClientNMB;
|
||||
|
||||
/* Add in the 137 sockets on all the interfaces. */
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
FD_SET(d->nmb_sock,pset);
|
||||
sock_array[num++] = d->nmb_sock;
|
||||
}
|
||||
|
||||
/* Add in the broadcast socket on 138. */
|
||||
FD_SET(ClientDGRAM,pset);
|
||||
sock_array[num++] = ClientDGRAM;
|
||||
|
||||
/* Add in the 138 sockets on all the interfaces. */
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
FD_SET(d->dgram_sock,pset);
|
||||
sock_array[num++] = d->dgram_sock;
|
||||
}
|
||||
|
||||
*listen_number = (count*2) + 2;
|
||||
*ppset = pset;
|
||||
*psock_array = sock_array;
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
listens for NMB or DGRAM packets, and queues them
|
||||
***************************************************************************/
|
||||
void listen_for_packets(BOOL run_election)
|
||||
BOOL listen_for_packets(BOOL run_election)
|
||||
{
|
||||
fd_set fds;
|
||||
int selrtn;
|
||||
struct timeval timeout;
|
||||
static fd_set *listen_set = NULL;
|
||||
static int listen_number = 0;
|
||||
static int *sock_array = NULL;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(ClientNMB,&fds);
|
||||
FD_SET(ClientDGRAM,&fds);
|
||||
fd_set fds;
|
||||
int selrtn;
|
||||
struct timeval timeout;
|
||||
|
||||
/* during elections and when expecting a netbios response packet we
|
||||
need to send election packets at tighter intervals
|
||||
if(listen_set == NULL)
|
||||
{
|
||||
if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
|
||||
{
|
||||
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
ideally it needs to be the interval (in ms) between time now and
|
||||
the time we are expecting the next netbios packet */
|
||||
memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
|
||||
|
||||
timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
|
||||
timeout.tv_usec = 0;
|
||||
/* during elections and when expecting a netbios response packet we
|
||||
need to send election packets at tighter intervals
|
||||
|
||||
/* We can only take term signals when we are in the select. */
|
||||
BlockSignals(False, SIGTERM);
|
||||
selrtn = sys_select(&fds,&timeout);
|
||||
BlockSignals(True, SIGTERM);
|
||||
ideally it needs to be the interval (in ms) between time now and
|
||||
the time we are expecting the next netbios packet */
|
||||
|
||||
if (FD_ISSET(ClientNMB,&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
|
||||
if (packet)
|
||||
{
|
||||
if ((ip_equal(loopback_ip, packet->ip) ||
|
||||
ismyip(packet->ip)) &&
|
||||
packet->port == NMB_PORT)
|
||||
{
|
||||
DEBUG(7,("discarding own packet from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_packet(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
if (FD_ISSET(ClientDGRAM,&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
|
||||
if (packet)
|
||||
{
|
||||
if ((ip_equal(loopback_ip, packet->ip) ||
|
||||
ismyip(packet->ip)) &&
|
||||
packet->port == DGRAM_PORT)
|
||||
{
|
||||
DEBUG(7,("discarding own packet from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_packet(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* We can only take term signals when we are in the select. */
|
||||
BlockSignals(False, SIGTERM);
|
||||
selrtn = sys_select(&fds,&timeout);
|
||||
BlockSignals(True, SIGTERM);
|
||||
|
||||
if(selrtn > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < listen_number; i++)
|
||||
{
|
||||
if(i < (listen_number/2))
|
||||
{
|
||||
/* Processing a 137 socket. */
|
||||
if (FD_ISSET(sock_array[i],&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(sock_array[i], NMB_PACKET);
|
||||
if (packet)
|
||||
{
|
||||
|
||||
/*
|
||||
* If we got a packet on the broadcast socket check it
|
||||
* came from one of our local nets. We should only be
|
||||
* receiving broadcasts from nets we have subnets for.
|
||||
*
|
||||
* Note that this filter precludes remote announces.
|
||||
* If we need this to work we will have to add an
|
||||
* 'allow local announce' parameter that gives a
|
||||
* list of networks we will allow through the filter.
|
||||
*/
|
||||
if((sock_array[i] == ClientNMB) && (!is_local_net(packet->ip)))
|
||||
{
|
||||
DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else if ((ip_equal(loopback_ip, packet->ip) ||
|
||||
ismyip(packet->ip)) && packet->port == NMB_PORT)
|
||||
{
|
||||
DEBUG(7,("discarding own packet from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_packet(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Processing a 138 socket. */
|
||||
|
||||
if (FD_ISSET(sock_array[i],&fds))
|
||||
{
|
||||
struct packet_struct *packet = read_packet(sock_array[i], DGRAM_PACKET);
|
||||
if (packet)
|
||||
{
|
||||
/*
|
||||
* If we got a packet on the broadcast socket check it
|
||||
* came from one of our local nets. We should only be
|
||||
* receiving broadcasts from nets we have subnets for.
|
||||
*
|
||||
* Note that this filter precludes remote announces.
|
||||
* If we need this to work we will have to add an
|
||||
* 'allow local announce' parameter that gives a
|
||||
* list of networks we will allow through the filter.
|
||||
*/
|
||||
if((sock_array[i] == ClientDGRAM) && (!is_local_net(packet->ip)))
|
||||
{
|
||||
DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else if ((ip_equal(loopback_ip, packet->ip) ||
|
||||
ismyip(packet->ip)) && packet->port == DGRAM_PORT)
|
||||
{
|
||||
DEBUG(7,("discarding own packet from %s:%d\n",
|
||||
inet_ntoa(packet->ip),packet->port));
|
||||
free_packet(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_packet(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end processing 138 socket. */
|
||||
} /* end for */
|
||||
} /* end if selret > 0 */
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
@ -636,7 +762,7 @@ BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,ch
|
||||
|
||||
p.ip = dest_ip;
|
||||
p.port = DGRAM_PORT;
|
||||
p.fd = ClientDGRAM;
|
||||
p.fd = fd;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = DGRAM_PACKET;
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "includes.h"
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
|
||||
extern struct subnet_record *subnetlist;
|
||||
|
||||
|
@ -168,7 +168,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* broadcast the packet, but it comes from ipzero */
|
||||
/* broadcast the packet */
|
||||
queue_netbios_packet(d,ClientNMB,
|
||||
re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
|
||||
name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
|
||||
@ -214,45 +214,43 @@ void add_domain_logon_names(void)
|
||||
****************************************************************************/
|
||||
void add_domain_master_bcast(void)
|
||||
{
|
||||
struct subnet_record *d;
|
||||
struct subnet_record *d;
|
||||
|
||||
if (!lp_domain_master()) return;
|
||||
if (!lp_domain_master()) return;
|
||||
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
|
||||
for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
|
||||
{
|
||||
struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
|
||||
|
||||
if (work && work->dom_state == DOMAIN_NONE)
|
||||
{
|
||||
struct nmb_name n;
|
||||
make_nmb_name(&n,myworkgroup,0x1b,scope);
|
||||
if (work && work->dom_state == DOMAIN_NONE)
|
||||
{
|
||||
struct nmb_name n;
|
||||
make_nmb_name(&n,myworkgroup,0x1b,scope);
|
||||
|
||||
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||
{
|
||||
DEBUG(0,("%s add_domain_names: attempting to become domain \
|
||||
master browser on workgroup %s %s\n",
|
||||
timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
|
||||
if (!find_name(d->namelist, &n, FIND_SELF))
|
||||
{
|
||||
DEBUG(0,("%s add_domain_names: attempting to become domain \
|
||||
master browser on workgroup %s %s\n", timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
|
||||
|
||||
/* send out a query to establish whether there's a
|
||||
domain controller on the local subnet. if not,
|
||||
we can become a domain controller. it's only
|
||||
polite that we check, before claiming the
|
||||
NetBIOS name 0x1b.
|
||||
*/
|
||||
/* send out a query to establish whether there's a
|
||||
domain controller on the local subnet. if not,
|
||||
we can become a domain controller. it's only
|
||||
polite that we check, before claiming the
|
||||
NetBIOS name 0x1b.
|
||||
*/
|
||||
|
||||
DEBUG(0,("add_domain_names:querying subnet %s \
|
||||
for domain master on workgroup %s\n",
|
||||
inet_ntoa(d->bcast_ip), myworkgroup));
|
||||
DEBUG(0,("add_domain_names:querying subnet %s \
|
||||
for domain master on workgroup %s\n", inet_ntoa(d->bcast_ip), myworkgroup));
|
||||
|
||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
||||
NAME_QUERY_DOMAIN,
|
||||
myworkgroup, 0x1b,
|
||||
0, 0,0,NULL,NULL,
|
||||
True, False,
|
||||
d->bcast_ip, d->bcast_ip, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
queue_netbios_packet(d,ClientNMB,NMB_QUERY,
|
||||
NAME_QUERY_DOMAIN,
|
||||
myworkgroup, 0x1b,
|
||||
0, 0,0,NULL,NULL,
|
||||
True, False,
|
||||
d->bcast_ip, d->bcast_ip, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -806,7 +806,8 @@ void response_netbios_packet(struct packet_struct *p)
|
||||
struct subnet_record *d = NULL;
|
||||
|
||||
if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
|
||||
DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
|
||||
DEBUG(2,("unknown netbios response id %d (received late or from nmblookup?)\n",
|
||||
nmb->header.name_trn_id));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,9 @@ pstring servicesf = CONFIGFILE;
|
||||
|
||||
extern pstring scope;
|
||||
|
||||
int ClientNMB = -1;
|
||||
int ClientDGRAM = -1;
|
||||
int ClientNMB = -1;
|
||||
int ClientDGRAM = -1;
|
||||
int global_nmb_port = -1;
|
||||
|
||||
extern pstring myhostname;
|
||||
static pstring host_file;
|
||||
@ -302,7 +303,8 @@ static void process(void)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
run_election = check_elections();
|
||||
listen_for_packets(run_election);
|
||||
if(listen_for_packets(run_election))
|
||||
return;
|
||||
|
||||
run_packet_queue();
|
||||
run_elections(t);
|
||||
@ -338,12 +340,19 @@ static BOOL open_sockets(BOOL isdaemon, int port)
|
||||
return False;
|
||||
}
|
||||
|
||||
/* The sockets opened here will be used to receive broadcast
|
||||
packets *only*. Interface specific sockets are opened in
|
||||
make_subnet() in namedbsubnet.c. Thus we bind to the
|
||||
address "0.0.0.0". The parameter 'socket address' is
|
||||
now deprecated.
|
||||
*/
|
||||
|
||||
if (isdaemon)
|
||||
ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
|
||||
ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0);
|
||||
else
|
||||
ClientNMB = 0;
|
||||
|
||||
ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
|
||||
ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0);
|
||||
|
||||
if (ClientNMB == -1)
|
||||
return(False);
|
||||
@ -353,7 +362,7 @@ static BOOL open_sockets(BOOL isdaemon, int port)
|
||||
set_socket_options(ClientNMB,"SO_BROADCAST");
|
||||
set_socket_options(ClientDGRAM,"SO_BROADCAST");
|
||||
|
||||
DEBUG(3,("Sockets opened.\n"));
|
||||
DEBUG(3,("open_sockets: Broadcast sockets opened.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -460,12 +469,12 @@ static void usage(char *pname)
|
||||
**************************************************************************/
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
int port = NMB_PORT;
|
||||
int opt;
|
||||
extern FILE *dbf;
|
||||
extern char *optarg;
|
||||
char pidFile[100] = { 0 };
|
||||
|
||||
global_nmb_port = NMB_PORT;
|
||||
*host_file = 0;
|
||||
|
||||
StartupTime = time(NULL);
|
||||
@ -537,7 +546,7 @@ static void usage(char *pname)
|
||||
DEBUGLEVEL = atoi(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
global_nmb_port = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
@ -618,9 +627,9 @@ static void usage(char *pname)
|
||||
}
|
||||
|
||||
|
||||
DEBUG(3,("Opening sockets %d\n", port));
|
||||
DEBUG(3,("Opening sockets %d\n", global_nmb_port));
|
||||
|
||||
if (!open_sockets(is_daemon,port)) return 1;
|
||||
if (!open_sockets(is_daemon,global_nmb_port)) return 1;
|
||||
|
||||
load_interfaces();
|
||||
add_my_subnets(myworkgroup);
|
||||
|
@ -24,9 +24,6 @@
|
||||
#define REPLACE_GETPASS
|
||||
#include "includes.h"
|
||||
|
||||
extern int ClientNMB;
|
||||
extern int ClientDGRAM;
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
|
||||
extern pstring myname;
|
||||
|
Loading…
Reference in New Issue
Block a user