local_only NetServerEnum syncs can now be issued.
authorSamba Release Account <samba-bugs@samba.org>
Thu, 1 Aug 1996 17:49:40 +0000 (17:49 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Thu, 1 Aug 1996 17:49:40 +0000 (17:49 +0000)
bug spotted in nameservresp.c - arguments to test subnet the response
is received on (same_net()) were the wrong way round (ccm@shentel.net)

samba was adding WORKGROUP(1e) as a unique not a group name: fixed this

bug in reply_name_status() and reply_name_query(): WINS entries weren't
being looked up.

name status reply adds local SELF entries to WINS SELF entries: some
SELF entries are only added locally, while others are only added via
WINS. name status needs to have both, combined.

a sync will only occur when an ANN_LocalMasterAnnouncement is received, NOT
an ANN_HostAnnouncement or an ANN_DomainAnnouncement.

when samba is a member of a workgroup, it looks for (using a wins server)
and announces to its domain master. NAME_QUERY_ANNOUNCE_HOST - yet another
'state' - has been created to do this: do the name query on the wins server
and send the announce host to the answer to this query.

jeremy @ vantive wrote the original code to do this, which used the
name_query() function.  i'm trying to avoid name_query: it times out and
generally messes things up, but using queue_netbios_packet() and
queue_netbios_pkt_wins() is... not intuitive?

lkcl with help from jra

18 files changed:
source/include/nameserv.h
source/include/proto.h
source/libsmb/namequery.c
source/nameannounce.c
source/namebrowse.c
source/namedbname.c
source/namedbresp.c
source/namedbsubnet.c
source/namedbwork.c
source/nameelect.c
source/nameresp.c
source/nameserv.c
source/nameservreply.c
source/nameservresp.c
source/namework.c
source/nmbd/nmbd.c
source/nmbsync.c
source/utils/nmblookup.c

index 7a97097e78ed36b3fb5494946bc5a32f0ffa3560..582378e18398b58778390cbedc5ca04c5fa90e84 100644 (file)
 #define NB_ACTIVE 0x04
 #define NB_CONFL  0x08
 #define NB_DEREG  0x10
-#define NB_BFLAG  0x00
-#define NB_PFLAG  0x20
-#define NB_MFLAG  0x40
-#define NB__FLAG  0x60
+#define NB_BFLAG  0x00 /* broadcast node type */
+#define NB_PFLAG  0x20 /* point-to-point node type */
+#define NB_MFLAG  0x40 /* mixed bcast & p-p node type */
+#define NB_HFLAG  0x60 /* microsoft 'hybrid' node type */
 #define NB_FLGMSK 0x60
 
 #define REFRESH_TIME (15*60)
@@ -68,7 +68,7 @@
 #define NAME_BFLAG(p)     (((p) & NB_FLGMSK) == NB_BFLAG)
 #define NAME_PFLAG(p)     (((p) & NB_FLGMSK) == NB_PFLAG)
 #define NAME_MFLAG(p)     (((p) & NB_FLGMSK) == NB_MFLAG)
-#define NAME__FLAG(p)     (((p) & NB_FLGMSK) == NB__FLAG)
+#define NAME_HFLAG(p)     (((p) & NB_FLGMSK) == NB_HFLAG)
 
 /* server type identifiers */
 #define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
@@ -99,14 +99,16 @@ enum master_state
 
 enum state_type
 {
-       NAME_STATUS_PDC_SRV_CHK,
+       NAME_STATUS_DOM_SRV_CHK,
        NAME_STATUS_SRV_CHK,
        NAME_REGISTER_CHALLENGE,
        NAME_REGISTER,
        NAME_RELEASE,
        NAME_QUERY_CONFIRM,
-       NAME_QUERY_SYNC,
-       NAME_QUERY_PDC_SRV_CHK,
+       NAME_QUERY_ANNOUNCE_HOST,
+       NAME_QUERY_SYNC_LOCAL,
+       NAME_QUERY_SYNC_REMOTE,
+       NAME_QUERY_DOM_SRV_CHK,
        NAME_QUERY_SRV_CHK,
        NAME_QUERY_FIND_MST,
        NAME_QUERY_MST_CHK
@@ -147,6 +149,7 @@ struct browse_cache_record
        struct in_addr ip;
        time_t sync_time;
        BOOL synced;
+       BOOL local;
 };
 
 /* this is used to hold the list of servers in my domain, and is */
@@ -190,6 +193,8 @@ struct work_record
 };
 
 /* initiated name queries recorded in this list to track any responses... */
+/* sadly, we need to group everything together. i suppose that if this
+   gets unwieldy, then a union ought to be considered. oh for c++... */
 struct response_record
 {
   struct response_record *next;
@@ -204,6 +209,10 @@ struct response_record
   int nb_flags;
   time_t ttl;
 
+  int server_type;
+  fstring my_name;
+  fstring my_comment;
+
   BOOL bcast;
   BOOL recurse;
   struct in_addr send_ip;
index 60b8eed59a5c977277622045ba8b112eb9995b25..10f2bc33257c2165655cfb6c548a6d8667381c9e 100644 (file)
@@ -295,6 +295,11 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
                 int name_type,
                 struct in_addr ip);
 void announce_backup(void);
+void do_announce_host(int command,
+               char *from_name, int from_type, struct in_addr from_ip,
+               char *to_name  , int to_type  , struct in_addr to_ip,
+               time_t announce_interval,
+               char *server_name, int server_type, char *server_comment);
 void 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);
@@ -305,11 +310,15 @@ void announce_master(void);
 
 void expire_browse_cache(time_t t);
 struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
-                                             time_t ttl, struct in_addr ip);
+                                             time_t ttl, struct in_addr ip, BOOL local);
 void do_browser_lists(void);
 
+/*The following definitions come from  namedb.c  */
+
+
 /*The following definitions come from  namedbname.c  */
 
