lots of changes to nmbd
authorSamba Release Account <samba-bugs@samba.org>
Wed, 17 Jul 1996 18:33:36 +0000 (18:33 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Wed, 17 Jul 1996 18:33:36 +0000 (18:33 +0000)
lkcl
(This used to be commit 45d3b2644733333c657c48a69719fec72881f7df)

19 files changed:
source3/client/client.c
source3/include/nameserv.h
source3/include/proto.h
source3/include/version.h
source3/libsmb/namequery.c
source3/nameannounce.c
source3/namedbname.c
source3/namedbserver.c
source3/nameelect.c
source3/namepacket.c
source3/nameresp.c
source3/nameresp.doc
source3/nameserv.c
source3/nameservreply.c
source3/nameservresp.c
source3/namework.c
source3/nmbd/nmbd.c
source3/smbd/ipc.c
source3/utils/nmblookup.c

index 2eb4be7d132e298d206b650ae7d45163a8eba2df..14a6e20ab588078ba23bab936172ba71b62d3c89 100644 (file)
@@ -3585,7 +3585,7 @@ static void server_info()
 /****************************************************************************
 try and browse available connections on a host
 ****************************************************************************/
 /****************************************************************************
 try and browse available connections on a host
 ****************************************************************************/
-static BOOL list_servers()
+static BOOL list_servers(char *wk_grp)
 {
   char *rparam = NULL;
   char *rdata = NULL;
 {
   char *rparam = NULL;
   char *rdata = NULL;
@@ -3600,7 +3600,7 @@ static BOOL list_servers()
   p = param;
   SSVAL(p,0,0x68); /* api number */
   p += 2;
   p = param;
   SSVAL(p,0,0x68); /* api number */
   p += 2;
-  strcpy(p,"WrLehDO");
+  strcpy(p,"WrLehDz");
   p = skip_string(p,1);
 
   strcpy(p,"B16BBDz");
   p = skip_string(p,1);
 
   strcpy(p,"B16BBDz");
@@ -3615,6 +3615,11 @@ static BOOL list_servers()
 
   SIVAL(p,0,SV_TYPE_ALL);
 
 
   SIVAL(p,0,SV_TYPE_ALL);
 
+  p += 4;
+
+  strcpy(p, wk_grp);
+  p = skip_string(p,1);
+
   if (call_api(PTR_DIFF(p+4,param),0,
               8,10000,
               &rprcnt,&rdrcnt,
   if (call_api(PTR_DIFF(p+4,param),0,
               8,10000,
               &rprcnt,&rdrcnt,
@@ -3638,9 +3643,10 @@ static BOOL list_servers()
        for (i=0;i<count;i++) {
          char *sname = p2;
          int comment_offset = IVAL(p2,22) & 0xFFFF;
        for (i=0;i<count;i++) {
          char *sname = p2;
          int comment_offset = IVAL(p2,22) & 0xFFFF;
-         printf("\t%-16.16s     %s\n",
+         uint32 stype = IVAL(p2,18);
+         printf("\t%-16.16s     %s %8x\n",
                 sname,
                 sname,
-                comment_offset?rdata+comment_offset-converter:"");
+                comment_offset?rdata+comment_offset-converter:"", stype);
 
          ok=True;
          p2 += 26;
 
          ok=True;
          p2 += 26;
@@ -3651,7 +3657,7 @@ static BOOL list_servers()
   if (rparam) {free(rparam); rparam = NULL;}
   if (rdata) {free(rdata); rdata = NULL;}
 
   if (rparam) {free(rparam); rparam = NULL;}
   if (rdata) {free(rdata); rdata = NULL;}
 
-  SIVAL(p,0,SV_TYPE_DOMAIN_ENUM);
+  SIVAL(p,0,0x7fffffff);
 
   if (call_api(PTR_DIFF(p+4,param),0,
               8,10000,
 
   if (call_api(PTR_DIFF(p+4,param),0,
               8,10000,
@@ -3676,9 +3682,10 @@ static BOOL list_servers()
        for (i=0;i<count;i++) {
          char *sname = p2;
          int comment_offset = IVAL(p2,22) & 0xFFFF;
        for (i=0;i<count;i++) {
          char *sname = p2;
          int comment_offset = IVAL(p2,22) & 0xFFFF;
-         printf("\t%-16.16s     %s\n",
+         uint32 stype =IVAL(p2,18);
+         printf("\t%-16.16s     %s %8x\n",
                 sname,
                 sname,
-                comment_offset?rdata+comment_offset-converter:"");
+                comment_offset?rdata+comment_offset-converter:"",stype);
          
          ok=True;
          p2 += 26;
          
          ok=True;
          p2 += 26;
@@ -4391,9 +4398,9 @@ static void usage(char *pname)
            sleep(1);
            browse_host(True);
          }
            sleep(1);
            browse_host(True);
          }
-         if (!list_servers()) {
+         if (!list_servers(workgroup)) {
            sleep(1);
            sleep(1);
-           list_servers();
+           list_servers(workgroup);
          }
 
          send_logout();
          }
 
          send_logout();
index de5e492644abfe20115d0f791d18b0b509f2eeba..b634250c8116bf8f0dc840d7da2f7d09e877110c 100644 (file)
 enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
 enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
 enum packet_type {NMB_PACKET, DGRAM_PACKET};
 enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
 enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
 enum packet_type {NMB_PACKET, DGRAM_PACKET};
-enum master_state { MST_NONE, MST_WON, MST_MSB, MST_BROWSER, MST_DOMAIN };
+enum master_state
+{
+   MST_NONE,
+   MST_WON,
+   MST_MSB,
+   MST_BROWSER,
+   MST_DOMAIN_NONE,
+   MST_DOMAIN_MEM,
+   MST_DOMAIN_TST,
+   MST_DOMAIN
+};
 
 enum state_type
 {
 
 enum state_type
 {
index 2286b93a6d58e8392d3aea7c39b2fd8970838757..e7225a7271985f17951e0b352454570981534d9b 100644 (file)
@@ -256,7 +256,7 @@ BOOL ms_browser_name(char *name, int type);
 void remove_name(struct subnet_record *d, struct name_record *n);
 struct name_record *find_name(struct name_record *n,
                        struct nmb_name *name,
 void remove_name(struct subnet_record *d, struct name_record *n);
 struct name_record *find_name(struct name_record *n,
                        struct nmb_name *name,
-                       int search, struct in_addr ip);
+                       int search);
 struct name_record *find_name_search(struct subnet_record **d,
                        struct nmb_name *name,
                        int search, struct in_addr ip);
 struct name_record *find_name_search(struct subnet_record **d,
                        struct nmb_name *name,
                        int search, struct in_addr ip);
@@ -286,6 +286,7 @@ struct response_record *find_response_record(struct subnet_record **d,
                                uint16 id);
 void remove_old_servers(struct work_record *work, time_t t,
                                        BOOL remove_all);
                                uint16 id);
 void remove_old_servers(struct work_record *work, time_t t,
                                        BOOL remove_all);
+struct server_record *find_server(struct work_record *work, char *name);
 struct server_record *add_server_entry(struct subnet_record *d, 
                                       struct work_record *work,
                                       char *name,int servertype, 
 struct server_record *add_server_entry(struct subnet_record *d, 
                                       struct work_record *work,
                                       char *name,int servertype, 
@@ -320,12 +321,13 @@ void run_elections(void);
 void process_election(struct packet_struct *p,char *buf);
 BOOL check_elections(void);
 void process_logon_packet(struct packet_struct *p,char *buf,int len);
 void process_election(struct packet_struct *p,char *buf);
 BOOL check_elections(void);
 void process_logon_packet(struct packet_struct *p,char *buf,int len);
+void debug_browse_data(char *outbuf, int len);
 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);
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
 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);
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
-                               int rcode,int opcode, BOOL recurse,
+                               int rcode, int rcv_code, int opcode, BOOL recurse,
                                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
                                char *data,int len);
 void queue_packet(struct packet_struct *packet);
                                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
                                char *data,int len);
 void queue_packet(struct packet_struct *packet);
@@ -357,11 +359,12 @@ void add_my_names(void);
 void remove_my_names();
 void refresh_my_names(time_t t);
 void query_refresh_names(void);
 void remove_my_names();
 void refresh_my_names(time_t t);
 void query_refresh_names(void);
-void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
+void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
+                               uint16 response_id,
                                struct nmb_name *name,
                                int nb_flags, int ttl, struct in_addr register_ip,
                                BOOL new_owner, struct in_addr reply_to_ip);
                                struct nmb_name *name,
                                int nb_flags, int ttl, struct in_addr register_ip,
                                BOOL new_owner, struct in_addr reply_to_ip);
-void send_name_response(int fd,
+void send_name_response(int fd, struct in_addr from_ip,
                                int name_trn_id, int opcode, BOOL success, BOOL recurse,
                                struct nmb_name *reply_name, int nb_flags, int ttl,
                                struct in_addr ip);
                                int name_trn_id, int opcode, BOOL success, BOOL recurse,
                                struct nmb_name *reply_name, int nb_flags, int ttl,
                                struct in_addr ip);
@@ -369,6 +372,7 @@ void reply_name_release(struct packet_struct *p);
 void reply_name_reg(struct packet_struct *p);
 void reply_name_status(struct packet_struct *p);
 void reply_name_query(struct packet_struct *p);
 void reply_name_reg(struct packet_struct *p);
 void reply_name_status(struct packet_struct *p);
 void reply_name_query(struct packet_struct *p);
+void debug_state_type(int state);
 void response_netbios_packet(struct packet_struct *p);
 void reset_server(char *name, int state, struct in_addr ip);
 void tell_become_backup(void);
 void response_netbios_packet(struct packet_struct *p);
 void reset_server(char *name, int state, struct in_addr ip);
 void tell_become_backup(void);
index 964411164ddda6a36eef221384cbf64449ac71ee..7bde637b18438c038108d3b8a168210fbe3f3110 100644 (file)
@@ -1 +1 @@
-#define VERSION "1.9.16alpha10"
+#define VERSION "1.9.16a10"
index d1b1ae7d3e5c976b7af299d22011d7c46789f8bf..54809130017362c728643397ead2421b8f22a8cb 100644 (file)
@@ -173,6 +173,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
            continue;
          }
 
            continue;
          }
 
+      debug_nmb_packet(p2);
+
          _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
          free_packet(p2);
          return(True);
          _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
          free_packet(p2);
          return(True);
@@ -266,6 +268,8 @@ BOOL name_query(int fd,char *name,int name_type,
            continue;
          }
          
            continue;
          }
          
+      debug_nmb_packet(p2);
+
          if (nmb2->header.opcode != 0 ||
              nmb2->header.nm_flags.bcast ||
              nmb2->header.rcode ||
          if (nmb2->header.opcode != 0 ||
              nmb2->header.nm_flags.bcast ||
              nmb2->header.rcode ||
index 63dfc1555b0428c90494ec830d37c9ef9e74922c..3107d02c1498da6dc93f884ad61db4898150c216 100644 (file)
@@ -48,7 +48,7 @@ extern  pstring ServerComment;
 extern int  updatecount;
 extern int  workgroup_count;
 
 extern int  updatecount;
 extern int  workgroup_count;
 
-/* what server type are we currently */
+extern struct in_addr ipgrp;
 
 /****************************************************************************
   send a announce request to the local net
 
 /****************************************************************************
   send a announce request to the local net
@@ -146,12 +146,19 @@ void announce_backup(void)
   char *p;
   struct subnet_record *d1;
   int tok;
   char *p;
   struct subnet_record *d1;
   int tok;
+  static uint32 id_count = 0;
   
   if (!lastrun) lastrun = t;
   
   if (!lastrun) lastrun = t;
+#if 1
+  if (t < lastrun + 1 * 60)
+#else
   if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
   if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
+#endif
        return;
   lastrun = t;
   
        return;
   lastrun = t;
   
+  DEBUG(4,("checking backups...\n"));
+
   for (tok = 0; tok <= workgroup_count; tok++)
     {
       for (d1 = subnetlist; d1; d1 = d1->next)
   for (tok = 0; tok <= workgroup_count; tok++)
     {
       for (d1 = subnetlist; d1; d1 = d1->next)
@@ -178,14 +185,15 @@ void announce_backup(void)
              
              bzero(outbuf,sizeof(outbuf));
              p = outbuf;
              
              bzero(outbuf,sizeof(outbuf));
              p = outbuf;
+
              CVAL(p,0) = ANN_GetBackupListReq;
              CVAL(p,0) = ANN_GetBackupListReq;
-             p++;
-             
-             CVAL(p,0) = 1; /* count? */
-             SIVAL(p,1,work->token); /* workgroup unique key index */
-             p += 5;
-             p++;
+             CVAL(p,1) = work->token; /* workgroup unique key index */
+             SIVAL(p,2,++id_count); /* unique count. not that we use it! */
+
+             p += 6;
              
              
+          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
+
              if (!AM_DOMCTL(work))
           {
             /* only ask for a list of backup domain controllers
              if (!AM_DOMCTL(work))
           {
             /* only ask for a list of backup domain controllers
@@ -199,6 +207,8 @@ void announce_backup(void)
                                  *iface_ip(d->bcast_ip));
           }
 
                                  *iface_ip(d->bcast_ip));
           }
 
+          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
+
              if (!AM_MASTER(work))
           {
             /* only ask for a list of master browsers if we
              if (!AM_MASTER(work))
           {
             /* only ask for a list of master browsers if we
@@ -208,7 +218,7 @@ void announce_backup(void)
                                  ClientDGRAM,outbuf,
                                  PTR_DIFF(p,outbuf),
                                  myname, work->work_group,
                                  ClientDGRAM,outbuf,
                                  PTR_DIFF(p,outbuf),
                                  myname, work->work_group,
-                                 0x0,0x1b,d->bcast_ip,
+                                 0x0,0x1d,d->bcast_ip,
                                  *iface_ip(d->bcast_ip));
           }
            }
                                  *iface_ip(d->bcast_ip));
           }
            }
@@ -246,13 +256,15 @@ static void do_announce_host(int command,
        CVAL(p,22) = 0x02; /* minor version */
 
        SIVAL(p,23,server_type);
        CVAL(p,22) = 0x02; /* minor version */
 
        SIVAL(p,23,server_type);
-       SSVAL(p,27,0xaa55); /* browse signature */
-       SSVAL(p,29,0x001f); /* browse version: CIFS draft 1.0 indicates 0x001f */
+       SSVAL(p,27,0x010f); /* browse version: got from NT/AS 4.00 */
+       SSVAL(p,29,0xaa55); /* browse signature */
 
        strcpy(p+31,server_comment);
        p += 31;
        p = skip_string(p,1);
 
 
        strcpy(p+31,server_comment);
        p += 31;
        p = skip_string(p,1);
 
+    debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
+
        /* send the announcement */
        send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
                                          PTR_DIFF(p,outbuf),
        /* send the announcement */
        send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,
                                          PTR_DIFF(p,outbuf),
@@ -290,6 +302,8 @@ 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)
 {
 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))
        {
                DEBUG(3,("sending local master announce to %s for %s(1e)\n",
        if (AM_MASTER(work))
        {
                DEBUG(3,("sending local master announce to %s for %s(1e)\n",
@@ -307,11 +321,15 @@ void announce_server(struct subnet_record *d, struct work_record *work,
                /* XXXX should we do a domain-announce-kill? */
                if (server_type != 0)
                {
                /* 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,
                        do_announce_host(ANN_DomainAnnouncement,
-                                               work->work_group, 0x00, d->myip,
-                                               MSBROWSE        , 0x01, d->bcast_ip,
+                                               name    , 0x00, d->myip,
+                                               MSBROWSE, 0x01, d->bcast_ip,
                                                ttl*1000,
                                                ttl*1000,
-                                               name, server_type ? SV_TYPE_DOMAIN_ENUM : 0, comment);
+                                               work->work_group, server_type ? domain_type : 0,
+                                               comment);
                }
        }
        else
                }
        }
        else
@@ -345,6 +363,8 @@ void announce_host(void)
     {
       struct work_record *work;
       
     {
       struct work_record *work;
       
+      if (ip_equal(d->bcast_ip, ipgrp)) continue;
+
       for (work = d->workgrouplist; work; work = work->next)
        {
          uint32 stype = work->ServerType;
       for (work = d->workgrouplist; work; work = work->next)
        {
          uint32 stype = work->ServerType;
index 82b19077f9d1d1eb66f20bc2d3f9a2d03359a61f..c06d10f60c4848397f342fa9187b286794093bf8 100644 (file)
@@ -120,7 +120,7 @@ void remove_name(struct subnet_record *d, struct name_record *n)
   **************************************************************************/
 struct name_record *find_name(struct name_record *n,
                        struct nmb_name *name,
   **************************************************************************/
 struct name_record *find_name(struct name_record *n,
                        struct nmb_name *name,
-                       int search, struct in_addr ip)
+                       int search)
 {
        struct name_record *ret;
   
 {
        struct name_record *ret;
   
@@ -132,12 +132,7 @@ struct name_record *find_name(struct name_record *n,
                        if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
                                continue;
          
                        if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
                                continue;
          
-                       /* zero ip is either samba's ip or a way of finding a
-                          name without needing to know the ip address */
-                       if (zero_ip(ip) || ip_equal(ip, ret->ip))
-                       {
-                               return ret;
-                       }
+                       return ret;
                }
        }
     return NULL;
                }
        }
     return NULL;
@@ -161,7 +156,9 @@ struct name_record *find_name_search(struct subnet_record **d,
        {
                if (*d != NULL)
         {
        {
                if (*d != NULL)
         {
-                       return find_name((*d)->namelist, name, search, ip);
+                       DEBUG(4,("find_name on local: %s %s search %x\n",
+                                               namestr(name),inet_ntoa(ip), search));
+                       return find_name((*d)->namelist, name, search);
                }
         else
         {
                }
         else
         {
@@ -180,7 +177,9 @@ struct name_record *find_name_search(struct subnet_record **d,
 
        if (*d == NULL) return NULL;
 
 
        if (*d == NULL) return NULL;
 
-       return find_name((*d)->namelist, name, search, ip);
+       DEBUG(4,("find_name on WINS: %s %s search %x\n",
+                                               namestr(name),inet_ntoa(ip), search));
+       return find_name((*d)->namelist, name, search);
 }
 
 
 }
 
 
index de0cda79cce998f74f8184ca256705220e6f15d7..f695644129209631cdc50690d19f9f3221322dec 100644 (file)
@@ -102,6 +102,26 @@ static void add_server(struct work_record *work,struct server_record *s)
 }
 
 
 }
 
 
+/****************************************************************************
+  find a server in a server list.
+  **************************************************************************/
+struct server_record *find_server(struct work_record *work, char *name)
+{
+       struct server_record *ret;
+  
+       if (!work) return NULL;
+
+       for (ret = work->serverlist; ret; ret = ret->next)
+       {
+               if (strequal(ret->serv.name,name))
+               {
+                       return ret;
+               }
+       }
+    return NULL;
+}
+
+
 /****************************************************************************
   add a server entry
   ****************************************************************************/
 /****************************************************************************
   add a server entry
   ****************************************************************************/
@@ -115,33 +135,30 @@ struct server_record *add_server_entry(struct subnet_record *d,
   struct server_record *s;
   
   if (name[0] == '*')
   struct server_record *s;
   
   if (name[0] == '*')
-    {
+  {
       return (NULL);
       return (NULL);
-    }
-  
-  for (s = work->serverlist; s; s = s->next)
-    {
-      if (strequal(name,s->serv.name)) break;
-    }
+  }
   
   
+  s = find_server(work, name);
+
   if (s && !replace)
   if (s && !replace)
-    {
-      DEBUG(4,("Not replacing %s\n",name));
-      return(s);
-    }
+  {
+    DEBUG(4,("Not replacing %s\n",name));
+    return(s);
+  }
   
   if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
     updatedlists=True;
 
   if (!s)
   
   if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
     updatedlists=True;
 
   if (!s)
-    {
-      newentry = True;
-      s = (struct server_record *)malloc(sizeof(*s));
+  {
+    newentry = True;
+    s = (struct server_record *)malloc(sizeof(*s));
       
       
-      if (!s) return(NULL);
+    if (!s) return(NULL);
       
       
-      bzero((char *)s,sizeof(*s));
-    }
+    bzero((char *)s,sizeof(*s));
+  }
   
   
   if (d->my_interface && strequal(lp_workgroup(),work->work_group))
   
   
   if (d->my_interface && strequal(lp_workgroup(),work->work_group))
index ba66f41a916f616ca508df720a8dc83d693d35ca..2b0fa5c0dd05725e6bc2fea5fd141239f3ee2849 100644 (file)
@@ -41,6 +41,7 @@ extern pstring scope;
 
 extern pstring myname;
 extern struct in_addr ipzero;
 
 extern pstring myname;
 extern struct in_addr ipzero;
+extern struct in_addr ipgrp;
 
 /* machine comment for host announcements */
 extern  pstring ServerComment;
 
 /* machine comment for host announcements */
 extern  pstring ServerComment;
@@ -201,21 +202,27 @@ void name_unregister_work(struct subnet_record *d, char *name, int name_type)
 void name_register_work(struct subnet_record *d, char *name, int name_type,
                                int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
 {
 void name_register_work(struct subnet_record *d, char *name, int name_type,
                                int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
 {
-  enum name_source source = ismyip(ip) ? SELF : REGISTER;
+  enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
+                                                               SELF : REGISTER;
 
   if (source == SELF)
   {
     struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
 
 
   if (source == SELF)
   {
     struct work_record *work = find_workgroupstruct(d, lp_workgroup(), False);
 
-    if (work && work->state != MST_NONE)
+    add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
+
+    if (work)
     {
     {
-      /* samba is in the process of working towards master browser-ness.
-         initiate the next stage.
-       */
-      become_master(d, work);
+      if (work->state != MST_NONE)
+      {
+        /* samba is in the process of working towards master browser-ness.
+           initiate the next stage.
+         */
+        become_master(d, work);
+        return;
+      }
     }
   }
     }
   }
-  add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
 }
 
 
 }
 
 
@@ -248,8 +255,8 @@ void become_master(struct subnet_record *d, struct work_record *work)
 
   if (!work) return;
   
 
   if (!work) return;
   
-  DEBUG(2,("Becoming master for %s (currently at stage %d)\n",
-                                       work->work_group,work->state));
+  DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
+                                       work->work_group,inet_ntoa(d->bcast_ip),work->state));
   
   switch (work->state)
   {
   
   switch (work->state)
   {
@@ -298,10 +305,50 @@ void become_master(struct subnet_record *d, struct work_record *work)
         /* ask all servers on our local net to announce to us */
         announce_request(work, d->bcast_ip);
       }
         /* ask all servers on our local net to announce to us */
         announce_request(work, d->bcast_ip);
       }
+      break;
+   }
+
+   case MST_BROWSER:
+   {
+      /* don't have to do anything: just report success */
+      DEBUG(3,("3rd stage: become master browser!\n"));
+
+      break;
+   }
+
+   case MST_DOMAIN_NONE:
+   {
+      if (lp_domain_master())
+      {
+        work->state = MST_DOMAIN_MEM; /* ... become domain member */
+        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         );
+
+        /* DON'T do anything else after calling add_my_name_entry() */
+        return;
+      }
+      else
+      {
+        DEBUG(4,("samba not configured as a domain master.\n"));
+      }
+  
+      break;
+   }
 
 
+   case MST_DOMAIN_MEM:
+   {
       if (lp_domain_master())
       {
       if (lp_domain_master())
       {
-        DEBUG(3,("third stage: register as domain master\n"));
+        work->state = MST_DOMAIN_TST; /* ... possibly become domain master */
+        DEBUG(3,("domain second stage: register as domain master\n"));
+
+        if (lp_domain_logons())
+           {
+          work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
+          add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
+        }
 
         /* add domain master name */
         add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE         );
 
         /* add domain master name */
         add_my_name_entry(d,work->work_group,0x1b,NB_ACTIVE         );
@@ -311,34 +358,62 @@ void become_master(struct subnet_record *d, struct work_record *work)
       }
       else
       {
       }
       else
       {
-        DEBUG(3,("samba not configured as a domain master: no third stage.\n"));
+        DEBUG(4,("samba not configured as a domain master.\n"));
       }
   
       break;
     }
       }
   
       break;
     }
-    case MST_BROWSER: /* while we were still a master browser... */
+
+    case MST_DOMAIN_TST: /* while we were still a master browser... */
     {
       /* update our server status */
       if (lp_domain_master())
       {
     {
       /* update our server status */
       if (lp_domain_master())
       {
-        DEBUG(3,("fourth stage: samba is now a domain master.\n"));
+        struct subnet_record *d1;
+               uint32 update_type = 0;
+
+        DEBUG(3,("domain third stage: samba is now a domain master.\n"));
         work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
 
         work->state = MST_DOMAIN; /* ... registering WORKGROUP(1b) succeeded */
 
-        work->ServerType |= SV_TYPE_DOMAIN_MASTER;
+        update_type |= SV_TYPE_DOMAIN_MASTER;
       
         if (lp_domain_logons())
            {
       
         if (lp_domain_logons())
            {
-             work->ServerType |= SV_TYPE_DOMAIN_CTRL;
-             work->ServerType |= SV_TYPE_DOMAIN_MEMBER;
+             update_type |= SV_TYPE_DOMAIN_CTRL;
            }
            }
+
+               work->ServerType |= update_type;
         add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
         add_server_entry(d,work,myname,work->ServerType,0,ServerComment,True);
+
+               for (d1 = subnetlist; d1; d1 = d1->next)
+               {
+               struct work_record *w;
+                       if (ip_equal(d1->bcast_ip, d->bcast_ip)) continue;
+
+               for (w = d1->workgrouplist; w; w = w->next)
+                       {
+                               struct server_record *s = find_server(w, myname);
+                               if (strequal(w->work_group, work->work_group))
+                               {
+                                       w->ServerType |= update_type;
+                               }
+                               if (s)
+                               {
+                                       s->serv.type |= update_type;
+                                       DEBUG(4,("found server %s on %s: update to %8x\n",
+                                                                       s->serv.name, inet_ntoa(d1->bcast_ip),
+                                                                       s->serv.type));
+                               }
+                       }
+               }
       }
   
       break;
     }
       }
   
       break;
     }
+
     case MST_DOMAIN:
     {
     case MST_DOMAIN:
     {
-      /* nothing else to become, at the moment: we are top-dog. */
+      /* don't have to do anything: just report success */
       DEBUG(3,("fifth stage: there isn't one yet!\n"));
       break;
     }
       DEBUG(3,("fifth stage: there isn't one yet!\n"));
       break;
     }
@@ -414,16 +489,16 @@ void run_elections(void)
   lastime = t;
   
   for (d = subnetlist; d; d = d->next)
   lastime = t;
   
   for (d = subnetlist; d; d = d->next)
-    {
-      struct work_record *work;
-      for (work = d->workgrouplist; work; work = work->next)
+  {
+    struct work_record *work;
+    for (work = d->workgrouplist; work; work = work->next)
        {
          if (work->RunningElection)
        {
          if (work->RunningElection)
-           {
-             send_election(d,work->work_group, work->ElectionCriterion,
+         {
+           send_election(d,work->work_group, work->ElectionCriterion,
                            t-StartupTime,myname);
              
                            t-StartupTime,myname);
              
-             if (work->ElectionCount++ >= 4)
+           if (work->ElectionCount++ >= 4)
                {
                  /* I won! now what :-) */
                  DEBUG(2,(">>> Won election on %s %s <<<\n",
                {
                  /* I won! now what :-) */
                  DEBUG(2,(">>> Won election on %s %s <<<\n",
@@ -434,9 +509,9 @@ void run_elections(void)
 
                  become_master(d, work);
                }
 
                  become_master(d, work);
                }
-           }
+         }
        }
        }
-    }
+  }
 }
 
 
 }
 
 
index 5afdb8af0eda8545a8feaee4d4f1bb324c0c46eb..acedbc015115d3081163aa54b39ac218d88d8f5b 100644 (file)
@@ -40,6 +40,40 @@ extern struct in_addr ipgrp;
 
 static uint16 name_trn_id=0;
 
 
 static uint16 name_trn_id=0;
 
+
+/***************************************************************************
+  updates the unique transaction identifier
+  **************************************************************************/
+void debug_browse_data(char *outbuf, int len)
+{
+    int i,j;
+    for (i = 0; i < len; i+= 16)
+      {
+       DEBUG(4, ("%3x char ", i));
+       
+       for (j = 0; j < 16; j++)
+         {
+           unsigned char x = outbuf[i+j];
+           if (x < 32 || x > 127) x = '.';
+           
+           if (i+j >= len) break;
+           DEBUG(4, ("%c", x));
+         }
+       
+       DEBUG(4, (" hex ", i));
+       
+       for (j = 0; j < 16; j++)
+         {
+           if (i+j >= len) break;
+           DEBUG(4, (" %02x", outbuf[i+j]));
+         }
+       
+       DEBUG(4, ("\n"));
+      }
+    
+}
+
+
 /***************************************************************************
   updates the unique transaction identifier
   **************************************************************************/
 /***************************************************************************
   updates the unique transaction identifier
   **************************************************************************/
@@ -138,7 +172,7 @@ void initiate_netbios_packet(uint16 *id,
   reply to a netbios name packet 
   ****************************************************************************/
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
   reply to a netbios name packet 
   ****************************************************************************/
 void reply_netbios_packet(struct packet_struct *p1,int trn_id,
-                               int rcode,int opcode, BOOL recurse,
+                               int rcode, int rcv_code, int opcode, BOOL recurse,
                                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
                                char *data,int len)
 {
                                struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
                                char *data,int len)
 {
@@ -150,7 +184,7 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id,
   
   p = *p1;
 
   
   p = *p1;
 
-  switch (rr_type)
+  switch (rcv_code)
   {
     case NMB_STATUS:
        {
   {
     case NMB_STATUS:
        {
@@ -539,5 +573,9 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
   p.timestamp = time(NULL);
   p.packet_type = DGRAM_PACKET;
 
   p.timestamp = time(NULL);
   p.packet_type = DGRAM_PACKET;
 
+  DEBUG(4,("send mailslot %s from %s %s", mailslot,
+                    inet_ntoa(src_ip),namestr(&dgram->source_name)));
+  DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
+
   return(send_packet(&p));
 }
   return(send_packet(&p));
 }
index f87088dffa59c1e5b89f8aed473b2b28b31b7cd9..0f76323df0bb52e5ec0e5d700956a65e6a2641f0 100644 (file)
@@ -45,6 +45,8 @@ static void dead_netbios_entry(struct subnet_record *d,
   DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
           inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
 
   DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
           inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
 
+  debug_state_type(n->state);
+
   switch (n->state)
   {
     case NAME_QUERY_CONFIRM:
   switch (n->state)
   {
     case NAME_QUERY_CONFIRM:
@@ -113,7 +115,7 @@ static void dead_netbios_entry(struct subnet_record *d,
                   wanted the unique name and tell them that they can have it
                 */
 
                   wanted the unique name and tell them that they can have it
                 */
 
-               add_name_respond(d,n->fd, n->response_id ,&n->name,
+               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);
 
                                                n->nb_flags, GET_TTL(0),
                                                n->reply_to_ip, False, n->reply_to_ip);
 
@@ -140,7 +142,7 @@ static void dead_netbios_entry(struct subnet_record *d,
                /* IMPORTANT: see response_name_reg() */
 
                name_register_work(d,n->name.name,n->name.name_type,
                /* IMPORTANT: see response_name_reg() */
 
                name_register_work(d,n->name.name,n->name.name_type,
-                               n->nb_flags, n->ttl, n->send_ip, n->bcast);
+                               n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
          }
          else
          {
          }
          else
          {
index 0349bd47c2eff2cce39c23fbef68618f53331e47..23340a8c28e61b8dd857dbae7a46087c1fcabb25 100644 (file)
@@ -131,18 +131,6 @@ samba should take this into account (see rfc1001.txt 10.3).
 remove_name_entry() issues this samba 'state'
 response_name_rel() deals with responses to NAME_RELEASE.
 
 remove_name_entry() issues this samba 'state'
 response_name_rel() deals with responses to NAME_RELEASE.
 
-- NAME_REGISTER_CHALLENGE
-
-when a samba 'state' of type NAME_REGISTER_CHALLENGE is sent, and a
-response is not received, it is assumed that the server being queried
-is either dead, deaf or unreachable. the host that wanted this
-unique name is then informed that it can have it (the name query
-challenge went unanswered) and that its registration of this name
-did in fact succeed.
-
-reply_name_reg() issues this samba 'state'
-response_name_query_register() deals with responses.
-
 - NAME_REGISTER
 
 when a samba 'state' of type NAME_REGISTER is sent, and a response is
 - NAME_REGISTER
 
 when a samba 'state' of type NAME_REGISTER is sent, and a response is
index 371f12e0110a3898c77634c4399a8fdcab561e15..ee75a9825a345676811b9962ffde09d3552823c8 100644 (file)
@@ -37,6 +37,7 @@ extern int DEBUGLEVEL;
 
 extern pstring scope;
 extern pstring myname;
 
 extern pstring scope;
 extern pstring myname;
+extern pstring ServerComment;
 extern struct in_addr ipzero;
 extern struct in_addr ipgrp;
 
 extern struct in_addr ipzero;
 extern struct in_addr ipgrp;
 
@@ -124,7 +125,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
      it must be re-registered, rather than just registered */
 
   make_nmb_name(&n, name, type, scope);
      it must be re-registered, rather than just registered */
 
   make_nmb_name(&n, name, type, scope);
-  if (find_name(d->namelist, &n, SELF, ipzero))
+  if (find_name(d->namelist, &n, SELF))
        re_reg = True;
 
   /* XXXX BUG: if samba is offering WINS support, it should still add the
        re_reg = True;
 
   /* XXXX BUG: if samba is offering WINS support, it should still add the
@@ -141,6 +142,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
          actually be true
        */
 
          actually be true
        */
 
+      DEBUG(4,("samba as WINS server adding: "));
       /* this will call add_netbios_entry() */
       name_register_work(d, name, type, nb_flags,0, ipzero, False);
     }
       /* this will call add_netbios_entry() */
       name_register_work(d, name, type, nb_flags,0, ipzero, False);
     }
@@ -155,10 +157,11 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
   }
   else
   {
   }
   else
   {
+    /* 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),
        queue_netbios_packet(d,ClientNMB,
                                 re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
                             name, type, nb_flags, GET_TTL(0),
-                            True, True, d->bcast_ip, d->bcast_ip);
+                            True, True, d->bcast_ip, ipzero);
   }
 }
 
   }
 }
 
@@ -181,9 +184,10 @@ void add_my_names(void)
 
   for (d = subnetlist; d; d = d->next)
   {
 
   for (d = subnetlist; d; d = d->next)
   {
-    if (!d->my_interface) continue;
+    BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
+
+    if (!d->my_interface && !wins_iface) continue;
 
 
-    /* these names need to be refreshed with the WINS server */
        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,0x20,NB_ACTIVE);
        add_my_name_entry(d, myname,0x03,NB_ACTIVE);
        add_my_name_entry(d, myname,0x00,NB_ACTIVE);
@@ -195,11 +199,20 @@ void add_my_names(void)
        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,"__SAMBA__",0x20,NB_ACTIVE,0,SELF,ip,False,wins);
        add_netbios_entry(d,"__SAMBA__",0x00,NB_ACTIVE,0,SELF,ip,False,wins);
 
-    if (lp_domain_logons() && lp_domain_master()) {
+    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);
     }
   }
        /* XXXX the 0x1c is apparently something to do with domain logons */
          add_my_name_entry(d, my_workgroup(),0x1c,NB_ACTIVE|NB_GROUP);
     }
   }
+  if (lp_domain_master() && (d = find_subnet(ipgrp)))
+  {
+    struct work_record *work = find_workgroupstruct(d, lp_workgroup(), True);
+    if (work && work->state == MST_NONE)
+    {
+      work->state = MST_DOMAIN_NONE;
+      become_master(d, work);
+    }
+  }
 }
 
 
 }
 
 
index 6501bded6850950ff12f3a19bcaac578b90b955b..84b9277d603b8733dabd115ac762ecf3865227c0 100644 (file)
@@ -42,7 +42,8 @@ extern struct in_addr ipgrp;
 /****************************************************************************
   add a netbios entry. respond to the (possibly new) owner.
   **************************************************************************/
 /****************************************************************************
   add a netbios entry. respond to the (possibly new) owner.
   **************************************************************************/
-void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
+void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
+                               uint16 response_id,
                                struct nmb_name *name,
                                int nb_flags, int ttl, struct in_addr register_ip,
                                BOOL new_owner, struct in_addr reply_to_ip)
                                struct nmb_name *name,
                                int nb_flags, int ttl, struct in_addr register_ip,
                                BOOL new_owner, struct in_addr reply_to_ip)
@@ -52,7 +53,7 @@ void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
                                                nb_flags,ttl,REGISTER,register_ip,False,True);
 
        /* reply yes or no to the host that requested the name */
                                                nb_flags,ttl,REGISTER,register_ip,False,True);
 
        /* reply yes or no to the host that requested the name */
-       send_name_response(fd, response_id, NMB_REG,
+       send_name_response(fd,from_ip, response_id, NMB_REG,
                                new_owner, True,
                                name, nb_flags, ttl, reply_to_ip);
 }
                                new_owner, True,
                                name, nb_flags, ttl, reply_to_ip);
 }
@@ -60,7 +61,7 @@ void add_name_respond(struct subnet_record *d, int fd, uint16 response_id,
 /****************************************************************************
 send a registration / release response: pos/neg
 **************************************************************************/
 /****************************************************************************
 send a registration / release response: pos/neg
 **************************************************************************/
-void send_name_response(int fd,
+void send_name_response(int fd, struct in_addr from_ip,
                                int name_trn_id, int opcode, BOOL success, BOOL recurse,
                                struct nmb_name *reply_name, int nb_flags, int ttl,
                                struct in_addr ip)
                                int name_trn_id, int opcode, BOOL success, BOOL recurse,
                                struct nmb_name *reply_name, int nb_flags, int ttl,
                                struct in_addr ip)
@@ -85,14 +86,14 @@ void send_name_response(int fd,
   rdata[1] = 0;
   putip(&rdata[2],(char *)&ip);
   
   rdata[1] = 0;
   putip(&rdata[2],(char *)&ip);
   
-  p.ip = ip;
+  p.ip = from_ip;
   p.port = NMB_PORT;
   p.fd = fd;
   p.timestamp = time(NULL);
   p.packet_type = NMB_PACKET;
 
   reply_netbios_packet(&p,name_trn_id,
   p.port = NMB_PORT;
   p.fd = fd;
   p.timestamp = time(NULL);
   p.packet_type = NMB_PACKET;
 
   reply_netbios_packet(&p,name_trn_id,
-                      rcode,opcode,recurse,
+                      rcode,opcode,opcode,recurse,
                       reply_name, 0x20, 0x1,
                       ttl, 
                       rdata, 6);
                       reply_name, 0x20, 0x1,
                       ttl, 
                       rdata, 6);
@@ -145,7 +146,7 @@ void reply_name_release(struct packet_struct *p)
   if (bcast) return;
   
   /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
   if (bcast) return;
   
   /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
-  send_name_response(p->fd, nmb->header.name_trn_id, NMB_REL,
+  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);
 }
@@ -285,7 +286,7 @@ void reply_name_reg(struct packet_struct *p)
 
     /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
     reply_netbios_packet(p,nmb->header.name_trn_id,
 
     /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
     reply_netbios_packet(p,nmb->header.name_trn_id,
-                      0,NMB_WAIT_ACK,False,
+                      0,NMB_WAIT_ACK,NMB_WAIT_ACK,False,
                       reply_name, 0x0a, 0x01,
                       15*1000, /* 15 seconds long enough to wait? */
                       rdata, 2);
                       reply_name, 0x0a, 0x01,
                       15*1000, /* 15 seconds long enough to wait? */
                       rdata, 2);
@@ -302,7 +303,7 @@ void reply_name_reg(struct packet_struct *p)
        or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
      */
 
        or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
      */
 
-       send_name_response(p->fd, nmb->header.name_trn_id, NMB_REG,
+       send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG,
                                                success, True,
                                                reply_name, nb_flags, ttl, ip);
   }
                                                success, True,
                                                reply_name, nb_flags, ttl, ip);
   }
@@ -322,6 +323,7 @@ void reply_name_status(struct packet_struct *p)
   int names_added;
   struct name_record *n;
   struct subnet_record *d = NULL;
   int names_added;
   struct name_record *n;
   struct subnet_record *d = NULL;
+  int search = FIND_SELF;
 
   BOOL bcast = nmb->header.nm_flags.bcast;
   
 
   BOOL bcast = nmb->header.nm_flags.bcast;
   
@@ -335,9 +337,13 @@ void reply_name_status(struct packet_struct *p)
   DEBUG(3,("Name status for name %s %s\n",
           namestr(&nmb->question.question_name), inet_ntoa(p->ip)));
   
   DEBUG(3,("Name status for name %s %s\n",
           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,
   n = find_name_search(&d, &nmb->question.question_name,
-                               FIND_SELF|FIND_LOCAL,
-                               p->ip);
+                               search, p->ip);
   
   if (!n) return;
   
   
   if (!n) return;
   
@@ -396,7 +402,7 @@ void reply_name_status(struct packet_struct *p)
   
   /* Send a POSITIVE NAME STATUS RESPONSE */
   reply_netbios_packet(p,nmb->header.name_trn_id,
   
   /* Send a POSITIVE NAME STATUS RESPONSE */
   reply_netbios_packet(p,nmb->header.name_trn_id,
-                          0,0,True,
+                          0,NMB_STATUS,0,True,
                       &nmb->question.question_name,
                       nmb->question.question_type,
                       nmb->question.question_class,
                       &nmb->question.question_name,
                       nmb->question.question_type,
                       nmb->question.question_class,
@@ -452,15 +458,26 @@ void reply_name_query(struct packet_struct *p)
   if (name_type == 0x1b)
   {
     /* even if it's a broadcast, we don't ignore queries for PDC names */
   if (name_type == 0x1b)
   {
     /* even if it's a broadcast, we don't ignore queries for PDC names */
-    search |= FIND_WINS;
-    search &= ~FIND_SELF;
+    search = FIND_WINS;
   }
 
   }
 
-  if (!(d = find_req_subnet(p->ip, bcast)))
+  if (search | FIND_LOCAL)
   {
   {
-    DEBUG(3,("name query: bcast %s not known\n",
-                                 inet_ntoa(p->ip)));
-    success = False;
+    if (!(d = find_req_subnet(p->ip, bcast)))
+    {
+      DEBUG(3,("name query: bcast %s not known\n",
+                                   inet_ntoa(p->ip)));
+      success = False;
+    }
+  }
+  else
+  {
+    if (!(d = find_subnet(ipgrp)))
+    {
+      DEBUG(3,("name query: wins search %s not known\n",
+                                   inet_ntoa(p->ip)));
+      success = False;
+    }
   }
 
   DEBUG(3,("Name query "));
   }
 
   DEBUG(3,("Name query "));
@@ -492,7 +509,7 @@ void reply_name_query(struct packet_struct *p)
          another WINS server if the name is not in our database, or we are
          not a WINS server ourselves
        */
          another WINS server if the name is not in our database, or we are
          not a WINS server ourselves
        */
-      ttl = n->death_time - p->timestamp;
+      ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0);
       retip = n->ip;
       nb_flags = n->nb_flags;
   }
       retip = n->ip;
       nb_flags = n->nb_flags;
   }
@@ -524,7 +541,7 @@ void reply_name_query(struct packet_struct *p)
   }
   
   reply_netbios_packet(p,nmb->header.name_trn_id,
   }
   
   reply_netbios_packet(p,nmb->header.name_trn_id,
-                          rcode,0,True,
+                          rcode,NMB_QUERY,0,True,
                       &nmb->question.question_name,
                       nmb->question.question_type,
                       nmb->question.question_class,
                       &nmb->question.question_name,
                       nmb->question.question_type,
                       nmb->question.question_class,
index e47afc55b34c618444e784623b44fb4bc7a40e7d..46acc2b99276ed56d2bd62a4112563228654ef43 100644 (file)
@@ -339,7 +339,7 @@ static void response_name_query_register(struct nmb_packet *nmb,
        }
 
        /* register the old or the new owners' ip */
        }
 
        /* register the old or the new owners' ip */
-       add_name_respond(d, n->fd, n->response_id,&n->name,n->nb_flags,
+       add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
                                        GET_TTL(0), register_ip,
                                        new_owner, n->reply_to_ip);
 }
                                        GET_TTL(0), register_ip,
                                        new_owner, n->reply_to_ip);
 }
@@ -434,7 +434,7 @@ static void debug_rr_type(int rr_type)
 /****************************************************************************
   report the response record nmbd state
   ****************************************************************************/
 /****************************************************************************
   report the response record nmbd state
   ****************************************************************************/
-static void debug_state_type(int state)
+void debug_state_type(int state)
 {
   /* report the state type to help debugging */
   switch (state)
 {
   /* report the state type to help debugging */
   switch (state)
index 85a07a7dc94f39e5bfe1ef4a1fd3f492da9b3781..4329e6f197ad3d1ba7c13961bd7ae56cd47225e7 100644 (file)
@@ -64,6 +64,7 @@ extern int  updatecount;
 
 extern time_t StartupTime;
 
 
 extern time_t StartupTime;
 
+extern BOOL updatedlists;
 
 /****************************************************************************
 tell a server to become a backup browser
 
 /****************************************************************************
 tell a server to become a backup browser
@@ -195,18 +196,22 @@ BOOL listening_name(struct work_record *work, struct nmb_name *n)
   resources. We just have to pass it to smbd (via browser.dat) and let
   the client choose using bit masks.
   ******************************************************************/
   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,int command,char *buf)
+static void process_announce(struct packet_struct *p,uint16 command,char *buf)
 {
   struct dgram_packet *dgram = &p->packet.dgram;
   struct in_addr ip = dgram->header.source_ip;
   struct subnet_record *d = find_subnet(ip); 
   int update_count = CVAL(buf,0);
 {
   struct dgram_packet *dgram = &p->packet.dgram;
   struct in_addr ip = dgram->header.source_ip;
   struct subnet_record *d = find_subnet(ip); 
   int update_count = CVAL(buf,0);
+
   int ttl = IVAL(buf,1)/1000;
   char *name = buf+5;
   int osmajor=CVAL(buf,21);
   int osminor=CVAL(buf,22);
   uint32 servertype = IVAL(buf,23);
   int ttl = IVAL(buf,1)/1000;
   char *name = buf+5;
   int osmajor=CVAL(buf,21);
   int osminor=CVAL(buf,22);
   uint32 servertype = IVAL(buf,23);
+  uint32 browse_type= CVAL(buf,27);
+  uint32 browse_sig = CVAL(buf,29);
   char *comment = buf+31;
   char *comment = buf+31;
+
   struct work_record *work;
   char *work_name;
   char *serv_name = dgram->source_name.name;
   struct work_record *work;
   char *work_name;
   char *serv_name = dgram->source_name.name;
@@ -215,9 +220,9 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
   comment[43] = 0;
   
   DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
   comment[43] = 0;
   
   DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
-  DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x comment=%s\n",
+  DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
           namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
           namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
-          servertype,comment));
+          servertype,browse_type,browse_sig,comment));
   
   name[15] = 0;  
   
   
   name[15] = 0;  
   
@@ -236,7 +241,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
       return;
     }
   
       return;
     }
   
