Large changes from jra@cygnus.com. Mainly browser updates.
authorSamba Release Account <samba-bugs@samba.org>
Wed, 9 Apr 1997 01:19:25 +0000 (01:19 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Wed, 9 Apr 1997 01:19:25 +0000 (01:19 +0000)
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.

23 files changed:
source/include/includes.h
source/include/nameserv.h
source/include/proto.h
source/lib/access.c
source/lib/interface.c
source/lib/util.c
source/nameannounce.c
source/namebrowse.c
source/namedbname.c
source/namedbresp.c
source/namedbsubnet.c
source/namedbwork.c
source/nameelect.c
source/namelogon.c
source/namepacket.c
source/nameresp.c
source/nameserv.c
source/nameservreply.c
source/nameservresp.c
source/namework.c
source/nmbd/nmbd.c
source/nmbsync.c
source/param/loadparm.c

index a8653d09788ccf97b03b37e1c8bd1f02bfd5f697..249e4940a917f0e906e8f838fcef247d5249267a 100644 (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>
index 027931f9e632aab9db8a77b6d834a51fbf58e40d..17ae085bc62f4cbb29af224c668f904673d3fc02 100644 (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
index bbfcad78f94d00d2f542a2994fd17a104ba008e2..cfc05c1c6b48c8e0229d31240babaa22a1ceb974 100644 (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  */
 
index 31a48d09d3cc9192ddfce98f8a1077707bcccdd3..599cb5ca7e390df9843ddc1db989930c697bebde 100644 (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;
index 1c41293cf77314d950557aef16bdcd21d26936d1..0e2a13e7b93cc38bfa6789f784bd761f41fcd89c 100644 (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 */
index 643c2fb7a501c0bb3c82066ccc225d1d02e08198..53b24173d51228e7e1e9d9e711603c81375633dc 100644 (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;
 }
 
index 8dc0668f4eda28c5f4fb14499a821b6a150aa791..a1eae127a2a2718e8fce3dd66091332dbaa7ee1a 100644 (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,24 +309,24 @@ void announce_host(time_t t)
     {
       struct work_record *work;
       
-      if (ip_equal(d->bcast_ip, ipgrp)) continue;
-
+      if (ip_equal(d->bcast_ip, wins_ip)) continue;
+      
       for (work = d->workgrouplist; work; work = work->next)
        {
          uint32 stype = work->ServerType;
          struct server_record *s;
          BOOL announce = False;
          
-      /* must work on the code that does announcements at up to
-         30 seconds later if a master browser sends us a request
-         announce.
-       */
+         /* must work on the code that does announcements at up to
+            30 seconds later if a master browser sends us a request
+            announce.
+            */
 
          if (work->needannounce) {
            /* drop back to a max 3 minute announce - this is to prevent a
               single lost packet from stuffing things up for too long */
            work->announce_interval = MIN(work->announce_interval,
-                                               CHECK_TIME_MIN_HOST_ANNCE*60);
+                                         CHECK_TIME_MIN_HOST_ANNCE*60);
            work->lastannounce_time = t - (work->announce_interval+1);
          }
          
@@ -339,7 +339,7 @@ void announce_host(time_t t)
            work->announce_interval += 60;
          
          work->lastannounce_time = t;
-
+         
          for (s = work->serverlist; s; s = s->next) {
            if (strequal(myname, s->serv.name)) { 
              announce = True; 
@@ -353,18 +353,18 @@ void announce_host(time_t t)
          }
          
          if (work->needannounce)
-         {
+           {
              work->needannounce = False;
              break;
              /* sorry: can't do too many announces. do some more later */
-         }
+           }
        }
-  }
+    }
 }
 
 
 /****************************************************************************
-  announce myself as a master to all other primary domain conrollers.
+  announce myself as a master to all other domain master browsers.
 
   this actually gets done in search_and_sync_workgroups() via the
   NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
@@ -393,86 +393,77 @@ void announce_master(time_t t)
            }
        }
     }
-  
+  DEBUG(4,( "announce_master: am_master = %d for workgroup %s\n", am_master, lp_workgroup()));
+
   if (!am_master) return; /* only proceed if we are a master browser */
   
+  /* Note that we don't do this if we are domain master browser. */
+
   for (d = subnetlist; d; d = d->next)
     {
-      struct work_record *work;
-      for (work = d->workgrouplist; work; work = work->next)
-       {
-         struct server_record *s;
-         for (s = work->serverlist; s; s = s->next)
-           {
-             if (strequal(s->serv.name, myname)) continue;
-             
-             /* all DOMs (which should also be master browsers) */
-             if (s->serv.type & SV_TYPE_DOMAIN_CTRL)
-               {
-                 /* check the existence of a pdc for this workgroup, and if
-                    one exists at the specified ip, sync with it and announce
-                    ourselves as a master browser to it */
-                 
-                 if (!*lp_domain_controller() ||
-                     !strequal(lp_domain_controller(), s->serv.name))
-                   {
-                     if (!lp_wins_support() && *lp_wins_server())
-                       {
-                         queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
-                                                NAME_QUERY_DOM_SRV_CHK,
-                                                work->work_group,0x1b,0,0,0,NULL,NULL,
-                                                False, False, ipzero, ipzero);
-                       }
-                     else
-                       {
-                         struct subnet_record *d2;
-                         for (d2 = subnetlist; d2; d2 = d2->next)
-                           {
-                             queue_netbios_packet(d,ClientNMB,NMB_QUERY,
-                                                  NAME_QUERY_DOM_SRV_CHK,
-                                                  work->work_group,0x1b,0,0,0,NULL,NULL,
-                                                  True, False, d2->bcast_ip, d2->bcast_ip);
-                           }
-                       }
-                   }
-               }
-           }
-         
-         /* now do primary domain controller - the one that's not
-            necessarily in our browse lists, although it ought to be
-            this pdc is the one that we get TOLD about through smb.conf.
-            basically, if it's on a subnet that we know about, it may end
-            up in our browse lists (which is why it's explicitly excluded
-            in the code above) */
-         
-         if (*lp_domain_controller())
-           {
-             struct in_addr ip;
-             BOOL bcast = False;
-             
-             ip = *interpret_addr2(lp_domain_controller());
-             
-             if (zero_ip(ip)) {
-               ip = d->bcast_ip;
-               bcast = True;
-             }
-
-             DEBUG(2, ("Searching for DOM %s at %s\n",
-                       lp_domain_controller(), inet_ntoa(ip)));
-             
-             /* check the existence of a pdc for this workgroup, and if
-                one exists at the specified ip, sync with it and announce
-                ourselves as a master browser to it */
-             queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
-                                    work->work_group,0x1b,0,0,0,NULL,NULL,
-                                    bcast, False, ip, ip);
+      /* Try and find our workgroup on this subnet */
+      struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
+
+      if (work)
+        {
+          char *name;
+          int   type;
+
+          if (*lp_domain_controller())
+            {
+              /* the domain controller option is used to manually specify
+                 the domain master browser to sync with
+               */
+
+              /* XXXX i'm not sure we should be using the domain controller
+                 option for this purpose.
+               */
+
+              name = lp_domain_controller();
+              type = 0x20;
+            }
+          else
+            {
+              /* assume that the domain master browser we want to sync
+                 with is our own domain.
+               */
+              name = work->work_group;
+              type = 0x1b;
+            }
+
+          /* check the existence of a dmb for this workgroup, and if
+             one exists at the specified ip, sync with it and announce
+             ourselves as a master browser to it
+           */
+
+          if (!lp_wins_support() && *lp_wins_server() &&
+               ip_equal(d->bcast_ip, wins_ip))
+            {
+              DEBUG(4, ("Local Announce: find %s<%02x> from WINS server %s\n",
+                         name, type, lp_wins_server()));
+
+              queue_netbios_pkt_wins(d,ClientNMB,
+                        NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
+                        name, type, 0,0,0,
+                        work->work_group,NULL,
+                        False, False, ipzero, ipzero);
+            }
+          else
+            {
+              DEBUG(4, ("Local Announce: find %s<%02x> on %s\n",
+                name, type, inet_ntoa(d->bcast_ip)));
+
+              queue_netbios_packet(d,ClientNMB,
+                         NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
+                         name, type, 0,0,0,
+                         work->work_group,NULL,
+                         True, False, d->bcast_ip, d->bcast_ip);
            }
        }
     }
 }
 
-
-
 /****************************************************************************
   do all the "remote" announcements. These are used to put ourselves
   on a remote browse list. They are done blind, no checking is done to
index 3bc4f9f82aa1f66b103c5f2a2bbc759fe09b28e4..b87ea9fec3439ceffa3391c1737e5ea18004913a 100644 (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,21 +167,48 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
   struct subnet_record *d;
   struct work_record *work;
 
-  if (!(d = find_subnet(b->ip))) return;
+  /* Look for the workgroup first on the local subnet. If this
+     fails try WINS - we may need to sync with the domain master,
+     or we may be the domain master and need to sync with subnet
+     masters.
+  */
+
+  if (!(d = find_subnet_all(b->ip))) {
+    DEBUG(0, ("start_sync_browse_entry: failed to get a \
+subnet for a browse cache entry workgroup %s, server %s\n", 
+                  b->group, b->name));
+    return;
+  }
 
-  if (!(work = find_workgroupstruct(d, b->group, False))) return;
+  if (!(work = find_workgroupstruct(d, b->group, False))) {
+      DEBUG(0, ("start_sync_browse_entry: failed to get a \
+workgroup for a browse cache entry workgroup %s, server %s\n", 
+               b->group, b->name));
+      return;
+  }
 
-  /* only sync if we are the master */
-  if (AM_MASTER(work)) {
+  /* only sync if we are a subnet master or domain master - but
+     we sync if we are a master for this workgroup on *any* 
+     of our interfaces. */
+  if (AM_MASTER(work) || AM_DOMMST(work) || AM_ANY_MASTER(work)) {
 
-      /* first check whether the group we intend to sync with exists. if it
-         doesn't, the server must have died. o dear. */
+    DEBUG(4, ("start_sync_browse_entry: Initiating %s sync with %s<0x20>, \
+workgroup %s\n",
+               b->local ? "local" : "remote", b->name, b->group));
 
-      /* see response_netbios_packet() or expire_netbios_response_entries() */
-      queue_netbios_packet(d,ClientNMB,NMB_QUERY,
-                       b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
-                                          b->group,0x20,0,0,0,NULL,NULL,
-                                          False,False,b->ip,b->ip);
+    /* first check whether the server we intend to sync with exists. if it
+       doesn't, the server must have died. o dear. */
+
+    /* see response_netbios_packet() or expire_netbios_response_entries() */
+    /* We cheat here by using the my_comment field of the response_record 
+       struct as the workgroup name we are going to do the sync for. 
+       This is because the reply packet doesn't include the workgroup, but 
+       we need it when the reply comes back.
+    */
+    queue_netbios_packet(d,ClientNMB,NMB_QUERY,
+                        b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
+                        b->name,0x20,0,0,0,NULL,b->group,
+                        False,False,b->ip,b->ip);
   }
 
   b->synced = True;
@@ -195,10 +223,14 @@ void do_browser_lists(time_t t)
   struct browse_cache_record *b;
   static time_t last = 0;
   
-  if (t-last < 20) return; /* don't do too many of these at once! */
+  if (t-last < 20) 
+   {
+     DEBUG(9,("do_browser_lists: returning due to t(%d) - last(%d) < 20\n",
+             t, last));
+     return; /* don't do too many of these at once! */
                            /* XXXX equally this period should not be too long
                               the server may die in the intervening gap */
-  
+   } 
   last = t;
   
   /* pick any entry in the list, preferably one whose time is up */
@@ -210,9 +242,15 @@ void do_browser_lists(time_t t)
   if (b && !b->synced)
   {
     /* sync with the selected entry then remove some dead entries */
+    DEBUG(4,("do_browser_lists: Initiating sync with %s, workgroup %s\n",
+              b->name, b->group));
     start_sync_browse_entry(b);
     expire_browse_cache(t - 60);
   }
+  else
+  {
+    DEBUG(9, ("do_browser_lists: no entries to sync.\n"));
+  }
 
 }
 
index 2e8c8d589ae38dce93e6e71bc0e3af5b4c2f79b4..d27bcf81586f566c89fe6c19406500b5b84dbf6b 100644 (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;
 }
 
@@ -172,27 +173,27 @@ struct name_record *find_name_search(struct subnet_record **d,
                        struct nmb_name *name,
                        int search, struct in_addr ip)
 {
-       if (d == NULL) return NULL; /* bad error! */
+  if (d == NULL) return NULL; /* bad error! */
        
-    if (search & FIND_LOCAL) {
-      if (*d != NULL) {
-       struct name_record *n = find_name((*d)->namelist, name, search);
-       DEBUG(4,("find_name on local: %s %s search %x\n",
-                namestr(name),inet_ntoa(ip), search));
-       if (n) return n;
-      }
+  if (search & FIND_LOCAL) {
+    if (*d != NULL) {
+      struct name_record *n = find_name((*d)->namelist, name, search);
+      DEBUG(4,("find_name on local: %s %s search %x\n",
+              namestr(name),inet_ntoa(ip), search));
+      if (n) return n;
     }
+  }
 
-    if (!(search & FIND_WINS)) return NULL;
+  if (!(search & FIND_WINS)) return NULL;
 
-    /* find WINS subnet record. */
-    *d = find_subnet(ipgrp);
-    
-    if (*d == NULL) return NULL;
-    
-    DEBUG(4,("find_name on WINS: %s %s search %x\n",
-            namestr(name),inet_ntoa(ip), search));
-    return find_name((*d)->namelist, name, search);
+  /* find WINS subnet record. */
+  *d = find_subnet(wins_ip);
+  
+  if (*d == NULL) return NULL;
+  
+  DEBUG(4,("find_name on WINS: %s %s search %x\n",
+          namestr(name),inet_ntoa(ip), search));
+  return find_name((*d)->namelist, name, search);
 }
 
 
@@ -245,7 +246,7 @@ void dump_names(void)
         }
                DEBUG(4,("\n"));
 
-      if (f && ip_equal(d->bcast_ip, ipgrp) && n->source == REGISTER)
+      if (f && ip_equal(d->bcast_ip, wins_ip) && n->source == REGISTER)
       {
       /* XXXX i have little imagination as to how to output nb_flags as
          anything other than as a hexadecimal number :-) */
@@ -281,7 +282,7 @@ void dump_names(void)
   ****************************************************************************/
 void load_netbios_names(void)
 {
-  struct subnet_record *d = find_subnet(ipgrp);
+  struct subnet_record *d = find_subnet(wins_ip);
   fstring fname;
 
   FILE *f;
@@ -466,8 +467,9 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
   
   if (!n2) add_name(d,n);
 
-  DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x\n",
-               namestr(&n->name),inet_ntoa(ip),ttl,nb_flags));
+  DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x to interface %s\n",
+          namestr(&n->name),inet_ntoa(ip),ttl,nb_flags,
+          ip_equal(d->bcast_ip, wins_ip) ? "WINS" : inet_ntoa(d->bcast_ip)));
 
   return(n);
 }
@@ -520,7 +522,7 @@ struct name_record *dns_name_search(struct nmb_name *question, int Time)
        char *r;
        BOOL dns_type = (name_type == 0x20 || name_type == 0);
        struct in_addr dns_ip;
-       struct subnet_record *d = find_subnet(ipgrp);
+       struct subnet_record *d = find_subnet(wins_ip);
 
        if (d == NULL) return NULL;
 
index d89bfe8ae843bbd042faf8dffdaf8ee895c9a87b..6755de6534b620cb4a1bc3e3adda49a098edc649 100644 (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 */
index 367179b6c613c6b19a316d8fc401011c7f727cd8..144729e1e17dc3eb98cbeca528cb5d1f102cf4ef 100644 (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,31 +86,30 @@ static void add_subnet(struct subnet_record *d)
 struct subnet_record *find_subnet(struct in_addr bcast_ip)
 {   
   struct subnet_record *d;
-  struct in_addr wins_ip = ipgrp;
   
   /* search through subnet list for broadcast/netmask that matches
      the source ip address. a subnet 255.255.255.255 represents the
      WINS list. */
   
-       for (d = subnetlist; d; d = d->next)
+  for (d = subnetlist; d; d = d->next)
     {
-        if (ip_equal(bcast_ip, wins_ip))
+      if (ip_equal(bcast_ip, wins_ip))
+       {
+         if (ip_equal(bcast_ip, d->bcast_ip))
            {
-                       if (ip_equal(bcast_ip, d->bcast_ip))
-                       {
-                               return d;
-                       }
+             return d;
+           }
         }
-        else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
+      else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
+       {
+         if (!ip_equal(d->bcast_ip, wins_ip))
            {
-                       if (!ip_equal(d->bcast_ip, wins_ip))
-                       {
-                               return d;
-                       }
+             return d;
            }
+       }
     }
   
-       return (NULL);
+  return (NULL);
 }
 
 
@@ -122,9 +126,19 @@ struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
     return find_subnet(*iface_bcast(ip));
   }
   /* find the subnet under the pseudo-ip of 255.255.255.255 */
-  return find_subnet(ipgrp);
+  return find_subnet(wins_ip);
 }
 
+/****************************************************************************
+  find a subnet in the subnetlist - if the subnet is not found
+  then return the WINS subnet.
+  **************************************************************************/
+struct subnet_record *find_subnet_all(struct in_addr bcast_ip)
+{
+  struct subnet_record *d = find_subnet(bcast_ip);
+  if(!d)
+    return find_subnet( wins_ip);
+}
 
 /****************************************************************************
   create a domain entry
@@ -157,24 +171,24 @@ static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr
   ****************************************************************************/
 void add_subnet_interfaces(void)
 {
-       struct interface *i;
+  struct interface *i;
 
-       /* loop on all local interfaces */
-       for (i = local_interfaces; i; i = i->next)
+  /* loop on all local interfaces */
+  for (i = local_interfaces; i; i = i->next)
+    {
+      /* add the interface into our subnet database */
+      if (!find_subnet(i->bcast))
        {
-               /* add the interface into our subnet database */
-               if (!find_subnet(i->bcast))
-               {
-                 make_subnet(i->bcast,i->nmask);
-               }
+         make_subnet(i->bcast,i->nmask);
        }
+    }
 
-       /* add the pseudo-ip interface for WINS: 255.255.255.255 */
-       if (lp_wins_support() || (*lp_wins_server()))
+  /* add the pseudo-ip interface for WINS: 255.255.255.255 */
+  if (lp_wins_support() || (*lp_wins_server()))
     {
-               struct in_addr wins_bcast = ipgrp;
-               struct in_addr wins_nmask = ipzero;
-               make_subnet(wins_bcast, wins_nmask);
+      struct in_addr wins_bcast = wins_ip;
+      struct in_addr wins_nmask = ipzero;
+      make_subnet(wins_bcast, wins_nmask);
     }
 }
 
@@ -205,7 +219,7 @@ void add_my_subnets(char *group)
   add a domain entry. creates a workgroup, if necessary, and adds the domain
   to the named a workgroup.
   ****************************************************************************/
-struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
+static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip, 
                                       struct in_addr mask_ip,
                                       char *name, BOOL add, BOOL lmhosts)
 {
@@ -215,7 +229,7 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
      in the DEBUG comment. i assume that the DEBUG comment below actually
      intends to refer to bcast_ip? i don't know.
 
-  struct in_addr ip = ipgrp;
+  struct in_addr ip = wins_ip;
 
   */
 
@@ -223,6 +237,8 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
     bcast_ip = *iface_bcast(bcast_ip);
   
   /* add the domain into our domain database */
+  /* Note that we never add into the WINS subnet as add_subnet_entry
+     is only called to add our local interfaces. */
   if ((d = find_subnet(bcast_ip)) ||
       (d = make_subnet(bcast_ip, mask_ip)))
     {
index 0cfc47c41a8a80d92b9be114a004bc5290931aab..80a670fea84e8d36d4f8ea034144c20bf25782fb 100644 (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;
+}                
index c33206083ecff71d179ffc0e186bda7ae2975c79..a11d0fb786775978595a946f612f352457d964a3 100644 (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;
index 3fab49cedd618e95f4e6c2dabe56a55f1c3fa9a4..1ea09ee2bb62a500d5364836c3421d74cd7b12ad 100644 (file)
@@ -47,104 +47,114 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len)
 {
   struct dgram_packet *dgram = &p->packet.dgram;
   struct in_addr ip = dgram->header.source_ip;
-  struct subnet_record *d = find_subnet(ip);
+  struct subnet_record *d = find_subnet_all(ip);
   char *logname,*q;
   fstring reply_name;
   BOOL add_slashes = False;
   pstring outbuf;
   int code,reply_code;
   struct work_record *work;
-       char   unknown_byte = 0;
-       uint16 request_count = 0;
-       uint16 token = 0;
+  char   unknown_byte = 0;
+  uint16 request_count = 0;
+  uint16 token = 0;
   
-  if (!d) return;
-  
-       if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) return;
+  if (!lp_domain_logons())
+    {
+      DEBUG(3,("No domain logons\n"));
+      return;
+    }
   
-       if (!lp_domain_logons())
-       {
-    DEBUG(3,("No domain logons\n"));
-    return;
-  }
+  if (!d) 
+    {
+      DEBUG(0,("process_logon_packet: Cannot find subnet for logon request from %s\n",
+                inet_ntoa(p->ip)  ));
+      return;
+    }
   
-  code = SVAL(buf,0);
-       switch (code)
-       {
-  case 0:    
+  if (!(work = find_workgroupstruct(d,dgram->dest_name.name, False))) 
     {
-      char *machine = buf+2;
-      char *user = skip_string(machine,1);
-                       char *tmp;
-      logname = skip_string(user,1);
-                       tmp = skip_string(logname,1);
-                       unknown_byte = CVAL(tmp,0);
-                       request_count = SVAL(tmp,1);
-                       token = SVAL(tmp,3);
-
-                       reply_code = 0x6;
-      strcpy(reply_name,myname); 
-      strupper(reply_name);
-      add_slashes = True;
-                       DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
-                                         machine,inet_ntoa(p->ip),user,token));
-    break;
-               }
-  case 7:    
+      DEBUG(0,("process_logon_packet: Cannot find WORKGROUP %s for logon request fomr %s\n",
+                dgram->dest_name.name, inet_ntoa(p->ip) ));
+      return;
+    }
+  code = SVAL(buf,0);
+  switch (code)
     {
-      char *machine = buf+2;
-      logname = skip_string(machine,1);
-                       token = SVAL(skip_string(logname,1),0);
-
-      strcpy(reply_name,lp_domain_controller()); 
-                       if (!*reply_name)
-                       {
-                               /* oo! no domain controller. must be us, then */
+    case 0:    
+      {
+       char *machine = buf+2;
+       char *user = skip_string(machine,1);
+       char *tmp;
+       logname = skip_string(user,1);
+       tmp = skip_string(logname,1);
+       unknown_byte = CVAL(tmp,0);
+       request_count = SVAL(tmp,1);
+       token = SVAL(tmp,3);
+       
+       reply_code = 0x6;
        strcpy(reply_name,myname); 
-        reply_code = 0xC;
+       strupper(reply_name);
+       add_slashes = True;
+       DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
+                machine,inet_ntoa(p->ip),user,token));
+       break;
+      }
+    case 7:    
+      {
+       char *machine = buf+2;
+       logname = skip_string(machine,1);
+       token = SVAL(skip_string(logname,1),0);
+       
+       strcpy(reply_name,lp_domain_controller()); 
+       if (!*reply_name)
+         {
+           /* oo! no domain controller. must be us, then */
+           strcpy(reply_name,myname); 
+           reply_code = 0xC;
+         }
+       else
+         {
+           /* refer logon request to the domain controller */
+           reply_code = 0x7;
+         }
+
+       strupper(reply_name);
+       DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
+                machine,inet_ntoa(p->ip), reply_name, reply_code,token));
+       break;
+      }
+    default:
+      {
+       DEBUG(3,("Unknown domain request %d\n",code));
+       return;
       }