+void set_samba_nb_type(void);
 BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
 BOOL ms_browser_name(char *name, int type);
 void remove_name(struct subnet_record *d, struct name_record *n);
@@ -342,6 +351,7 @@ void remove_response_record(struct subnet_record *d,
 struct response_record *make_response_queue_record(enum state_type state,
                                int id,uint16 fd,
                                int quest_type, char *name,int type, int nb_flags, time_t ttl,
+                               int server_type, char *my_name, char *my_comment,
                                BOOL bcast,BOOL recurse,
                                struct in_addr send_ip, struct in_addr reply_to_ip);
 struct response_record *find_response_record(struct subnet_record **d,
@@ -432,13 +442,15 @@ void expire_netbios_response_entries();
 struct response_record *queue_netbios_pkt_wins(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,
                                struct in_addr send_ip, struct in_addr reply_to_ip);
 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,
-                           BOOL bcast,BOOL recurse,
-                               struct in_addr send_ip, struct in_addr reply_to_ip);
+                       int server_type, char *my_name, char *my_comment,
+                   BOOL bcast,BOOL recurse,
+                       struct in_addr send_ip, struct in_addr reply_to_ip);
 
 /*The following definitions come from  nameserv.c  */
 
@@ -502,7 +514,7 @@ int main(int argc,char *argv[]);
 
 char *getsmbpass(char *pass);
 void sync_browse_lists(struct subnet_record *d, struct work_record *work,
-               char *name, int nm_type, struct in_addr ip);
+               char *name, int nm_type, struct in_addr ip, BOOL local);
 
 /*The following definitions come from  params.c  */
 
index 54809130017362c728643397ead2421b8f22a8cb..21d3bd1e5017e97c3798ab8b5f7b8fa4921b4081 100644 (file)
@@ -54,7 +54,7 @@ static void _interpret_node_status(char *p, char *master,char *rname)
       if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
       if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
       if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
-      if ((p[0] & 0x60) == 0x60) strcat(flags,"_ ");
+      if ((p[0] & 0x60) == 0x60) strcat(flags,"H ");
       if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
       if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
       if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
@@ -109,8 +109,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
   nmb->header.opcode = 0;
   nmb->header.response = False;
   nmb->header.nm_flags.bcast = False;
-  nmb->header.nm_flags.recursion_available = 0;
-  nmb->header.nm_flags.recursion_desired = 1;
+  nmb->header.nm_flags.recursion_available = False;
+  nmb->header.nm_flags.recursion_desired = False;
   nmb->header.nm_flags.trunc = False;
   nmb->header.nm_flags.authoritative = False;
   nmb->header.rcode = 0;
@@ -152,6 +152,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
       if ((p2=receive_packet(fd,NMB_PACKET,90)))
        {     
          struct nmb_packet *nmb2 = &p2->packet.nmb;
+      debug_nmb_packet(p2);
+
          if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
              !nmb2->header.response) {
            /* its not for us - maybe deal with it later */
@@ -173,8 +175,6 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
            continue;
          }
 
-      debug_nmb_packet(p2);
-
          _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
          free_packet(p2);
          return(True);