-  if (same_context(dgram)) return;
+  if (!strequal(dgram->dest_name.scope,scope )) return;
   
   if (command == ANN_DomainAnnouncement) { 
     /* XXXX if we are a master browser for the workgroup work_name,
   
   if (command == ANN_DomainAnnouncement) { 
     /* XXXX if we are a master browser for the workgroup work_name,
@@ -249,6 +254,7 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
      */
 
     work_name = name;
      */
 
     work_name = name;
+    add = True;
   } else {
     work_name = dgram->dest_name.name;
   }
   } else {
     work_name = dgram->dest_name.name;
   }
@@ -268,9 +274,10 @@ static void process_announce(struct packet_struct *p,int command,char *buf)
   
   ttl = GET_TTL(ttl);
   
   
   ttl = GET_TTL(ttl);
   
-  /* add them to our browse list */
+  /* add them to our browse list, and update the browse.dat file */
   add_server_entry(d,work,name,servertype,ttl,comment,True);
   add_server_entry(d,work,name,servertype,ttl,comment,True);
-  
+  updatedlists = True;
+
 #if 0
   /* the tell become backup code is broken, no great harm is done by
      disabling it */
 #if 0
   /* the tell become backup code is broken, no great harm is done by
      disabling it */
@@ -339,12 +346,12 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
   struct dgram_packet *dgram = &p->packet.dgram;
   struct in_addr ip = dgram->header.source_ip;
   int count = CVAL(buf,0);
   struct dgram_packet *dgram = &p->packet.dgram;
   struct in_addr ip = dgram->header.source_ip;
   int count = CVAL(buf,0);
