general sorting out, from crashes generated by do_lsa_req_chal() in client.c
[kai/samba.git] / source3 / namebrowse.c
index 3bc4f9f82aa1f66b103c5f2a2bbc759fe09b28e4..ae5f00ce10e2016ce1495837f2594fdfd13f2dd7 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    NBT netbios routines and daemon - version 2
-   Copyright (C) Andrew Tridgell 1994-1995
+   Copyright (C) Andrew Tridgell 1994-1997
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -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,12 +91,12 @@ void expire_browse_cache(time_t t)
     }
 }
 
-
 /****************************************************************************
   add a browser entry
   ****************************************************************************/
 struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
-                                             time_t ttl, struct in_addr ip, BOOL local)
+                                             time_t ttl, struct subnet_record *d,
+                                              struct in_addr ip, BOOL local)
 {
   BOOL newentry=False;
   
@@ -136,7 +138,8 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
   b->ip     = ip;
   b->type   = type;
   b->local  = local; /* local server list sync or complete sync required */
-  
+  b->subnet = d;
   if (newentry || ttl < b->sync_time) 
     b->sync_time = ttl;
   
@@ -163,25 +166,40 @@ find a server responsible for a workgroup, and sync browse lists
 **************************************************************************/
 static void start_sync_browse_entry(struct browse_cache_record *b)
 {                     
-  struct subnet_record *d;
+  struct subnet_record *d = b->subnet;
   struct work_record *work;
 
-  if (!(d = find_subnet(b->ip))) return;
+  /* Check panic conditions - these should not be true. */
+  if(b->subnet != wins_subnet) {
+      DEBUG(0, 
+        ("start_sync_browse_entry: ERROR sync requested on non-WINS subnet.\n"));
+      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)) {
+  DEBUG(4, ("start_sync_browse_entry: Initiating %s sync with %s<0x20>, \
+workgroup %s\n",
+             b->local ? "local" : "remote", b->name, b->group));
 
-      /* first check whether the group we intend to sync with exists. if it
-         doesn't, the server must have died. o dear. */
+  /* 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() */
-      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);
-  }
+  /* 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, 0);
 
   b->synced = True;
 }
@@ -195,10 +213,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 +232,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"));
   }
 
+  expire_browse_cache(t - 60);
 }