@@ -257,6 +257,8 @@ BOOL name_query(int fd,char *name,int name_type,
       if ((p2=receive_packet(fd,NMB_PACKET,90)))
        {     
          struct nmb_packet *nmb2 = &p2->packet.nmb;
+      debug_nmb_packet(p2);
+
          if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
              !nmb2->header.response) {
            /* its not for us - maybe deal with it later 
@@ -268,8 +270,6 @@ BOOL name_query(int fd,char *name,int name_type,
            continue;
          }
          
-      debug_nmb_packet(p2);
-
          if (nmb2->header.opcode != 0 ||
              nmb2->header.nm_flags.bcast ||
              nmb2->header.rcode ||
index 4801f9e0bd213f6e06a3915649d46158a8803fad..c76dffda00aed8f16dc604362fbcaa558ab837b8 100644 (file)
@@ -120,9 +120,12 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
                 int name_type,
                 struct in_addr ip)
 {                     
-  add_browser_entry(serv_name, name_type, work_name, 0, ip);
+  /* with a domain master we can get the whole list (not local only list) */
+  BOOL local_only = state != NAME_STATUS_DOM_SRV_CHK;
 
-  if (state == NAME_STATUS_PDC_SRV_CHK)
+  add_browser_entry(serv_name, name_type, work_name, 0, ip, local_only);
+
+  if (state == NAME_STATUS_DOM_SRV_CHK)
   {
     /* announce ourselves as a master browser to serv_name */
     do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
@@ -230,7 +233,7 @@ void announce_backup(void)
 /****************************************************************************
   send a host announcement packet
   **************************************************************************/
-static void do_announce_host(int command,
+void do_announce_host(int command,
                char *from_name, int from_type, struct in_addr from_ip,
                char *to_name  , int to_type  , struct in_addr to_ip,
                time_t announce_interval,
@@ -303,45 +306,86 @@ 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;
-
-       if (AM_MASTER(work))
+       BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
+       
+       if (wins_iface && server_type != 0)
        {
-               DEBUG(3,("sending local master announce to %s for %s(1e)\n",
-                                               inet_ntoa(d->bcast_ip),work->work_group));
-
-               do_announce_host(ANN_LocalMasterAnnouncement,
-                                               name            , 0x00, d->myip,
-                                               work->work_group, 0x1e, d->bcast_ip,
-                                               ttl*1000,
-                                               name, server_type, comment);
-
-               DEBUG(3,("sending domain announce to %s for %s\n",
-                                               inet_ntoa(d->bcast_ip),work->work_group));
-
-               /* XXXX should we do a domain-announce-kill? */
-               if (server_type != 0)
+               /* wins pseudo-ip interface */
+               if (!AM_MASTER(work))
                {
-                       if (AM_DOMCTL(work)) {
-                               domain_type |= SV_TYPE_DOMAIN_CTRL;
+                       /* non-master announce by unicast to the domain master */
+                       if (!lp_wins_support() && *lp_wins_server())
+                       {
+                               /* look up the domain master with the WINS server */
+                               queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
+                                        NAME_QUERY_ANNOUNCE_HOST,
+                                        work->work_group,0x1b,0,ttl*1000,
+                                        server_type,name,comment,
+                                        False, False, ipzero, d->bcast_ip);
                        }
-                       do_announce_host(ANN_DomainAnnouncement,
-                                               name    , 0x00, d->myip,
-                                               MSBROWSE, 0x01, d->bcast_ip,
-                                               ttl*1000,
-                                               work->work_group, server_type ? domain_type : 0,
-                                               comment);
+                       else
+                       {
+                               /* we are the WINS server, but not the domain master.
+                                  what's going on??? and we're not going to deal with
+                                  this case, right now
+                                */
+                       }
+               }
+
+               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
+                  use WINS lookup of the domain master if another wins server
+                  is being used! 
+                */
        }
        else
        {
-               DEBUG(3,("sending host announce to %s for %s(1d)\n",
-                                               inet_ntoa(d->bcast_ip),work->work_group));
-
-               do_announce_host(ANN_HostAnnouncement,
-                                               name            , 0x00, d->myip,
-                                               work->work_group, 0x1d, d->bcast_ip,
-                                               ttl*1000,
-                                               name, server_type, comment);
+               if (AM_MASTER(work))
+               {
+                       DEBUG(3,("sending local master announce to %s for %s(1e)\n",
+                                                       inet_ntoa(d->bcast_ip),work->work_group));
+
+                       do_announce_host(ANN_LocalMasterAnnouncement,
+                                                       name            , 0x00, d->myip,
+                                                       work->work_group, 0x1e, d->bcast_ip,
+                                                       ttl*1000,
+                                                       name, server_type, comment);
+
+                       DEBUG(3,("sending domain announce to %s for %s\n",
+                                                       inet_ntoa(d->bcast_ip),work->work_group));
+
+                       /* XXXX should we do a domain-announce-kill? */
+                       if (server_type != 0)
+                       {
+                               if (AM_DOMCTL(work))
+                               {
+                                       domain_type |= SV_TYPE_DOMAIN_CTRL;
+                               }
+                               do_announce_host(ANN_DomainAnnouncement,
+                                                       name    , 0x00, d->myip,
+                                                       MSBROWSE, 0x01, d->bcast_ip,
+                                                       ttl*1000,
+                                                       work->work_group, server_type ? domain_type : 0,
+                                                       comment);
+                       }
+               }
+               else
+               {
+                       DEBUG(3,("sending host announce to %s for %s(1d)\n",
+                                                       inet_ntoa(d->bcast_ip),work->work_group));
+
+                       do_announce_host(ANN_HostAnnouncement,
+                                                       name            , 0x00, d->myip,
+                                                       work->work_group, 0x1d, d->bcast_ip,
+                                                       ttl*1000,
+                                                       name, server_type, comment);
+               }
        }
 }
 
@@ -433,7 +477,7 @@ void announce_host(void)
   least 15 minutes.
   
   this actually gets done in search_and_sync_workgroups() via the
-  NAME_QUERY_PDC_SRV_CHK command, if there is a response from the
+  NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
   name query initiated here.  see response_name_query()
   **************************************************************************/
 void announce_master(void)
@@ -473,7 +517,7 @@ void announce_master(void)
            {
              if (strequal(s->serv.name, myname)) continue;
              
-             /* all PDCs (which should also be master browsers) */
+             /* 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
@@ -485,13 +529,10 @@ void announce_master(void)
                    {
                      if (!lp_wins_support() && *lp_wins_server())
                        {
-                         struct in_addr ip;
-                         ip = ipzero;
-                         
                          queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY,
-                                                NAME_QUERY_PDC_SRV_CHK,
-                                                work->work_group,0x1b,0,0,
-                                                False, False, ip, ip);
+                                                NAME_QUERY_DOM_SRV_CHK,
+                                                work->work_group,0x1b,0,0,0,NULL,NULL,
+                                                False, False, ipzero, ipzero);
                        }
                      else
                        {
@@ -499,8 +540,8 @@ void announce_master(void)
                          for (d2 = subnetlist; d2; d2 = d2->next)
                            {
                              queue_netbios_packet(d,ClientNMB,NMB_QUERY,
-                                                  NAME_QUERY_PDC_SRV_CHK,
-                                                  work->work_group,0x1b,0,0,
+                                                  NAME_QUERY_DOM_SRV_CHK,
+                                                  work->work_group,0x1b,0,0,0,NULL,NULL,
                                                   True, False, d2->bcast_ip, d2->bcast_ip);
                            }
                        }
@@ -527,14 +568,14 @@ void announce_master(void)
                bcast = True;
              }
 
-             DEBUG(2, ("Searching for PDC %s at %s\n",
+             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_PDC_SRV_CHK,
-                                    work->work_group,0x1b, 0, 0,
+             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);
            }
        }
index e62aa1ec6db7c2fa1eefcfb9927fc948f6a9c343..b426bc7a15005404137016c35ab6664a5b1e37d1 100644 (file)
@@ -94,7 +94,7 @@ 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)
+                                             time_t ttl, struct in_addr ip, BOOL local)
 {
   BOOL newentry=False;
   
@@ -135,6 +135,7 @@ 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 */
   
   if (newentry || ttl < b->sync_time) 
     b->sync_time = ttl;
@@ -176,8 +177,9 @@ static void start_sync_browse_entry(struct browse_cache_record *b)
          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,NAME_QUERY_SYNC,
-                                          b->group,0x20,0,0,
+      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);
   }
 
index 37a9fe9c31e812f9c023b4e4e65c27e5202b9200..177c36fc07edd16b7d64ceaf1f5591d730a6bbcc 100644 (file)
@@ -41,6 +41,27 @@ extern struct subnet_record *subnetlist;
 
 #define WINS_LIST "wins.dat"
 
+uint16 nb_type = 0; /* samba's NetBIOS name type */
+
+
+/****************************************************************************
+  samba's NetBIOS name type
+
+  XXXX maybe functionality could be set: B, M, P or H name registration
+  and resolution could be set through nb_type. just a thought.  
+  ****************************************************************************/
+void set_samba_nb_type(void)
+{
+       if (lp_wins_support() || (*lp_wins_server()))
+       {
+               nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
+       }
+       else
+       {
+               nb_type = NB_BFLAG; /* samba is broadcast-only node type */
+       }
+}
+
 
 /****************************************************************************
   true if two netbios names are equal
@@ -390,7 +411,7 @@ struct name_record *add_netbios_entry(struct subnet_record *d,
     if (!wins && type != 0x1b)
     {
        /* the only broadcast (non-WINS) names we are adding are ours
-          (SELF) and PDC type names */
+          (SELF) and Domain Master type names */
        return NULL;
     }
   }
index c453d9bbec2fbd64fe4b9f83b133c072019b8a80..d89bfe8ae843bbd042faf8dffdaf8ee895c9a87b 100644 (file)
@@ -94,6 +94,7 @@ void remove_response_record(struct subnet_record *d,
 struct response_record *make_response_queue_record(enum state_type state,
                                int id,uint16 fd,
                                int quest_type, char *name,int type, int nb_flags, time_t ttl,
+                               int server_type, char *my_name, char *my_comment,
                                BOOL bcast,BOOL recurse,
                                struct in_addr send_ip, struct in_addr reply_to_ip)
 {
@@ -111,10 +112,13 @@ struct response_record *make_response_queue_record(enum state_type state,
   make_nmb_name(&n->name, name, type, scope);
   n->nb_flags = nb_flags;
   n->ttl = ttl;
+  n->server_type = server_type;
   n->bcast = bcast;
   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);
 
   n->repeat_interval = 1; /* XXXX should be in ms */
   n->repeat_count = 3; /* 3 retries */
index a259f25393ada1b82d4ac03cf1cdac536accc315..5c683e5e49bfbcdb86826da8422d42dae4701907 100644 (file)
@@ -50,6 +50,7 @@ extern struct interface *local_interfaces;
 /* this is our domain/workgroup/server database */
 struct subnet_record *subnetlist = NULL;
 
+extern uint16 nb_type; /* samba's NetBIOS name type */
 
 /****************************************************************************
   add a domain into the list
@@ -166,7 +167,7 @@ void add_subnet_interfaces(void)
        }
 
        /* add the pseudo-ip interface for WINS: 255.255.255.255 */
-       if (lp_wins_support())
+       if (lp_wins_support() || (*lp_wins_server()))
     {
                struct in_addr wins_bcast = ipgrp;
                struct in_addr wins_nmask = ipzero;
@@ -231,8 +232,8 @@ struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
         or register with WINS server, if it's our workgroup */
       if (strequal(lp_workgroup(), name))
        {
-         add_my_name_entry(d,name,0x1e,NB_ACTIVE|NB_GROUP);
-         add_my_name_entry(d,name,0x0 ,NB_ACTIVE|NB_GROUP);
+         add_my_name_entry(d,name,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
+         add_my_name_entry(d,name,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
        }
       /* add samba server name to workgroup list. don't add
          lmhosts server entries to local interfaces */
index 13dde54b2274b5ee2f5c02caa36c4cede868f885..200132304b00de76087c4ff95d7a5b201869cdc2 100644 (file)
@@ -181,7 +181,7 @@ struct work_record *find_workgroupstruct(struct subnet_record *d,
       DEBUG(2,("add any workgroups: initiating browser search on %s\n",
               inet_ntoa(d->bcast_ip)));
       queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
-                            MSBROWSE,0x1,0,0,
+                            MSBROWSE,0x1,0,0,0,NULL,NULL,
                             True,False, d->bcast_ip, d->bcast_ip);
       return NULL;
     }
index 1095f8a7fad2aa7c3da9e727f31aebf78d310fb1..8c93de03a8510eeb68f3440769fdfad63738b95b 100644 (file)
@@ -52,6 +52,7 @@ extern time_t StartupTime;
 
 extern struct subnet_record *subnetlist;
 
+extern uint16 nb_type; /* samba's NetBIOS name type */
 
 /*******************************************************************
   occasionally check to see if the master browser is around
@@ -81,7 +82,7 @@ void check_master_browser(void)
          if (!AM_MASTER(work))
            {
              queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
-                                  work->work_group,0x1d,0,0,
+                                  work->work_group,0x1d,0,0,0,NULL,NULL,
                                   True,False,d->bcast_ip,d->bcast_ip);
            }
        }
@@ -268,7 +269,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
       add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
 
       /* add special browser name */
-      add_my_name_entry(d,MSBROWSE        ,0x01,NB_ACTIVE|NB_GROUP);
+      add_my_name_entry(d,MSBROWSE        ,0x01,nb_type|NB_ACTIVE|NB_GROUP);
 
       /* DON'T do anything else after calling add_my_name_entry() */
       return;
@@ -282,7 +283,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
       add_server_entry(d,work,work->work_group,domain_type,0,myname,True);
 
       /* add master name */
-      add_my_name_entry(d,work->work_group,0x1d,NB_ACTIVE         );
+      add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
   
       /* DON'T do anything else after calling add_my_name_entry() */
       return;
@@ -320,7 +321,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
         DEBUG(3,("domain first stage: register as domain member\n"));
 
         /* add domain member name */
-        add_my_name_entry(d,work->work_group,0x1e,NB_ACTIVE         );
+        add_my_name_entry(d,work->work_group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
 
         /* DON'T do anything else after calling add_my_name_entry() */
         return;
@@ -347,7 +348,7 @@ void become_master(struct subnet_record *d, struct work_record *work)
         }
 
         /* add domain master name */
-        add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE         );
+        add_my_name_entry(d,work->work_group,0x1b,nb_type|NB_ACTIVE         );
 
         /* DON'T do anything else after calling add_my_name_entry() */
         return;
index 0f76323df0bb52e5ec0e5d700956a65e6a2641f0..7fcb41e79f0623738d80b0e65018315b764910e0 100644 (file)
@@ -224,6 +224,7 @@ void expire_netbios_response_entries()
 struct response_record *queue_netbios_pkt_wins(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,
                                struct in_addr send_ip, struct in_addr reply_to_ip)
 {
@@ -256,6 +257,7 @@ struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
 
   return queue_netbios_packet(d,fd, quest_type, state, 
                       name, name_type, nb_flags, ttl,
+               server_type,my_name,my_comment,
                       bcast, recurse, send_ip, reply_to_ip);
 }
 
@@ -269,8 +271,9 @@ struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
 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,
-                           BOOL bcast,BOOL recurse,
-                               struct in_addr send_ip, struct in_addr reply_to_ip)
+                       int server_type, char *my_name, char *my_comment,
+                   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;
@@ -289,6 +292,7 @@ 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)))
     {
       add_response_record(d,n);
index 93cc59741534e4fe51ca1f90c6929e9dc2151cae..da1480961f1ee2d887ecbd8652750ee08376dcfa 100644 (file)
@@ -43,6 +43,7 @@ extern struct in_addr ipgrp;
 
 extern struct subnet_record *subnetlist;
 
+extern uint16 nb_type; /* samba's NetBIOS type */
 
 /****************************************************************************
   remove an entry from the name list
@@ -90,7 +91,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
          server, or if no reply is received, then we can remove the name */
 
         queue_netbios_pkt_wins(d,ClientNMB,NMB_REL,NAME_RELEASE,
-                 name, type, 0, 0,
+                 name, type, 0, 0,0,NULL,NULL,
                  False, True, ipzero, ipzero);
     }
   }