-  int Index = IVAL(buf,1); /* caller's index representing workgroup */
+  uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
   char *buf1;
   
   char *buf1;
   
-  DEBUG(3,("Receive Backup ack for %s from %s total=%d index=%d\n",
+  DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
           namestr(&dgram->dest_name), inet_ntoa(ip),
           namestr(&dgram->dest_name), inet_ntoa(ip),
-          count, Index));
+          count, info));
   
   if (same_context(dgram)) return;
   
   
   if (same_context(dgram)) return;
   
@@ -352,44 +359,49 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
   
   /* go through the list of servers attempting to sync browse lists */
   for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
   
   /* go through the list of servers attempting to sync browse lists */
   for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
-    {
-      struct in_addr back_ip;
-      struct subnet_record *d;
+  {
+    struct in_addr back_ip;
+    struct subnet_record *d;
       
       
-      DEBUG(4,("Searching for backup browser %s at %s...\n",
+    DEBUG(4,("Searching for backup browser %s at %s...\n",
               buf1, inet_ntoa(ip)));
       
               buf1, inet_ntoa(ip)));
       
-      /* XXXX assume name is a DNS name NOT a netbios name. a more complete
-            approach is to use reply_name_query functionality to find the name */
-      back_ip = *interpret_addr2(buf1);
+    /* XXXX assume name is a DNS name NOT a netbios name. a more complete
+          approach is to use reply_name_query functionality to find the name */
+
+    back_ip = *interpret_addr2(buf1);
       
       
-      if (zero_ip(back_ip))
+    if (zero_ip(back_ip))
        {
          DEBUG(4,("Failed to find backup browser server using DNS\n"));
          continue;
        }
       
       DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
        {
          DEBUG(4,("Failed to find backup browser server using DNS\n"));
          continue;
        }
       
       DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
+      DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
       
       
-      if ((d = find_subnet(back_ip)))
+      /* XXXX function needs work */
+         continue;
+
+    if ((d = find_subnet(back_ip)))
        {
          struct subnet_record *d1;
          for (d1 = subnetlist; d1; d1 = d1->next)
        {
          struct subnet_record *d1;
          for (d1 = subnetlist; d1; d1 = d1->next)
-           {
+         {
              struct work_record *work;
              for (work = d1->workgrouplist; work; work = work->next)
                {
              struct work_record *work;
              for (work = d1->workgrouplist; work; work = work->next)
                {
-                 if (work->token == Index)
-                   {
+                 if (work->token == 0 /* token */)
+                 {
                      queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
                                           work->work_group,0x1d,0,0,
                                           False,False,back_ip,back_ip);
                      return;
                      queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
                                           work->work_group,0x1d,0,0,
                                           False,False,back_ip,back_ip);
                      return;
-                   }
+                 }
                }
                }
-           }
+         }
        }
        }
