.cvsignore: Added make_smbcodepage
authorJeremy Allison <jra@samba.org>
Fri, 17 Oct 1997 23:08:07 +0000 (23:08 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 17 Oct 1997 23:08:07 +0000 (23:08 +0000)
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 used to be commit 6904c2de080b2a9702800e9e4126386ced20569d)

16 files changed:
source3/.cvsignore
source3/include/nameserv.h
source3/include/proto.h
source3/lib/interface.c
source3/lib/util.c
source3/locking/locking.c
source3/nameannounce.c
source3/namedbresp.c
source3/namedbserver.c
source3/namedbsubnet.c
source3/namepacket.c
source3/nameresp.c
source3/nameserv.c
source3/nameservresp.c
source3/nmbd/nmbd.c
source3/nmbsync.c

index 9b7ea034be99c5382ea765149ad8ef6426e7a40e..f6b77ee2f96eaa5c1d5bfb6037c31faf87f2b972 100644 (file)
@@ -1,6 +1,7 @@
 Makefile.RPM
 makefile
 makefile.sunos5
+make_smbcodepage
 nmbd
 nmblookup
 smbclient
index 81487e9ce9ab500093d944fd28328e74cabcb2c7..ecd19b9563475777cdfed493af4cb327c847c536 100644 (file)
@@ -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 */
index 85ef0943400d77a36e23e29af5fc9d7d95ad326d..fa689d1c90f24c7a508201a3b092d08f1c705451 100644 (file)
@@ -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);
index 1dc605ff2fd6546bc58024d32c99a4010ca4eac0..c920cc0cfcf81288bca5eb3f0f8ca7fc2fe544e8 100644 (file)
@@ -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
   **************************************************************************/
index a82713a0d84c44ab3bc0204e96c58f8e8f88190c..b69b30d20cd2b4f97b33c4783c08e6d2b33b202c 100644 (file)
@@ -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)
index 5071121bed0fd41db7f95ec665b975d9bb4a886f..bbc0c0033fffc7d5470fc5585cd6cade70754f29 100644 (file)
@@ -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.
 ********************************************************************/
index d69ee32ddf7b6fb01198f47c9f77088ef5af197b..b8dcb71fffd677c05a92ce6427594f745bf78ec5 100644 (file)
@@ -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);
-
-    if(wins_iface)
-    {
-      DEBUG(0,("announce_server: error - announcement requested on WINS \
+  /* 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 \
 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));
+  /* 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);
+    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));
+    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);
-       }
+    /* 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);
+  }
 }
 
 /****************************************************************************
index c8a31a6c79be0d810dccd6d5901c109ae67a2caa..e9fe39c3d7383c7bc55623f0b2e1cb329b588a16 100644 (file)
@@ -25,7 +25,6 @@
 #include "includes.h"
 
 extern int ClientNMB;
-extern int ClientDGRAM;
 
 extern struct subnet_record *subnetlist;
 
index 9223cb6ce6a4667a716becbd8a7ae3ac774103ae..7440b42494a1438ebfd979a250c8112cb8d6fdcc 100644 (file)
@@ -32,7 +32,6 @@
 #include "smb.h"
 
 extern int ClientNMB;
-extern int ClientDGRAM;
 
 extern int DEBUGLEVEL;
 
index c6663d71fd472077ad724a2a34260e5bb81bbc5b..3597c3238751e51defe370c78ae5e86b8fb5fbea 100644 (file)
@@ -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. */
index 4a9f586a762d29b5cad0c04da88d10f7f58e54cf..55c850f25443dc6748c7b71f42074970dbe0c0b4 100644 (file)
@@ -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;
 
index 2e625735c49336c6547e479c655ea140ee6dded0..81624fcaf1b30910fc5ac4754ca871964d085db4 100644 (file)
@@ -25,7 +25,6 @@
 #include "includes.h"
 
 extern int ClientNMB;
-extern int ClientDGRAM;
 
 extern struct subnet_record *subnetlist;
 
index bc37d1c424eff1da9a3cc7345e3f5bbc8235e93d..a90b41f834cd792053aa094c13026b98868758ab 100644 (file)
@@ -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;
-
-       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);
-
-               if (work && work->dom_state == DOMAIN_NONE)
-               {
-                       struct nmb_name n;
-                       make_nmb_name(&n,myworkgroup,0x1b,scope);
+  struct subnet_record *d;
 
-                       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 (!lp_domain_master()) return;
 
-                               /* 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.
-                               */
+  for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
+  { 
+    struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
 
-                               DEBUG(0,("add_domain_names:querying subnet %s \
-for domain master on workgroup %s\n", 
-                                                 inet_ntoa(d->bcast_ip), myworkgroup));
+    if (work && work->dom_state == DOMAIN_NONE)
+    {
+      struct nmb_name n;
+      make_nmb_name(&n,myworkgroup,0x1b,scope);
 
-                               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);
-                       }
-               }
-       }
+      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.
+         */
+
+        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);
+      }
+    }
+  }
 }
 
 
index deb56c0850e2b09eb125679b392cc7e1bc920fdc..61e4a835f46eb7a63be8f3fc29174b42a0c38c8d 100644 (file)
@@ -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;
   }
 
index c7af54fa13b4b5a723f53bb51649d3ddabff599f..047284832f01f024f975b70311c9524d5f930a83 100644 (file)
@@ -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);
index de2f7aa00f1bcaaa6740727464500f97ee27d435..34d309d00322b508a5750a674c00a4f920881d98 100644 (file)
@@ -24,9 +24,6 @@
 #define REPLACE_GETPASS
 #include "includes.h"
 
-extern int ClientNMB;
-extern int ClientDGRAM;
-
 extern int DEBUGLEVEL;
 
 extern pstring myname;