- new handling of ST_TYPE bits, they are now consolidated much more in
authorAndrew Tridgell <tridge@samba.org>
Wed, 21 Aug 1996 06:09:00 +0000 (06:09 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 21 Aug 1996 06:09:00 +0000 (06:09 +0000)
DFLT_SERVER_TYPE in nameserv.h

- got rid of a lot of spurious domain controller stuff. Samba is not a
domain controller yet, but it can be a domain master. We were claiming
to be a domain controller in some packets which may have caused
problems

- don't do preferred master startups on the WINS pseudo-net

- don't do election requests on the WINS pseudo-net

- fix a nasty bug in become_non_master() which wiped out the bits in
remove_type before using them. The result was that samba didn't like
losing its master status.

- changed the logic in the election packet handling to enable us to
become a non-master whenever we receive a winning election frame, even
if we aren't expecting it

- get another packet from the socket in nmbd when we reject one of our
own packets, this stops us from going into the packet reading code too
often and makes nmbd much snappier

- always remove a name immediately when we try to release it, don't
wait for the lack of response from the network, otherwise we will end
up replying to name that we don't really own. We still send the dereg
packets, we just don't wait for them to time out.
(This used to be commit eb84f2f342375439d94481a0ccf47c9593544e32)

source3/include/nameserv.h
source3/include/smb.h
source3/lib/util.c
source3/nameannounce.c
source3/namedbwork.c
source3/nameelect.c
source3/namepacket.c
source3/nameserv.c
source3/namework.c
source3/smbd/ipc.c

index 8dc737bdb069903a21d291beac5dcaa33fc22e82..e4876bac57022d7d641556eb7ea8560ccbbb1af1 100644 (file)
@@ -383,3 +383,9 @@ struct packet_struct
 
 /* do all remote announcements this often */
 #define REMOTE_ANNOUNCE_INTERVAL 180
+
+#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
+                         SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
+                         SV_TYPE_PRINTQ_SERVER | SV_TYPE_SERVER_NT | \
+                         SV_TYPE_NT)
+
index 349d406b49f7c7361029c327fa096ffcc2dd3423..7e002122cc767f9c4f08b42e69eeec7b0daced72 100644 (file)
@@ -785,6 +785,7 @@ char *Strstr(char *s, char *p);
 #define SV_TYPE_DOMAIN_ENUM         0x80000000
 #define SV_TYPE_ALL                 0xFFFFFFFF  
 
+/* what server type are we currently */
 
 
 /* protocol types. It assumes that higher protocols include lower protocols
index 2f3ac1bb150685c306f53bd6b6dc8ddd47444bbc..2fedded3292ccb213688bd02d3485bc6ced63d48 100644 (file)
@@ -3148,7 +3148,7 @@ my own panic function - not suitable for general use
 ********************************************************************/
 void ajt_panic(void)
 {
-  system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
+  system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
 }
 #endif
 
index 5591c5ba19af6fb349819467a593a65f4ee6ef5a..ff2c89df85296785105d25b5ba901eed0af402b1 100644 (file)
@@ -208,7 +208,7 @@ void remove_my_servers(void)
 void announce_server(struct subnet_record *d, struct work_record *work,
                     char *name, char *comment, time_t ttl, int server_type)
 {
-       uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
+       uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE;
        BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
        
        if (wins_iface && server_type != 0)
@@ -237,11 +237,6 @@ void announce_server(struct subnet_record *d, struct work_record *work,
                        }
                }
 