-                       else
-                       {
-                               /* refer logon request to the domain controller */
-                               reply_code = 0x7;
     }
-
-                       strupper(reply_name);
-                       DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
-                                 machine,inet_ntoa(p->ip), reply_name, reply_code,token));
-    break;
-               }
-  default:
-               {
-    DEBUG(3,("Unknown domain request %d\n",code));
-    return;
-  }
-       }
   
   bzero(outbuf,sizeof(outbuf));
   q = outbuf;
   SSVAL(q,0,reply_code);
   q += 2;
-
-       if (token == 0xffff || /* LM 2.0 or later */
-           token == 0xfffe) /* WfWg networking */
+  
+  if (token == 0xffff || /* LM 2.0 or later */
+      token == 0xfffe) /* WfWg networking */
+    {
+      if (add_slashes)
        {
-               if (add_slashes)
-               {
-    strcpy(q,"\\\\");
-    q += 2;
-  }
-               strcpy(q, reply_name); 
-               strupper(q);
-  q = skip_string(q,1);
-
-               if (token == 0xffff) /* LM 2.0 or later */
-   {
-                       SSVAL(q,0,token);
-   q += 2;
-  }
+         strcpy(q,"\\\\");
+         q += 2;
        }
-
+      strcpy(q, reply_name); 
+      strupper(q);
+      q = skip_string(q,1);
+      
+      if (token == 0xffff) /* LM 2.0 or later */
+       {
+         SSVAL(q,0,token);
+         q += 2;
+       }
+    }
+  
   SSVAL(q,0,0xFFFF);
   q += 2;
   