@@ -101,7 +102,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type)
         then we can remove the name. */
 
      queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
-                            name, type, 0, 0,
+                            name, type, 0, 0,0,NULL,NULL,
                             True, True, d->bcast_ip, d->bcast_ip);
   }
 }
@@ -151,7 +152,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
       /* a time-to-live allows us to refresh this name with the WINS server. */
          queue_netbios_pkt_wins(d,ClientNMB,
                                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
-                            name, type, nb_flags, GET_TTL(0),
+                            name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
                             False, True, ipzero, ipzero);
     }
   }
@@ -160,7 +161,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
     /* broadcast the packet, but it comes from ipzero */
        queue_netbios_packet(d,ClientNMB,
                                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
-                            name, type, nb_flags, GET_TTL(0),
+                            name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
                             True, True, d->bcast_ip, ipzero);
   }
 }
@@ -186,20 +187,20 @@ void add_my_names(void)
   {
     BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
 
-       add_my_name_entry(d, myname,0x20,NB_ACTIVE);
-       add_my_name_entry(d, myname,0x03,NB_ACTIVE);
-       add_my_name_entry(d, myname,0x00,NB_ACTIVE);
-       add_my_name_entry(d, myname,0x1f,NB_ACTIVE);
+       add_my_name_entry(d, myname,0x20,nb_type|NB_ACTIVE);
+       add_my_name_entry(d, myname,0x03,nb_type|NB_ACTIVE);
+       add_my_name_entry(d, myname,0x00,nb_type|NB_ACTIVE);
+       add_my_name_entry(d, myname,0x1f,nb_type|NB_ACTIVE);
 
     /* these names are added permanently (ttl of zero) and will NOT be
        refreshed with the WINS server  */
-       add_netbios_entry(d,"*",0x0,NB_ACTIVE,0,SELF,ip,False,wins);
-       add_netbios_entry(d,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
-       add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
+       add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
+       add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
+       add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,ip,False,wins);
 
     if (!wins_iface && lp_domain_logons() && lp_domain_master()) {
        /* XXXX the 0x1c is apparently something to do with domain logons */
-         add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
+         add_my_name_entry(d, my_workgroup(),0x1c,nb_type|NB_ACTIVE|NB_GROUP);
     }
   }
   if (lp_domain_master() && (d = find_subnet(ipgrp)))