-    }
+  }
 }
 
 
 }
 
 
@@ -397,19 +409,18 @@ static void process_rcv_backup_list(struct packet_struct *p,char *buf)
   send a backup list response.
   **************************************************************************/
 static void send_backup_list(char *work_name, struct nmb_name *src_name,
   send a backup list response.
   **************************************************************************/
 static void send_backup_list(char *work_name, struct nmb_name *src_name,
-                            int info_count, int token, int info,
+                            int token, uint32 info,
                             int name_type, struct in_addr ip)
 {                     
   struct subnet_record *d;
   char outbuf[1024];
   char *p, *countptr, *nameptr;
   int count = 0;
                             int name_type, struct in_addr ip)
 {                     
   struct subnet_record *d;
   char outbuf[1024];
   char *p, *countptr, *nameptr;
   int count = 0;
-  int i, j;
   char *theirname = src_name->name;
   
   DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", 
           work_name, inet_ntoa(ip),
   char *theirname = src_name->name;
   
   DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n", 
           work_name, inet_ntoa(ip),
-          myname,0x20,theirname,0x0));    
+          myname,0x0,theirname,0x0));     
   
   if (name_type == 0x1d)
     {
   
   if (name_type == 0x1d)
     {
@@ -429,18 +440,20 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
   p = outbuf;
   
   CVAL(p,0) = ANN_GetBackupListResp;    /* backup list response */
   p = outbuf;
   
   CVAL(p,0) = ANN_GetBackupListResp;    /* backup list response */
-  p++;
   
   
-  countptr = p; /* count pointer */
-  
-  SSVAL(p,1,token); /* sender's workgroup index representation */
-  SSVAL(p,3,info); /* XXXX clueless: info, usually zero */
+  p++;
+  countptr = p;
+
+  SIVAL(p,1,info); /* the sender's unique info */
+
   p += 5;
   
   nameptr = p;
   p += 5;
   
   nameptr = p;
-  
+
+#if 0
+
   for (d = subnetlist; d; d = d->next)
   for (d = subnetlist; d; d = d->next)
-    {
+  {
       struct work_record *work;
       
       for (work = d->workgrouplist; work; work = work->next)
       struct work_record *work;
       
       for (work = d->workgrouplist; work; work = work->next)
@@ -465,9 +478,9 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
              
              /* workgroup request: include all backup browsers in the list */
              /* domain request: include all domain members in the list */
              
              /* workgroup request: include all backup browsers in the list */
              /* domain request: include all domain members in the list */
-             
+
              if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
              if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
-                 (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
+                     (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
                {                          
                  DEBUG(4, ("%s ", s->serv.name));
                  
                {                          
                  DEBUG(4, ("%s ", s->serv.name));
                  
@@ -476,52 +489,34 @@ static void send_backup_list(char *work_name, struct nmb_name *src_name,
                  strupper(p);
                  p = skip_string(p,1);
                }
                  strupper(p);
                  p = skip_string(p,1);
                }
-           }
+        }
        }
        }
-    }
-  
+  }
+
+#endif
+
+       count++;
+       strcpy(p,myname);
+       strupper(p);
+       p = skip_string(p,1);
+
   if (count == 0)
     {
       DEBUG(4, ("none\n"));
   if (count == 0)
     {
       DEBUG(4, ("none\n"));
-      return;
     }
   else
     {
       DEBUG(4, (" - count %d\n", count));
     }
   
     }
   else
     {
       DEBUG(4, (" - count %d\n", count));
     }
   
-  CVAL(countptr,0) = count; /* total number of backup browsers found */
-  
+  CVAL(countptr, 0) = count;
+
   {
     int len = PTR_DIFF(p, outbuf);
   {
     int len = PTR_DIFF(p, outbuf);
-    
-    for (i = 0; i < len; i+= 16)
-      {
-       DEBUG(4, ("%3x char ", i));
-       
-       for (j = 0; j < 16; j++)
-         {
-           unsigned char x = outbuf[i+j];
-           if (x < 32 || x > 127) x = '.';
-           
-           if (i+j >= len) break;
-           DEBUG(4, ("%c", x));
-         }
-       
-       DEBUG(4, (" hex ", i));
-       
-       for (j = 0; j < 16; j++)
-         {
-           if (i+j >= len) break;
-           DEBUG(4, (" %02x", outbuf[i+j]));
-         }
-       
-       DEBUG(4, ("\n"));
-      }
-    
+    debug_browse_data(outbuf, len);
   }
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
   }
   send_mailslot_reply(BROWSE_MAILSLOT,ClientDGRAM,outbuf,PTR_DIFF(p,outbuf),
-                     myname,theirname,0x20,0x0,ip,*iface_ip(ip));
+                     myname,theirname,0x0,0x0,ip,*iface_ip(ip));
 }
 
 
 }
 
 