index 043e2c02f0fdd3b5c5766fc2284ca47771434b47..09ee5dd79e2476eb9daf2ad7d044c32aa7673ffa 100644 (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;
 
@@ -91,9 +91,9 @@ static void update_name_trn_id(void)
   initiate a netbios packet
   ****************************************************************************/
 void initiate_netbios_packet(uint16 *id,
-                               int fd,int quest_type,char *name,int name_type,
-                           int nb_flags,BOOL bcast,BOOL recurse,
-                           struct in_addr to_ip)
+                            int fd,int quest_type,char *name,int name_type,
+                            int nb_flags,BOOL bcast,BOOL recurse,
+                            struct in_addr to_ip)
 {
   struct packet_struct p;
   struct nmb_packet *nmb = &p.packet.nmb;
@@ -323,8 +323,10 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *n)
   struct subnet_record *d;
   struct name_record *n1;
 
+  /* We explicitly don't search WINS here - this will be done
+     in find_name_search is it was a packet from a non-local subnet. */
   d = find_subnet(p->ip);
-  
+
   n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
 
   return (n1 != NULL);
@@ -565,7 +567,6 @@ BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,ch
 {
   struct packet_struct p;
   struct dgram_packet *dgram = &p.packet.dgram;
-  struct in_addr wins_ip = ipgrp;
   char *ptr,*p2;
   char tmp[4];
 
index b920742c7650ba25c2e535edbaac4892999ea00c..fab16038ce0f1c5c1540f9f44be7b5466df7e365 100644 (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;
 
 
 /***************************************************************************
@@ -51,146 +51,146 @@ static void dead_netbios_entry(struct subnet_record *d,
   {
     case NAME_QUERY_CONFIRM:
     {
-               if (!lp_wins_support()) return; /* only if we're a WINS server */
-
-               if (n->num_msgs == 0)
+      if (!lp_wins_support()) return; /* only if we're a WINS server */
+      
+      if (n->num_msgs == 0)
         {
-                       /* oops. name query had no response. check that the name is
-                          unique and then remove it from our WINS database */
-
-                       /* IMPORTANT: see query_refresh_names() */
-
-                       if ((!NAME_GROUP(n->nb_flags)))
-                       {
-                               struct subnet_record *d1 = find_subnet(ipgrp);
-                               if (d1)
-                               {
-                                       /* remove the name that had been registered with us,
-                                          and we're now getting no response when challenging.
-                                          see rfc1001.txt 15.5.2
-                                        */
-                                       remove_netbios_name(d1, n->name.name, n->name.name_type,
-                                                                       REGISTER, n->send_ip);
-                               }
-                       }
+         /* oops. name query had no response. check that the name is
+            unique and then remove it from our WINS database */
+         
+         /* IMPORTANT: see query_refresh_names() */
+         
+         if ((!NAME_GROUP(n->nb_flags)))
+           {
+             struct subnet_record *d1 = find_subnet(wins_ip);
+             if (d1)
+               {
+                 /* remove the name that had been registered with us,
+                    and we're now getting no response when challenging.
+                    see rfc1001.txt 15.5.2
+                    */
+                 remove_netbios_name(d1, n->name.name, n->name.name_type,
+                                     REGISTER, n->send_ip);
                }
-               break;
+           }
+       }
+      break;
     }
-
-       case NAME_QUERY_MST_CHK:
+    
+  case NAME_QUERY_MST_CHK:
+    {
+      /* if no response received, the master browser must have gone
+        down on that subnet, without telling anyone. */
+      
+      /* IMPORTANT: see response_netbios_packet() */
+      
+      if (n->num_msgs == 0)
+       browser_gone(n->name.name, n->send_ip);
+      break;
+    }
+  
+  case NAME_RELEASE:
+    {
+      /* if no response received, it must be OK for us to release the
+        name. nobody objected (including a potentially dead or deaf
+        WINS server) */
+      
+      /* IMPORTANT: see response_name_release() */
+      
+      if (ismyip(n->send_ip))
        {
-         /* if no response received, the master browser must have gone
-                down on that subnet, without telling anyone. */
-
-         /* IMPORTANT: see response_netbios_packet() */
-
-         if (n->num_msgs == 0)
-                 browser_gone(n->name.name, n->send_ip);
-         break;
+         name_unregister_work(d,n->name.name,n->name.name_type);
        }
-
-       case NAME_RELEASE:
+      if (!n->bcast && n->num_msgs == 0)
        {
-         /* if no response received, it must be OK for us to release the
-                name. nobody objected (including a potentially dead or deaf
-                WINS server) */
-
-         /* IMPORTANT: see response_name_release() */
-
-         if (ismyip(n->send_ip))
-         {
-               name_unregister_work(d,n->name.name,n->name.name_type);
-         }
-         if (!n->bcast && n->num_msgs == 0)
-         {
-                DEBUG(0,("WINS server did not respond to name release!\n"));
-         /* XXXX whoops. we have problems. must deal with this */
-         }
-         break;
+         DEBUG(0,("WINS server did not respond to name release!\n"));
+         /* XXXX whoops. we have problems. must deal with this */
        }
-
-       case NAME_REGISTER_CHALLENGE:
-       {
-               /* name challenge: no reply. we can reply to the person that
-                  wanted the unique name and tell them that they can have it
-                */
-
-               add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
-                                               n->nb_flags, GET_TTL(0),
-                                               n->reply_to_ip, False, n->reply_to_ip);
-
-         if (!n->bcast && n->num_msgs == 0)
-         {
-                DEBUG(1,("WINS server did not respond to name registration!\n"));
-         /* XXXX whoops. we have problems. must deal with this */
-         }
       break;
+    }
+  
+  case NAME_REGISTER_CHALLENGE:
+    {
+      /* name challenge: no reply. we can reply to the person that
+        wanted the unique name and tell them that they can have it
+        */
+      
+      add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
+                      n->nb_flags, GET_TTL(0),
+                      n->reply_to_ip, False, n->reply_to_ip);
+      
+      if (!n->bcast && n->num_msgs == 0)
+       {
+         DEBUG(1,("WINS server did not respond to name registration!\n"));
+         /* XXXX whoops. we have problems. must deal with this */
        }
-
-       case NAME_REGISTER:
+      break;
+    }
+  
+  case NAME_REGISTER:
+    {
+      /* if no response received, and we are using a broadcast registration
+        method, it must be OK for us to register the name: nobody objected 
+        on that subnet. if we are using a WINS server, then the WINS
+        server must be dead or deaf.
+        */
+      if (n->num_msgs == 0)
        {
-         /* if no response received, and we are using a broadcast registration
-                method, it must be OK for us to register the name: nobody objected 
-                on that subnet. if we are using a WINS server, then the WINS
-                server must be dead or deaf.
-          */
-         if (n->num_msgs == 0)
-         {
-           if (n->bcast)
+         if (n->bcast)
            {
-                 /* broadcast method: implicit acceptance of the name registration
-                    by not receiving any objections. */
-
-                 /* IMPORTANT: see response_name_reg() */
-
-                 name_register_work(d,n->name.name,n->name.name_type,
-                                 n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+             /* broadcast method: implicit acceptance of the name registration
+                by not receiving any objections. */
+             
+             /* IMPORTANT: see response_name_reg() */
+             
+             name_register_work(d,n->name.name,n->name.name_type,
+                                n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
+           }
+         else
+           {
+             /* received no response. rfc1001.txt states that after retrying,
+                we should assume the WINS server is dead, and fall back to
+                broadcasting (see bits about M nodes: can't find any right
+                now) */
+             
+             DEBUG(1,("WINS server did not respond to name registration!\n"));
+             /* XXXX whoops. we have problems. must deal with this */
            }
-        else
-        {
-                 /* received no response. rfc1001.txt states that after retrying,
-                    we should assume the WINS server is dead, and fall back to
-                    broadcasting (see bits about M nodes: can't find any right
-             now) */
-               
-                 DEBUG(1,("WINS server did not respond to name registration!\n"));
-          /* XXXX whoops. we have problems. must deal with this */
-        }
-         }
-         break;
        }
-
-       case NAME_QUERY_DOMAIN:
-       {
-         /* if no response received, there is no domain controller on
+      break;
+    }
+  
+  case NAME_QUERY_DOMAIN:
+    {
+      /* if no response received, there is no domain controller on
          this local subnet.  it's ok for us to register
-       */
-
-         if (!n->bcast)
-         {
-                DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
-         /* XXXX whoops. someone's using this to unicast a packet.  this state
-            should only be used for broadcast checks
-          */
-         break;
-         }
-         if (n->num_msgs == 0)
-         {
-        struct work_record *work = find_workgroupstruct(d,n->name.name,False);
-        if (work && d)
-        {
-          become_domain_master(d,work);
-        }
-         }
+        */
+      
+      if (!n->bcast)
+       {
+         DEBUG(0,("NAME_QUERY_DOMAIN incorrectly used - contact samba-bugs!\n"));
+         /* XXXX whoops. someone's using this to unicast a packet.  this state
+            should only be used for broadcast checks
+            */
          break;
        }
-
-       default:
+      if (n->num_msgs == 0)
        {
-         /* nothing to do but delete the dead expected-response structure */
-         /* this is normal. */
-         break;
+         struct work_record *work = find_workgroupstruct(d,n->name.name,False);
+         if (work && d)
+           {
+             become_domain_master(d,work);
+           }
        }
+      break;
+    }
+
+  default:
+    {
+      /* nothing to do but delete the dead expected-response structure */
+      /* this is normal. */
+      break;
+    }
   }
 }
 
@@ -300,10 +300,9 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
                        int fd,int quest_type,enum state_type state,char *name,
                        int name_type,int nb_flags, time_t ttl,
                        int server_type, char *my_name, char *my_comment,
-                   BOOL bcast,BOOL recurse,
+                       BOOL bcast,BOOL recurse,
                        struct in_addr send_ip, struct in_addr reply_to_ip)
 {
-  struct in_addr wins_ip = ipgrp;
   struct response_record *n;
   uint16 id = 0xffff;
 
@@ -311,7 +310,7 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
   if (ip_equal(wins_ip, send_ip)) return NULL;
 
   initiate_netbios_packet(&id, fd, quest_type, name, name_type,
-                                     nb_flags, bcast, recurse, send_ip);
+                         nb_flags, bcast, recurse, send_ip);
 
   if (id == 0xffff) {
     DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
@@ -319,9 +318,9 @@ struct response_record *queue_netbios_packet(struct subnet_record *d,
   }
   
   if ((n = make_response_queue_record(state,id,fd,
-                                               quest_type,name,name_type,nb_flags,ttl,
-                                               server_type,my_name, my_comment,
-                                               bcast,recurse,send_ip,reply_to_ip)))
+                                     quest_type,name,name_type,nb_flags,ttl,
+                                     server_type,my_name, my_comment,
+                                     bcast,recurse,send_ip,reply_to_ip)))
     {
       add_response_record(d,n);
       return n;
index 77c3906242205bc3ce96dfcadfbd7d3fe6bee761..ac2dac1683c8df01cb4d76d497d19d464c25963e 100644 (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;
 
index 544cbc62b44ab872bebd883a516f1697fb57b365..001695b3fbde22e8d70f01c281307c72cac471ac 100644 (file)
@@ -36,7 +36,7 @@ extern int ClientNMB;
 
 extern int DEBUGLEVEL;
 
-extern struct in_addr ipgrp;
+extern struct in_addr wins_ip;
 
 
 /****************************************************************************
@@ -120,35 +120,35 @@ void reply_name_release(struct packet_struct *p)
           namestr(&nmb->question.question_name)));
   
   if (!(d = find_req_subnet(p->ip, bcast)))
-  {
-    DEBUG(3,("response packet: bcast %s not known\n",
-                       inet_ntoa(p->ip)));
-    return;
-  }
+    {
+      DEBUG(3,("response packet: bcast %s not known\n",
+              inet_ntoa(p->ip)));
+      return;
+    }
 
   if (bcast)
-       search |= FIND_LOCAL;
+    search |= FIND_LOCAL;
   else
-       search |= FIND_WINS;
+    search |= FIND_WINS;
 
   n = find_name_search(&d, &nmb->question.question_name, 
-                                       search, ip);
+                      search, ip);
   
   /* XXXX under what conditions should we reject the removal?? */
   if (n && n->ip_flgs[0].nb_flags == nb_flags)
-  {
+    {
       success = True;
       
       remove_name(d,n);
       n = NULL;
-  }
+    }
   
   if (bcast) return;
   
   /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
   send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
-                                               success, False,
-                                               &nmb->question.question_name, nb_flags, 0, ip);
+                    success, False,
+                    &nmb->question.question_name, nb_flags, 0, ip);
 }
 
 