@@ -310,7 +311,7 @@ void query_refresh_names(void)
                  
          queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
                                n->name.name, n->name.name_type,
-                               0,0,
+                               0,0,0,NULL,NULL,
                                False,False,n->ip,n->ip);
                  count++;
                }
index 84b9277d603b8733dabd115ac762ecf3865227c0..5b45e88c5e733b76472b04db10ab0cce64f6942f 100644 (file)
@@ -294,7 +294,8 @@ void reply_name_reg(struct packet_struct *p)
     /* initiate some enquiries to the current owner. */
        queue_netbios_packet(d,ClientNMB,NMB_QUERY,
                                                 NAME_REGISTER_CHALLENGE,
-                                                reply_name->name,reply_name->name_type,nb_flags,0,
+                                                reply_name->name,reply_name->name_type,
+                            nb_flags,0,0,NULL,NULL,
                                                 False, False, n->ip, p->ip);
   }
   else
@@ -311,8 +312,11 @@ void reply_name_reg(struct packet_struct *p)
 
 
 /****************************************************************************
-reply to a name status query
-****************************************************************************/
+  reply to a name status query
+
+  combine the list of the local interface on which the query was made with
+  the names registered via wins.
+  ****************************************************************************/
 void reply_name_status(struct packet_struct *p)
 {
   struct nmb_packet *nmb = &p->packet.nmb;
@@ -323,7 +327,7 @@ void reply_name_status(struct packet_struct *p)
   int names_added;
   struct name_record *n;
   struct subnet_record *d = NULL;
-  int search = FIND_SELF;
+  int search = FIND_SELF | FIND_WINS;
 
   BOOL bcast = nmb->header.nm_flags.bcast;
   
@@ -338,8 +342,6 @@ void reply_name_status(struct packet_struct *p)
           namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
   
   if (bcast)
-    search |= FIND_WINS;
-  else
     search |= FIND_LOCAL;
 
   n = find_name_search(&d, &nmb->question.question_name,
@@ -353,38 +355,55 @@ void reply_name_status(struct packet_struct *p)
   buf += 1;
   
   names_added = 0;
-  
-  for (n = d->namelist ; n && buf < bufend; n = n->next) 
+
+  n = d->namelist;
+
+  while (buf < bufend) 
+  {
+    if (n->source == SELF)
     {
       int name_type = n->name.name_type;
       
-      if (n->source != SELF) continue;
-      
-      /* start with first bit of putting info in buffer: the name */
-      
-      bzero(buf,18);
-         sprintf(buf,"%-15.15s",n->name.name);
-      strupper(buf);
-      
-      /* now check if we want to exclude other workgroup names
-        from the response. if we don't exclude them, windows clients
-        get confused and will respond with an error for NET VIEW */
-      
-      if (name_type >= 0x1b && name_type <= 0x20 && 
-         ques_type >= 0x1b && ques_type <= 0x20)
-       {
-         if (!strequal(qname, n->name.name)) continue;
-       }
-      
-      /* carry on putting name info in buffer */
+      /* check if we want to exclude other workgroup names
+            from the response. if we don't exclude them, windows clients
+            get confused and will respond with an error for NET VIEW */
       
-      buf[15] = name_type;
-      buf[16]  = n->nb_flags;
+      if (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 */
+        bzero(buf,18);
+           sprintf(buf,"%-15.15s",n->name.name);
+        strupper(buf);
+        
+        /* put name type and netbios flags in buffer */
+        buf[15] = name_type;
+        buf[16]  = n->nb_flags;
+        
+        buf += 18;
       
-      buf += 18;
-      
-      names_added++;
+        names_added++;
+      }
     }
+
+    n = n->next;
+
+    if (!n)
+    {
+      /* end of this name list: add wins names too? */
+      struct subnet_record *w_d;
+
+      if (!(w_d = find_subnet(ipgrp))) break;
+
+      if (w_d != d)
+      {
+        d = w_d;
+        n = d->namelist; /* start on the wins name list */
+      }
+       }
+       if (!n) break;
+  }
   
   SCVAL(countptr,0,names_added);
   
@@ -396,9 +415,7 @@ void reply_name_status(struct packet_struct *p)
     SIVAL(buf,24,num_good_receives);
   }
   
-  SIVAL(buf,46,0xFFB8E5); /* undocumented - used by NT */
-  
-  buf += 64;
+  buf += 46;
   
   /* Send a POSITIVE NAME STATUS RESPONSE */
   reply_netbios_packet(p,nmb->header.name_trn_id,
@@ -451,14 +468,13 @@ void reply_name_query(struct packet_struct *p)
   struct name_record *n;
 
   /* directed queries are for WINS server: broadcasts are local SELF queries.
-     the exception is PDC names.  */
+     the exception is Domain Master names.  */
 
   int search = bcast ? FIND_LOCAL | FIND_SELF : FIND_WINS;
   
-  if (name_type == 0x1b)
+  if (name_type == 0x1b || name_type == 0x0 || name_type == 0x20)
   {
-    /* even if it's a broadcast, we don't ignore queries for PDC names */
-    search = FIND_WINS;
+    search |= FIND_WINS;
   }
 
   if (search | FIND_LOCAL)
@@ -500,10 +516,11 @@ void reply_name_query(struct packet_struct *p)
            }
          }
       