@@ -544,15 +539,12 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
   struct subnet_record *d;
   struct work_record *work;
 
   struct subnet_record *d;
   struct work_record *work;
 
-  int count = CVAL(buf,0);
-  int token = SVAL(buf,1); /* sender's key index for the workgroup? */
-  int info  = SVAL(buf,3); /* XXXX don't know: some sort of info */
+  int    token = CVAL(buf,0); /* sender's key index for the workgroup */
+  uint32 info  = IVAL(buf,1); /* XXXX don't know: some sort of info */
   int name_type = dgram->dest_name.name_type;
 
   if (same_context(dgram)) return;
   
   int name_type = dgram->dest_name.name_type;
 
   if (same_context(dgram)) return;
   
-  if (count <= 0) return;
-  
   if (name_type != 0x1b && name_type != 0x1d) {
     DEBUG(0,("backup request to wrong type %d from %s\n",
              name_type,inet_ntoa(ip)));
   if (name_type != 0x1b && name_type != 0x1d) {
     DEBUG(0,("backup request to wrong type %d from %s\n",
              name_type,inet_ntoa(ip)));
@@ -565,11 +557,11 @@ static void process_send_backup_list(struct packet_struct *p,char *buf)
        {
          if (strequal(work->work_group, dgram->dest_name.name))
            {
        {
          if (strequal(work->work_group, dgram->dest_name.name))
            {
-             DEBUG(2,("sending backup list to %s %s count=%d\n",
-                      namestr(&dgram->dest_name),inet_ntoa(ip),count));
+             DEBUG(2,("sending backup list to %s %s id=%x\n",
+                      namestr(&dgram->dest_name),inet_ntoa(ip),info));
   
              send_backup_list(work->work_group,&dgram->source_name,
   
              send_backup_list(work->work_group,&dgram->source_name,
-                              count,token,info,name_type,ip);
+                              token,info,name_type,ip);
              return;
            }
        } 
              return;
            }
        } 
@@ -634,7 +626,6 @@ static void process_reset_browser(struct packet_struct *p,char *buf)
     }
 }
 
     }
 }
 