@@ -190,7 +190,7 @@ void reply_name_reg(struct packet_struct *p)
     {
       /* apparently we should return 255.255.255.255 for group queries
         (email from MS) */
-      ip = ipgrp;
+      ip = wins_ip;
     }
   
   if (!(d = find_req_subnet(p->ip, bcast)))
@@ -393,8 +393,8 @@ void reply_name_status(struct packet_struct *p)
       
       if (!strequal(n->name.name,"*") &&
          !strequal(n->name.name,"__SAMBA__") &&
-         (name_type < 0x1b || name_type > 0x20 || 
-          ques_type < 0x1b || ques_type > 0x20 ||
+         (name_type < 0x1b || name_type >= 0x20 || 
+          ques_type < 0x1b || ques_type >= 0x20 ||
           strequal(qname, n->name.name)))
       {
         /* start with first bit of putting info in buffer: the name */
@@ -433,7 +433,7 @@ void reply_name_status(struct packet_struct *p)
       /* end of this name list: add wins names too? */
       struct subnet_record *w_d;
 
-      if (!(w_d = find_subnet(ipgrp))) break;
+      if (!(w_d = find_subnet(wins_ip))) break;
 
       if (w_d != d)
       {
@@ -520,7 +520,7 @@ void reply_name_query(struct packet_struct *p)
   }
   else
   {
-    if (!(d = find_subnet(ipgrp)))
+    if (!(d = find_subnet(wins_ip)))
     {
       DEBUG(3,("name query: wins search %s not known\n",
                                    inet_ntoa(p->ip)));
index ce626976444448ae3909be55791e98dc09540f40..30541034b81d8041c68365abb4f72ff53b92e3c2 100644 (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"));
        }
 }
 
@@ -409,69 +418,74 @@ static void response_name_query_sync(struct nmb_packet *nmb,
                struct nmb_name *ans_name, BOOL bcast,
                struct response_record *n, struct subnet_record *d)
 {
-       DEBUG(4, ("Name query at %s ip %s - ",
-                 namestr(&n->name), inet_ntoa(n->send_ip)));
-
-       if (!name_equal(&n->name, ans_name))
-       {
-               /* someone gave us the wrong name as a reply. oops. */
-               DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
-               return;
-       }
+  DEBUG(4, ("Name query at %s ip %s - ",
+           namestr(&n->name), inet_ntoa(n->send_ip)));
 
-       if (nmb->header.rcode == 0 && nmb->answers->rdata)
+  if (!name_equal(&n->name, ans_name))
     {
-               int nb_flags = nmb->answers->rdata[0];
-               struct in_addr found_ip;
-
-               putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
-               if (!ip_equal(n->send_ip, found_ip))
-               {
-                       /* someone gave us the wrong ip as a reply. oops. */
-                       DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
-                       DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
-                       return;
-               }
-
-               DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
+      /* someone gave us the wrong name as a reply. oops. */
+      DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+      return;
+    }
 
-               if (n->state == NAME_QUERY_SYNC_LOCAL ||
-                   n->state == NAME_QUERY_SYNC_REMOTE)
-               {
-                       struct work_record *work = NULL;
-                       if ((work = find_workgroupstruct(d, ans_name->name, False)))
-                       {
-                               BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+  if (nmb->header.rcode == 0 && nmb->answers->rdata)
+    {
+      int nb_flags = nmb->answers->rdata[0];
+      struct in_addr found_ip;
+      
+      putip((char*)&found_ip,&nmb->answers->rdata[2]);
+      
+      if (!ip_equal(n->send_ip, found_ip))
+       {
+         /* someone gave us the wrong ip as a reply. oops. */
+         DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
+         DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
+         return;
+       }
 
-                               /* the server is there: sync quick before it (possibly) dies! */
-                               sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
-                                                       found_ip, local_list_only);
-                       }
-               }
-               else
-               {
-                       /* update our netbios name list (re-register it if necessary) */
-                       add_netbios_entry(d, ans_name->name, ans_name->name_type,
-                                                               nb_flags,GET_TTL(0),REGISTER,
-                                                               found_ip,False,!bcast);
-               }
+      DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
+      
+      if (n->state == NAME_QUERY_SYNC_LOCAL ||
+         n->state == NAME_QUERY_SYNC_REMOTE)
+       {
+         struct work_record *work = NULL;
+         /* We cheat here as we know that the workgroup name has
+            been placed in the my_comment field of the 
+            response_record struct by the code in 
+            start_sync_browse_entry().
+         */
+         if ((work = find_workgroupstruct(d, n->my_comment, False)))
+           {
+             BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
+             
+             /* the server is there: sync quick before it (possibly) dies! */
+             sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
+                               found_ip, local_list_only);
+           }
        }
-       else
+      else
        {
-               DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
-               if (n->state == NAME_QUERY_CONFIRM)
-               {
-                       /* XXXX remove_netbios_entry()? */
-                       /* lots of things we ought to do, here. if we get here,
-                          then we're in a mess: our name database doesn't match
-                          reality. sort it out
+         /* update our netbios name list (re-register it if necessary) */
+         add_netbios_entry(d, ans_name->name, ans_name->name_type,
+                           nb_flags,GET_TTL(0),REGISTER,
+                           found_ip,False,!bcast);
+       }
+    }
+  else
+    {
+      DEBUG(4, (" NEGATIVE RESPONSE!\n"));
+      
+      if (n->state == NAME_QUERY_CONFIRM)
+       {
+         /* XXXX remove_netbios_entry()? */
+         /* lots of things we ought to do, here. if we get here,
+            then we're in a mess: our name database doesn't match
+            reality. sort it out
              */
-               remove_netbios_name(d,n->name.name, n->name.name_type,
-                                                               REGISTER,n->send_ip);
-               }
+         remove_netbios_name(d,n->name.name, n->name.name_type,
+                             REGISTER,n->send_ip);
        }
+    }
 }
 
 
@@ -481,13 +495,13 @@ static void response_name_query_sync(struct nmb_packet *nmb,
 static void debug_rr_type(int rr_type)
 {
   switch (rr_type)
-  {
-      case NMB_STATUS: DEBUG(3,("Name status ")); break;
-         case NMB_QUERY : DEBUG(3,("Name query ")); break;
-         case NMB_REG   : DEBUG(3,("Name registration ")); break;
-         case NMB_REL   : DEBUG(3,("Name release ")); break;
-      default        : DEBUG(1,("wrong response packet type received")); break;
-  }
+    {
+    case NMB_STATUS: DEBUG(3,("Name status ")); break;
+    case NMB_QUERY : DEBUG(3,("Name query ")); break;
+    case NMB_REG   : DEBUG(3,("Name registration ")); break;
+    case NMB_REL   : DEBUG(3,("Name release ")); break;
+    default        : DEBUG(1,("wrong response packet type received")); break;
+    }
 }
 
 /****************************************************************************
@@ -497,8 +511,8 @@ void debug_state_type(int state)
 {
   /* report the state type to help debugging */
   switch (state)
-  {
-    case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("MASTER_SVR_CHECK\n")); break;
+    {
+    case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
     case NAME_QUERY_SRV_CHK      : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
     case NAME_QUERY_FIND_MST     : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
     case NAME_QUERY_MST_CHK      : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
@@ -506,17 +520,17 @@ void debug_state_type(int state)
     case NAME_QUERY_SYNC_LOCAL   : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
     case NAME_QUERY_SYNC_REMOTE  : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
     case NAME_QUERY_ANNOUNCE_HOST: DEBUG(4,("NAME_QUERY_ANNCE_HOST\n"));break;
-
+      
     case NAME_REGISTER           : DEBUG(4,("NAME_REGISTER\n")); break;
     case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
-
+      
     case NAME_RELEASE            : DEBUG(4,("NAME_RELEASE\n")); break;
-
-    case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
+      
+    case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
     case NAME_STATUS_SRV_CHK     : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
-
+      
     default: break;
-  }
+    }
 }
 
 /****************************************************************************
@@ -528,87 +542,95 @@ static BOOL response_problem_check(struct response_record *n,
                        struct nmb_packet *nmb, char *ans_name)
 {
   switch (nmb->answers->rr_type)
-  {
-    case NMB_REL:
     {
+    case NMB_REL:
+      {
         if (n->num_msgs > 1)
-        {
+         {
             DEBUG(1,("more than one release name response received!\n"));
             return True;
-        }
+         }
         break;
-    }
+      }
 
     case NMB_REG:
-    {
+      {
         if (n->num_msgs > 1)
-        {
+         {
             DEBUG(1,("more than one register name response received!\n"));
             return True;
-        }
+         }
         break;
-    }
-
+      }
+    
     case NMB_QUERY:
-    { 
-      if (n->num_msgs > 1)
-      {
-                 if (nmb->header.rcode == 0 && nmb->answers->rdata)
+      { 
+       if (n->num_msgs > 1)
+         {
+           if (nmb->header.rcode == 0 && nmb->answers->rdata)
+             {
+               int nb_flags = nmb->answers->rdata[0];
+               
+               if ((!NAME_GROUP(nb_flags)))
                  {
-                       int nb_flags = nmb->answers->rdata[0];
-
-                       if ((!NAME_GROUP(nb_flags)))
+                   /* oh dear. more than one person responded to a 
+                      unique name.
+                      there is either a network problem, a 
+                      configuration problem
+                      or a server is mis-behaving */
+                   
+                   /* XXXX mark the name as in conflict, and then let the
+                      person who just responded know that they 
+                      must also mark it
+                      as in conflict, and therefore must NOT use it.
+                      see rfc1001.txt 15.1.3.5 */
+                   
+                   /* this may cause problems for some 
+                      early versions of nmbd */
+                   
+                   switch (n->state)
+                     {
+                     case NAME_QUERY_FIND_MST:
                        {
-                          /* oh dear. more than one person responded to a unique name.
-                                 there is either a network problem, a configuration problem
-                                 or a server is mis-behaving */
-
-                          /* XXXX mark the name as in conflict, and then let the
-                                 person who just responded know that they must also mark it
-                                 as in conflict, and therefore must NOT use it.
-                  see rfc1001.txt 15.1.3.5 */
-                                       
-               /* this may cause problems for some early versions of nmbd */
-
-               switch (n->state)
-               {
-                case NAME_QUERY_FIND_MST:
-                {
-                  /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
-                  return False;
-                }
-                       case NAME_QUERY_ANNOUNCE_HOST:
-                       case NAME_QUERY_DOM_SRV_CHK:
-                case NAME_QUERY_SRV_CHK:
-                case NAME_QUERY_MST_CHK:
-                {
-                     if (!strequal(ans_name,n->name.name))
-                     {
-                            /* one subnet, one master browser per workgroup */
-                            /* XXXX force an election? */
-
-                            DEBUG(3,("more than one master browser replied!\n"));
-                                return True;
-                         }
-                   break;
-                }
-                default: break;
-               }
-               DEBUG(3,("Unique Name conflict detected!\n"));
-                          return True;
+                         /* query for ^1^2__MSBROWSE__^2^1 expect 
+                            lots of responses */
+                         return False;
                        }
+                     case NAME_QUERY_ANNOUNCE_HOST:
+                     case NAME_QUERY_DOM_SRV_CHK:
+                     case NAME_QUERY_SRV_CHK:
+                     case NAME_QUERY_MST_CHK:
+                       {
+                         if (!strequal(ans_name,n->name.name))
+                           {
+                             /* one subnet, one master browser 
+                                per workgroup */
+                             /* XXXX force an election? */
+                             
+                             DEBUG(3,("more than one master browser replied!\n"));
+                             return True;
+                           }
+                         break;
+                       }
+                     default: break;
+                     }
+                   DEBUG(3,("Unique Name conflict detected!\n"));
+                   return True;
                  }