-      /* name is directed query, or it's self, or it's a PDC type name, or
-            we're replying on behalf of a caller because they are on a different
-         subnet and cannot hear the broadcast. XXXX lp_wins_proxy should be
-                switched off in environments where broadcasts are forwarded */
+      /* name is directed query, or it's self, or it's a Domain Master type
+         name, or we're replying on behalf of a caller because they are on a
+         different subnet and cannot hear the broadcast. XXXX lp_wins_proxy
+         should be switched off in environments where broadcasts are forwarded
+       */
 
       /* XXXX note: for proxy servers, we should forward the query on to
          another WINS server if the name is not in our database, or we are
index 46acc2b99276ed56d2bd62a4112563228654ef43..a4cda7cdfb5a412dbcce1de5036f68f5a648372c 100644 (file)
@@ -124,7 +124,66 @@ static void response_name_reg(struct subnet_record *d, struct packet_struct *p)
 
 
 /****************************************************************************
-  response from a name query server check. states of type NAME_QUERY_PDC_SRV_CHK,
+  response from a name query announce host
+  NAME_QUERY_ANNOUNCE_HOST is dealt with here
+  ****************************************************************************/
+static void response_announce_host(struct nmb_name *ans_name, 
+               struct nmb_packet *nmb, 
+               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. */
+               /* XXXX should say to them 'oi! release that name!' */
+
+               DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
+               return;
+       }
+
+       if (nmb->header.rcode == 0 && nmb->answers->rdata)
+    {
+               /* we had sent out a name query to the current owner
+                  of a name because someone else wanted it. now they
+                  have responded saying that they still want the name,
+                  so the other host can't have it.
+                */
+
+               /* first check all the details are correct */
+
+               int nb_flags = nmb->answers->rdata[0];
+               struct in_addr found_ip;
+
+               putip((char*)&found_ip,&nmb->answers->rdata[2]);
+
+               if (nb_flags != n->nb_flags)
+               {
+                       /* someone gave us the wrong nb_flags as a reply. oops. */
+                       /* XXXX should say to them 'oi! release that name!' */
+
+                       DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
+                       DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
+                       return;
+               }
+
+       /* do an announce host */
+       do_announce_host(ANN_HostAnnouncement,
+                               n->my_name  , 0x00, d->myip,
+                               n->name.name, 0x1d, found_ip,
+                               n->ttl,
+                               n->my_name, n->server_type, n->my_comment);
+       }
+       else
+       {
+               /* XXXX negative name query response. no master exists. oops */
+       }
+}
+
+
+/****************************************************************************
+  response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
   NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
   ****************************************************************************/
 static void response_server_check(struct nmb_name *ans_name, 
@@ -132,13 +191,13 @@ static void response_server_check(struct nmb_name *ans_name,
 {
     /* issue another state: this time to do a name status check */
 
-    enum state_type cmd = (n->state == NAME_QUERY_PDC_SRV_CHK) ?
-             NAME_STATUS_PDC_SRV_CHK : NAME_STATUS_SRV_CHK;
+    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 */
     queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
                                ans_name->name, ans_name->name_type,
-                               0,0,
+                               0,0,0,NULL,NULL,
                                False,False,n->send_ip,n->reply_to_ip);
 }
 
@@ -185,7 +244,7 @@ static BOOL interpret_node_status(struct subnet_record *d,
       if (NAME_BFLAG    (nb_flags)) { strcat(flags,"B "); }
       if (NAME_PFLAG    (nb_flags)) { strcat(flags,"P "); }
       if (NAME_MFLAG    (nb_flags)) { strcat(flags,"M "); }
-      if (NAME__FLAG    (nb_flags)) { strcat(flags,"_ "); }
+      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_ACTIVE   (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
@@ -236,7 +295,7 @@ static BOOL interpret_node_status(struct subnet_record *d,
 
 
 /****************************************************************************
-  response from a name status check. states of type NAME_STATUS_PDC_SRV_CHK
+  response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
   and NAME_STATUS_SRV_CHK dealt with here.
   ****************************************************************************/
 static void response_name_status_check(struct in_addr ip,
@@ -380,14 +439,17 @@ static void response_name_query_sync(struct nmb_packet *nmb,
 
                DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
 
-               if (n->state == NAME_QUERY_SYNC)
+               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;
+
                                /* the server is there: sync quick before it (possibly) dies! */
                                sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
-                                                       found_ip);
+                                                       found_ip, local_list_only);
                        }
                }
                else
@@ -439,17 +501,23 @@ void debug_state_type(int state)
   /* report the state type to help debugging */
   switch (state)
   {
-    case NAME_QUERY_PDC_SRV_CHK : DEBUG(4,("MASTER_SVR_CHECK\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_STATUS_PDC_SRV_CHK: DEBUG(4,("NAME_STAT_MST_CHK\n")); break;
-    case NAME_STATUS_SRV_CHK    : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
-    case NAME_QUERY_MST_CHK     : DEBUG(4,("NAME_QUERY_MST_CHK\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_QUERY_CONFIRM     : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
-    case NAME_QUERY_SYNC        : DEBUG(4,("NAME_QUERY_SYNC\n")); break;
+    case NAME_QUERY_DOM_SRV_CHK  : DEBUG(4,("MASTER_SVR_CHECK\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;
+    case NAME_QUERY_CONFIRM      : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
+    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_SRV_CHK     : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
+
     default: break;
   }
 }
@@ -512,7 +580,8 @@ static BOOL response_problem_check(struct response_record *n,
                   /* query for ^1^2__MSBROWSE__^2^1 expect lots of responses */
                   return False;
                 }
-                       case NAME_QUERY_PDC_SRV_CHK:
+                       case NAME_QUERY_ANNOUNCE_HOST:
+                       case NAME_QUERY_DOM_SRV_CHK:
                 case NAME_QUERY_SRV_CHK:
                 case NAME_QUERY_MST_CHK:
                 {
@@ -576,8 +645,10 @@ static BOOL response_compatible(struct response_record *n,
 
     case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
     case NAME_QUERY_CONFIRM:
-    case NAME_QUERY_SYNC:
-    case NAME_QUERY_PDC_SRV_CHK:
+    case NAME_QUERY_ANNOUNCE_HOST:
+    case NAME_QUERY_SYNC_LOCAL:
+    case NAME_QUERY_SYNC_REMOTE:
+    case NAME_QUERY_DOM_SRV_CHK:
     case NAME_QUERY_SRV_CHK:
     case NAME_QUERY_FIND_MST:
     case NAME_QUERY_MST_CHK:
@@ -590,7 +661,7 @@ static BOOL response_compatible(struct response_record *n,
                break;
     }
       
-    case NAME_STATUS_PDC_SRV_CHK:
+    case NAME_STATUS_DOM_SRV_CHK:
     case NAME_STATUS_SRV_CHK:
     {
                if (nmb->answers->rr_type != NMB_STATUS)
@@ -638,7 +709,7 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
         break;
     }
 
-    case NAME_QUERY_PDC_SRV_CHK:
+    case NAME_QUERY_DOM_SRV_CHK:
     case NAME_QUERY_SRV_CHK:
     case NAME_QUERY_FIND_MST:
     {
@@ -646,15 +717,22 @@ static void response_process(struct subnet_record *d, struct packet_struct *p,
                break;
     }
       
-    case NAME_STATUS_PDC_SRV_CHK:
+    case NAME_STATUS_DOM_SRV_CHK:
     case NAME_STATUS_SRV_CHK:
     {
                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;
+    }
+      
     case NAME_QUERY_CONFIRM:
-    case NAME_QUERY_SYNC:
+    case NAME_QUERY_SYNC_LOCAL:
+    case NAME_QUERY_SYNC_REMOTE:
     {
                response_name_query_sync(nmb, ans_name, bcast, n, d);
                break;
@@ -702,7 +780,8 @@ void response_netbios_packet(struct packet_struct *p)
     return;
   }
 
-  if (!same_net(d->bcast_ip, d->mask_ip, p->ip)) /* copes with WINS 'subnet' */
+  /* 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)));
index 1a7a48aa9a74f08d8308fc43bb808701b645da17..74c567fa748116c342072c4fe47c07d94f3e078e 100644 (file)
@@ -284,17 +284,12 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
   tell_become_backup();
 #endif
 
-  /* XXXX over-kill: i don't think we should really be doing this,
-     but it doesn't do much harm other than to add extra network
-     traffic. to be more precise, we should (possibly) only
-     sync browse lists with a host that sends an
-     ANN_LocalMasterAnnouncement or an ANN_DomainAnnouncement.
-     possibly.
-   */
-
-  /* get their browse list from them and add it to ours. */
-  add_browser_entry(serv_name,dgram->dest_name.name_type,
-                   work->work_group,30,ip);
+  /* get the local_only browse list from the local master and add it to ours. */
+  if (command == ANN_LocalMasterAnnouncement)
+  {
+    add_browser_entry(serv_name,dgram->dest_name.name_type,
+                   work->work_group,30,ip,True);
+  }
 }
 
 /*******************************************************************
@@ -319,13 +314,13 @@ static void process_master_announce(struct packet_struct *p,char *buf)
   if (!lp_domain_master()) return;
   
   for (work = mydomain->workgrouplist; work; work = work->next)
+  {
+    if (AM_MASTER(work))
     {
-      if (AM_MASTER(work))
-       {
          /* merge browse lists with them */
-         add_browser_entry(name,0x1b, work->work_group,30,ip);
-       }
+         add_browser_entry(name,0x1b, work->work_group,30,ip,True);
     }
+  }
 }
 
 /*******************************************************************
@@ -394,7 +389,8 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
                  if (work->token == 0 /* token */)
                  {
                      queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
-                                          work->work_group,0x1d,0,0,
+                                          work->work_group,0x1d,
+                       0,0,0,NULL,NULL,
                                           False,False,back_ip,back_ip);
                      return;
                  }
index 10b356d9b5019183b8f67ec50a16bea307e9d8da..e2a4bdeb67ff62e8fd45eb930fc3d30a44794f81 100644 (file)
@@ -53,7 +53,6 @@ time_t StartupTime =0;
 
 extern struct in_addr ipzero;
 
-
  /****************************************************************************
   catch a sigterm
   ****************************************************************************/
@@ -90,6 +89,8 @@ static int sig_hup(void)
   dump_names();
   reload_services(True);
 
+  set_samba_nb_type();
+
   BlockSignals(False);
 #ifndef DONT_REINSTALL_SIG
   signal(SIGHUP,SIGNAL_CAST sig_hup);
@@ -524,6 +525,8 @@ static void usage(char *pname)
   if (!reload_services(False))
     return(-1);        
 
+  set_samba_nb_type();
+
   if (*group)
     add_my_subnets(group);
 
index de3d9e873316a6ee45e0edeaca181c1dc8fb54b2..2efb364bcae5a929ced3f5dd912d8e2c886b27b7 100644 (file)
@@ -136,8 +136,10 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv
   do a NetServerEnum and update our server and workgroup databases.
   ******************************************************************/
 void sync_browse_lists(struct subnet_record *d, struct work_record *work,
-               char *name, int nm_type, struct in_addr ip)
+               char *name, int nm_type, struct in_addr ip, BOOL local)
 {
+  uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
+
   if (!d || !work || !AM_MASTER(work)) return;
 
   pid = getpid();
@@ -169,8 +171,9 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work,
     {
       if (cli_send_login(NULL,NULL,True,True))
        {
-         add_info(d, work, SV_TYPE_DOMAIN_ENUM);
-         add_info(d, work, SV_TYPE_ALL&~SV_TYPE_DOMAIN_ENUM);
+         add_info(d, work, local_type|SV_TYPE_DOMAIN_ENUM);
+         add_info(d, work, local_type|(SV_TYPE_ALL&
+                      ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY)));
        }
       
       close_sockets();
index a543b90762f77c32e277ff47c07e20933db22f4b..292b526df9346709833064737b219a38a371dfad 100644 (file)
@@ -49,7 +49,7 @@ static BOOL open_sockets(void)
       return False;
     }   
 
-  ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
+  ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
 
   if (ServerFD == -1)
     return(False);
@@ -151,7 +151,7 @@ int main(int argc,char *argv[])
 
 
   for (i=optind;i<argc;i++)
-    {
+  {
       BOOL bcast = True;
       int retries = 2;
       char *p;
@@ -177,20 +177,18 @@ int main(int argc,char *argv[])
        retries = 1;
       }
 
-      if (name_query(ServerFD,lookup,lookup_type,bcast,True,
+    if (name_query(ServerFD,lookup,lookup_type,bcast,True,
                     *iface_bcast(ipzero),&ip,NULL)) 
        {
          printf("%s %s\n",inet_ntoa(ip),lookup);
-         if (find_status) 
-           {
+    }
+       if (find_status) 
+       {
              printf("Looking up status of %s\n",inet_ntoa(ip));
              name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
              printf("\n");
-           }
-      } else {
-       printf("couldn't find name %s\n",lookup);
-      }
-    }
+       }
+  }
 
   return(0);
 }