-
 /*******************************************************************
   process a announcement request
 
 /*******************************************************************
   process a announcement request
 
@@ -759,6 +750,7 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
     case ANN_DomainAnnouncement:
     case ANN_LocalMasterAnnouncement:
       {
     case ANN_DomainAnnouncement:
     case ANN_LocalMasterAnnouncement:
       {
+        debug_browse_data(buf, len);
        process_announce(p,command,buf+1);
        break;
       }
        process_announce(p,command,buf+1);
        break;
       }
@@ -777,15 +769,17 @@ void process_browse_packet(struct packet_struct *p,char *buf,int len)
       
     case ANN_GetBackupListReq:
       {
       
     case ANN_GetBackupListReq:
       {
+        debug_browse_data(buf, len);
        process_send_backup_list(p,buf+1);
        break;
       }
       
     case ANN_GetBackupListResp:
        process_send_backup_list(p,buf+1);
        break;
       }
       
     case ANN_GetBackupListResp:
-      {
-       process_rcv_backup_list(p, buf+1);
-       break;
-      }
+    {
+        debug_browse_data(buf, len);
+        process_rcv_backup_list(p, buf+1);
+        break;
+    }
       
     case ANN_ResetBrowserState:
       {
       
     case ANN_ResetBrowserState:
       {
index 40cb06aad4b78d8ea9328efaa9c766a334d2d4f7..10b356d9b5019183b8f67ec50a16bea307e9d8da 100644 (file)
@@ -323,7 +323,7 @@ static void process(void)
 
       announce_host();
 
 
       announce_host();
 
-#if 0
+#if 1
       /* XXXX what was this stuff supposed to do? It sent
         ANN_GetBackupListReq packets which I think should only be
         sent when trying to find out who to browse with */      
       /* XXXX what was this stuff supposed to do? It sent
         ANN_GetBackupListReq packets which I think should only be
         sent when trying to find out who to browse with */      