-                 else
-                 {
-             /* we have received a negative reply, having already received
-                at least one response (pos/neg). something's really wrong! */
-
-                DEBUG(3,("wierd name query problem detected!\n"));
-                    return True;
-                 }
-       }
+             }
+           else
+             {
+               /* we have received a negative reply, 
+                  having already received
+                  at least one response (pos/neg). 
+                  something's really wrong! */
+               
+               DEBUG(3,("wierd name query problem detected!\n"));
+               return True;
+             }
+         }
+      }
     }
-  }
   return False;
 }
 
@@ -685,73 +707,73 @@ static BOOL response_compatible(struct response_record *n,
   process the response packet received
   ****************************************************************************/
 static void response_process(struct subnet_record *d, struct packet_struct *p,
-                               struct response_record *n, struct nmb_packet *nmb,
-                               BOOL bcast, struct nmb_name *ans_name)
+                            struct response_record *n, struct nmb_packet *nmb,
+                            BOOL bcast, struct nmb_name *ans_name)
 {
   switch (n->state)
-  {
-    case NAME_RELEASE:
     {
+    case NAME_RELEASE:
+      {
         response_name_release(ans_name, d, p);
         break;
-    }
+      }
 
     case NAME_REGISTER:
-    {
+      {
                response_name_reg(ans_name, d, p);
         break;
-    }
+      }
 
     case NAME_REGISTER_CHALLENGE:
-    {
+      {
         response_name_query_register(nmb, ans_name, n, d);
         break;
-    }
+      }
 
     case NAME_QUERY_DOM_SRV_CHK:
     case NAME_QUERY_SRV_CHK:
     case NAME_QUERY_FIND_MST:
-    {
-               response_server_check(ans_name, n, d);
-               break;
-    }
-      
+      {
+       response_server_check(ans_name, n, d);
+       break;
+      }
+    
     case NAME_STATUS_DOM_SRV_CHK:
     case NAME_STATUS_SRV_CHK:
-    {
-               response_name_status_check(p->ip, nmb, bcast, n, d);
-               break;
-    }
-      
+      {
+       response_name_status_check(p->ip, nmb, bcast, n, d);
+       break;
+      }
+    
     case NAME_QUERY_ANNOUNCE_HOST:
-    {
-               response_announce_host(ans_name, nmb, n, d);
-               break;
-    }
+      {
+       response_announce_host(ans_name, nmb, n, d);
+       break;
+      }
       
     case NAME_QUERY_CONFIRM:
     case NAME_QUERY_SYNC_LOCAL:
     case NAME_QUERY_SYNC_REMOTE:
-    {
-               response_name_query_sync(nmb, ans_name, bcast, n, d);
-               break;
-    }
+      {
+       response_name_query_sync(nmb, ans_name, bcast, n, d);
+       break;
+      }
     case NAME_QUERY_MST_CHK:
-    {
-               /* no action required here. it's when NO responses are received
-                  that we need to do something. see expire_name_query_entries() */
+      {
+       /* no action required here. it's when NO responses are received
+          that we need to do something. see expire_name_query_entries() */
        
-               DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
-                                       namestr(&n->name), inet_ntoa(n->send_ip)));
-               break;
-    }
-
+       DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
+                 namestr(&n->name), inet_ntoa(n->send_ip)));
+       break;
+      }
+    
     default:
-    {
-               DEBUG(1,("unknown state type received in response_netbios_packet\n"));
-               break;
+      {
+       DEBUG(1,("unknown state type received in response_netbios_packet\n"));
+       break;
+      }
     }
-  }
 }
 
 
@@ -772,43 +794,41 @@ void response_netbios_packet(struct packet_struct *p)
   }
 
   if (!d)
-  {
-    DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
-    return;
-  }
+    {
+      DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
+      return;
+    }
 
   /* args wrong way round: spotted by ccm@shentel.net */
   if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
-  {
-    DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
-    DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
-  }
-
+    {
+      DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
+      DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
+    }
+  
   if (nmb->answers == NULL)
-  {
+    {
       /* hm. the packet received was a response, but with no answer. wierd! */
       DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
               inet_ntoa(p->ip), BOOLSTR(bcast)));
       return;
-  }
+    }
 
   ans_name = &nmb->answers->rr_name;
   DEBUG(3,("response for %s from %s (bcast=%s)\n",
           namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
   
   debug_rr_type(nmb->answers->rr_type);
-
+  
   n->num_msgs++; /* count number of responses received */
   n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
-
+  
   debug_state_type(n->state);
-
+  
   /* problem checking: multiple responses etc */
   if (response_problem_check(n, nmb, ans_name->name))
     return;
-
+  
   /* now deal with the current state */
   response_process(d, p, n, nmb, bcast, ans_name);
 }
-
-
index 20c1050597e2161bc5c462cceaa75421940d622f..1d3ff9e0ee336a6bca443c2c1ffd26f58b327943 100644 (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,8 +638,13 @@ static void process_announce_request(struct packet_struct *p,char *buf)
      if (strequal(dgram->dest_name, lp_workgroup()) return; ???
    */
 
-  if (!d) return;
-  
+  if (!d) 
+    {
+      DEBUG(3,("process_announce_request: No local interface to announce to %s\n",
+                name));
+      return;
+    }
   for (work = d->workgrouplist; work; work = work->next)
     {
      /* XXXX BUG: the destination name type should also be checked,
@@ -660,7 +673,7 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
     case ANN_LocalMasterAnnouncement:
       {
         debug_browse_data(buf, len);
-       process_announce(p,command,buf+1);
+       process_localnet_announce(p,command,buf+1);
        break;
       }
       
index e45facdc2e363b6f1200a927c365b1730f0368c5..eefb4162f79cc371ed656587da5fbb86efee45ca 100644 (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);
index 2efb364bcae5a929ced3f5dd912d8e2c886b27b7..fa60b3ac35acd4b74a33349c36ceeb4787fe5fdb 100644 (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();
index 672f1fe5483160c3b62e2a612d72e2157d5c9a7b..64dd01eeafa94c6d656ca7ac048de2bfd10685d7 100644 (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;