-               if (AM_DOMCTL(work))
-               {
-                       /* XXXX announce to backup domain masters? */
-               }
-
                /* XXXX any other kinds of announcements we need to consider here?
                   e.g local master browsers... no. local master browsers do
                   local master announcements to their domain master. they even
@@ -268,10 +263,6 @@ void announce_server(struct subnet_record *d, struct work_record *work,
                        /* XXXX should we do a domain-announce-kill? */
                        if (server_type != 0)
                        {
-                               if (AM_DOMCTL(work))
-                               {
-                                       domain_type |= SV_TYPE_DOMAIN_CTRL;
-                               }
                                do_announce_host(ANN_DomainAnnouncement,
                                                        name    , 0x00, d->myip,
                                                        MSBROWSE, 0x01, d->bcast_ip,
@@ -490,8 +481,7 @@ void announce_remote(void)
   pstring s2;
   struct in_addr addr;
   char *comment,*workgroup;
-  int stype = SV_TYPE_WORKSTATION | SV_TYPE_SERVER | SV_TYPE_PRINTQ_SERVER |
-    SV_TYPE_SERVER_UNIX;
+  int stype = DFLT_SERVER_TYPE;
 
   if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
     return;
index 200132304b00de76087c4ff95d7a5b201869cdc2..04f2103254b5aa38c947c2225149d23a9b68d4c6 100644 (file)
@@ -38,13 +38,10 @@ extern int DEBUGLEVEL;
 /* this is our domain/workgroup/server database */
 extern struct subnet_record *subnetlist;
 
-int workgroup_count = 0; /* unique index key: one for each workgroup */
+extern struct in_addr ipgrp;
 
-/* what server type are we currently */
+int workgroup_count = 0; /* unique index key: one for each workgroup */
 
-#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
-                       SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
-                       SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
 
 
 /****************************************************************************
@@ -89,7 +86,7 @@ static struct work_record *make_workgroup(char *name)
   StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
   work->serverlist = NULL;
   
-  work->ServerType = DFLT_SERVER_TYPE;
+  work->ServerType = DFLT_SERVER_TYPE | SV_TYPE_POTENTIAL_BROWSER;
   work->RunningElection = False;
   work->ElectionCount = 0;
   work->needelection = False;
@@ -202,7 +199,8 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
   
   if ((work = make_workgroup(name)))
     {
-      if (lp_preferred_master() &&
+      if (!ip_equal(d->bcast_ip, ipgrp) &&
+         lp_preferred_master() &&
          strequal(lp_workgroup(), name))
        {
          DEBUG(3, ("preferred master startup for %s\n", work->work_group));
index 041e4a8cca98073130d524a93adcd55486ffb93b..07429013e0db5380d9beef1bb9b1d4507a607172 100644 (file)
@@ -97,7 +97,11 @@ void browser_gone(char *work_name, struct in_addr ip)
 
   /* i don't know about this workgroup, therefore i don't care */
   if (!work || !d) return;
+
+  /* don't do election stuff on the WINS subnet */
+  if (ip_equal(d->bcast_ip,ipgrp)) 
+    return;
+
   if (strequal(work->work_group, lp_workgroup()))
   {
 
@@ -245,7 +249,8 @@ void name_register_work(struct subnet_record *d, char *name, int name_type,
   ******************************************************************/
 void become_master(struct subnet_record *d, struct work_record *work)
 {
-  uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX|0x00400000;
+  uint32 domain_type = SV_TYPE_DOMAIN_ENUM|DFLT_SERVER_TYPE|
+    SV_TYPE_POTENTIAL_BROWSER;
 
   if (!work) return;
   
@@ -369,12 +374,8 @@ void become_master(struct subnet_record *d, struct work_record *work)
         DEBUG(3,("domain third stage: samba is now a domain master.\n"));
         work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
 
-        update_type |= SV_TYPE_DOMAIN_MASTER;
-      
-        if (lp_domain_logons())
-           {
-             update_type |= SV_TYPE_DOMAIN_CTRL|SV_TYPE_SERVER_UNIX;
-           }
+        update_type |= DFLT_SERVER_TYPE | SV_TYPE_DOMAIN_MASTER | 
+         SV_TYPE_POTENTIAL_BROWSER;
 
                work->ServerType |= update_type;
                add_server_entry(d,work,myname,work->ServerType,0,lp_serverstring(),True);
@@ -427,7 +428,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
   DEBUG(2,("Becoming non-master for %s\n",work->work_group));
   
   /* can only remove master or domain types with this function */
-  remove_type &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
+  remove_type &= SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER;
 
   /* unbecome a master browser; unbecome a domain master, too :-( */
   if (remove_type & SV_TYPE_MASTER_BROWSER)
@@ -439,7 +440,7 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
   {
     /* no longer a master browser of any sort */
 
-       work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
+    work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
     work->ElectionCriterion &= ~0x4;
     work->state = MST_NONE;
 
@@ -454,11 +455,10 @@ void become_nonmaster(struct subnet_record *d, struct work_record *work,
   {
     if (work->state == MST_DOMAIN)
       work->state = MST_BROWSER;
-    remove_name_entry(d,work->work_group,0x1b);
-    
+    remove_name_entry(d,work->work_group,0x1b);    
   }
 
-  if (!(work->ServerType & SV_TYPE_DOMAIN_MASTER))
+  if (!(work->ServerType & SV_TYPE_MASTER_BROWSER))
   {
     if (work->state >= MST_BROWSER)
       work->state = MST_NONE;
@@ -515,18 +515,23 @@ void run_elections(void)
 static BOOL win_election(struct work_record *work,int version,uint32 criterion,
                         int timeup,char *name)
 {  
-  time_t t = time(NULL);
-  uint32 mycriterion;
+  int mytimeup = time(NULL) - StartupTime;
+  uint32 mycriterion = work->ElectionCriterion;
+
+  DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
+          version,ELECTION_VERSION,
+          criterion,mycriterion,
+          timeup,mytimeup,
+          name,myname));
+
   if (version > ELECTION_VERSION) return(False);
   if (version < ELECTION_VERSION) return(True);
   
-  mycriterion = work->ElectionCriterion;
-
   if (criterion > mycriterion) return(False);
   if (criterion < mycriterion) return(True);
 
-  if (timeup > (t - StartupTime)) return(False);
-  if (timeup < (t - StartupTime)) return(True);
+  if (timeup > mytimeup) return(False);
+  if (timeup < mytimeup) return(True);
 
   if (strcasecmp(myname,name) > 0) return(False);
   
@@ -551,46 +556,44 @@ void process_election(struct packet_struct *p,char *buf)
   struct work_record *work;
 
   if (!d) return;
+
+  if (ip_equal(d->bcast_ip,ipgrp)) {
+    DEBUG(3,("Unexpected election request from %s %s on WINS net\n",
+            name, inet_ntoa(p->ip)));
+    return;
+  }
   
   name[15] = 0;  
 
-  DEBUG(3,("Election request from %s vers=%d criterion=%08x timeup=%d\n",
-          name,version,criterion,timeup));
+  DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
+          name,inet_ntoa(p->ip),version,criterion,timeup));
   
   if (same_context(dgram)) return;
   
   for (work = d->workgrouplist; work; work = work->next)
     {
-      if (strequal(work->work_group, lp_workgroup()))
-       {
-         if (win_election(work, version,criterion,timeup,name))
-           {
-             if (!work->RunningElection)
-               {
-                 work->needelection = True;
-                 work->ElectionCount=0;
-          work->state = MST_NONE;
-               }
-           }
-         else
-           {
-             work->needelection = False;
-             
-             if (work->RunningElection)
-               {
-                 work->RunningElection = False;
-                 DEBUG(3,(">>> Lost election on %s %s <<<\n",
-                          work->work_group,inet_ntoa(d->bcast_ip)));
-                 
-                 /* if we are the master then remove our masterly names */
-                 if (AM_MASTER(work))
-                 {
-                     become_nonmaster(d, work,
-                                       SV_TYPE_MASTER_BROWSER|SV_TYPE_DOMAIN_MASTER);
-                 }
-               }
-           }
+      if (!strequal(work->work_group, lp_workgroup()))
+       continue;
+
+      if (win_election(work, version,criterion,timeup,name)) {
+       if (!work->RunningElection) {
+         work->needelection = True;
+         work->ElectionCount=0;
+         work->state = MST_NONE;
        }
+      } else {
+       work->needelection = False;
+         
+       if (work->RunningElection || AM_MASTER(work)) {
+         work->RunningElection = False;
+         DEBUG(3,(">>> Lost election on %s %s <<<\n",
+                  work->work_group,inet_ntoa(d->bcast_ip)));
+         if (AM_MASTER(work))
+           become_nonmaster(d, work,
+                            SV_TYPE_MASTER_BROWSER|
+                            SV_TYPE_DOMAIN_MASTER);
+       }
+      }
     }
 }
 
index 075096bc573fc9a41a918e81c60befa1b84e71e3..5bfa55d4f1646645c4788f97588a99dd3cb6b943 100644 (file)
@@ -491,6 +491,8 @@ void listen_for_packets(BOOL run_election)
   int selrtn;
   struct timeval timeout;
 
+try_again:
+
   FD_ZERO(&fds);
   FD_SET(ClientNMB,&fds);
   FD_SET(ClientDGRAM,&fds);
@@ -515,6 +517,7 @@ void listen_for_packets(BOOL run_election)
          DEBUG(7,("discarding own packet from %s:%d\n",
                   inet_ntoa(packet->ip),packet->port));          
          free_packet(packet);
+         goto try_again;
        } else {
          queue_packet(packet);
        }
@@ -530,6 +533,7 @@ void listen_for_packets(BOOL run_election)
          DEBUG(7,("discarding own packet from %s:%d\n",
                   inet_ntoa(packet->ip),packet->port));          
          free_packet(packet);
+         goto try_again;
        } else {
          queue_packet(packet);
        }
index 8831cb510f15d52f1d35cbbff3a2c7675bbb5328..26c2f330dacb1296a3630530a7aa9a665d0979e8 100644 (file)
@@ -47,7 +47,7 @@ extern uint16 nb_type; /* samba's NetBIOS type */
 /****************************************************************************
   remove an entry from the name list
 
-  note: the name will _always_ be removed: it's just a matter of when.
+  note: the name will _always_ be removed
   XXXX at present, the name is removed _even_ if a WINS server says keep it.
 
   ****************************************************************************/
@@ -72,37 +72,26 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
     n2->ip_flgs[0].nb_flags &= NB_DEREG;
   }
 
-  if (ip_equal(d->bcast_ip, ipgrp))
-  {
-    if (lp_wins_support())
-    {
-        /* we are a WINS server. */
-        /* XXXX assume that if we are a WINS server that we are therefore
-           not pointing to another WINS server as well. this may later NOT
-           actually be true
-         */
-        remove_netbios_name(d,name,type,SELF,ipzero);
-    }
-    else
-    {
-      /* not a WINS server: cannot just remove our own names: we have to
-         release them on the network first. ask permission from the WINS
-         server, or if no reply is received, then we can remove the name */
+  if (!n2) return;
 
-        queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
-                 name, type, 0, 0,0,NULL,NULL,
-                 False, True, ipzero, ipzero);
-    }
-  }
-  else
-  {
-     /* local interface: cannot just remove our own names: we have to
-        release them on the network first. once no reply is received,
-        then we can remove the name. */
+  /* remove the name immediately. even if the spec says we should
+     first try to release them, this is too dangerous with our current
+     name structures as otherwise we will end up replying to names we
+     don't really own */  
+  remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
 
-     queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
+  if (ip_equal(d->bcast_ip, ipgrp)) {
+    if (!lp_wins_support()) {
+      /* not a WINS server: we have to release them on the network */
+      queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
                             name, type, 0, 0,0,NULL,NULL,
-                            True, True, d->bcast_ip, d->bcast_ip);
+                            False, True, ipzero, ipzero);
+    }
+  } else {
+    /* local interface: release them on the network */
+    queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
+                        name, type, 0, 0,0,NULL,NULL,
+                        True, True, d->bcast_ip, d->bcast_ip);
   }
 }
 
index be034488c43146df4633e8c0fcaaf7b8c8e24fdd..0380c1460affa2e7c693614af517ab41aae9a8b7 100644 (file)
@@ -50,11 +50,6 @@ extern struct subnet_record *subnetlist;
 
 extern int  updatecount;
 
-/* what server type are we currently */
-#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
-               SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX |\
-               SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
-
 /* backup request types: which servers are to be included */
 #define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
 #define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL   )
index 9da7c993dd1da1150a94fb907e1cd3e920f0db47..87df699e29819b527b33ee8a118af84893207685 100644 (file)
@@ -1666,8 +1666,7 @@ static BOOL api_RNetServerGetInfo(int cnum,int uid, char *param,char *data,
       struct srv_info_struct *servers=NULL;
       int i,count;
       pstring comment;
-      uint32 servertype=SV_TYPE_SERVER_UNIX|SV_TYPE_WORKSTATION|
-       SV_TYPE_SERVER|SV_TYPE_TIME_SOURCE;
+      uint32 servertype=DFLT_SERVER_TYPE;
 
       strcpy(comment,lp_serverstring());