index 0f00e3ec21d3d34c0afe167192620551471a2534..415c939bf38c2b72a4e1fa3e0fda6c516ab29f40 100644 (file)
@@ -1013,7 +1013,7 @@ static BOOL api_RNetServerEnum(int cnum, int uid, char *param, char *data,
   int counted=0,total=0;
   int i;
   fstring domain;
   int counted=0,total=0;
   int i;
   fstring domain;
-  BOOL domains = False;
+  BOOL domains;
   BOOL domain_request;
   BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;
 
   BOOL domain_request;
   BOOL local_request = servertype & SV_TYPE_LOCAL_LIST_ONLY;
 
index 4fbd8390368693662aba91c5612a6a1ffc39332d..a543b90762f77c32e277ff47c07e20933db22f4b 100644 (file)
@@ -49,7 +49,7 @@ static BOOL open_sockets(void)
       return False;
     }   
 
       return False;
     }   
 
-  ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
+  ServerFD = open_socket_in(SOCK_DGRAM, NMB_PORT,3);
 
   if (ServerFD == -1)
     return(False);
 
   if (ServerFD == -1)
     return(False);
@@ -164,7 +164,7 @@ int main(int argc,char *argv[])
          strcpy(lookup,"\01\02__MSBROWSE__\02");
          lookup_type = 1;
        } else {
          strcpy(lookup,"\01\02__MSBROWSE__\02");
          lookup_type = 1;
        } else {
-         lookup_type = 0x1d;
+         lookup_type = 0x1b;
        }
       }
 
        }
       }