loadparm.c: Added new netbios aliases parameter (code from Cisco)
authorSamba Release Account <samba-bugs@samba.org>
Thu, 31 Jul 1997 18:47:26 +0000 (18:47 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Thu, 31 Jul 1997 18:47:26 +0000 (18:47 +0000)
nameannounce.c: Code to announce aliases as well as our own names.
namedbsubnet.c: Code to add the aliases to the server list.
nameserv.c: Code to defend our aliases on the namelist.
namework.c: Code to check it's one of our aliases.
nmbd.c: Code to initialise the aliases.
proto.h: Fixup protos.
util.c: Code to check it's one of our aliases.
All above code based on code for 1.9.16p11 donated by Cisco
from Ben Woodard <bwoodard@luthien.cisco.com>
Jeremy (jallison@whistle.com)
(This used to be commit a2ce1c0cb1331551ff728dcfe3260fab4cd827e5)

source3/include/proto.h
source3/lib/util.c
source3/nameannounce.c
source3/namedbsubnet.c
source3/nameserv.c
source3/namework.c
source3/nmbd/nmbd.c
source3/param/loadparm.c

index 23f7f191fb82252147b8cbce89563e5730094b65..0fa4251b8275a09b843b3aea2bd0a52ae589612e 100644 (file)
@@ -146,6 +146,7 @@ char *lp_wins_server(void);
 char *lp_interfaces(void);
 char *lp_socket_address(void);
 char *lp_nis_home_map_name(void);
+char *lp_netbios_aliases(void);
 BOOL lp_dns_proxy(void);
 BOOL lp_wins_support(void);
 BOOL lp_wins_proxy(void);
@@ -871,8 +872,8 @@ uint32 file_size(char *file_name);
 char *attrib_string(int mode);
 int StrCaseCmp(const char *s, const char *t);
 int StrnCaseCmp(const char *s, const char *t, int n);
-BOOL strequal(char *s1,char *s2);
-BOOL strnequal(char *s1,char *s2,int n);
+BOOL strequal(const char *s1,const char *s2);
+BOOL strnequal(const char *s1,const char *s2,int n);
 BOOL strcsequal(char *s1,char *s2);
 void strlower(char *s);
 void strupper(char *s);
@@ -965,6 +966,7 @@ void free_namearray(name_compare_entry *name_array);
 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
 int file_lock(char *name,int timeout);
 void file_unlock(int fd);
+BOOL is_myname(const char *s);
 
 /*The following definitions come from  vt_mode.c  */
 
index 51bb2b4a16adf8c7dfb0e94ede4bfc01a436affb..9982d105adc727fcffd92af273daf8769aa6c8e3 100644 (file)
@@ -74,6 +74,7 @@ pstring user_socket_options="";
 pstring sesssetup_user="";
 pstring myname = "";
 fstring myworkgroup = "";
+char **my_netbios_names;
 
 int smb_read_error = 0;
 
@@ -834,7 +835,7 @@ int StrnCaseCmp(const char *s, const char *t, int n)
 /*******************************************************************
   compare 2 strings 
 ********************************************************************/
-BOOL strequal(char *s1,char *s2)
+BOOL strequal(const char *s1, const char *s2)
 {
   if (s1 == s2) return(True);
   if (!s1 || !s2) return(False);
@@ -845,7 +846,7 @@ BOOL strequal(char *s1,char *s2)
 /*******************************************************************
   compare 2 strings up to and including the nth char.
   ******************************************************************/
-BOOL strnequal(char *s1,char *s2,int n)
+BOOL strnequal(const char *s1,const char *s2,int n)
 {
   if (s1 == s2) return(True);
   if (!s1 || !s2 || !n) return(False);
@@ -3741,3 +3742,20 @@ void file_unlock(int fd)
 #endif
   close(fd);
 }
+
+/*******************************************************************
+is the name specified one of my netbios names
+returns true is it is equal, false otherwise
+********************************************************************/
+BOOL is_myname(const char *s)
+{
+  int n;
+  BOOL ret = False;
+
+  for (n=0; my_netbios_names[n]; n++) {
+    if (strequal(my_netbios_names[n], s))
+      ret=True;
+  }
+  DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
+  return(ret);
+}
index e92e989c313f4f2b0e027f43550cda113cda3a33..2f169e9287c0e534becda3c8031efe16c058aa2c 100644 (file)
@@ -39,6 +39,7 @@ extern struct in_addr ipzero;
 
 extern pstring myname;
 extern fstring myworkgroup;
+extern char **my_netbios_names;
 
 extern int ClientDGRAM;
 extern int ClientNMB;
@@ -202,7 +203,7 @@ void announce_my_servers_removed(void)
                        struct server_record *s;
                        for (s = work->serverlist; s; s = s->next)
                        {
-                               if (!strequal(myname,s->serv.name)) continue;
+                               if (!is_myname(s->serv.name)) continue;
                                announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
                        }
                }
@@ -230,7 +231,9 @@ interface for workgroup %s, name %s\n", work->work_group, name));
       return;
     }
 
-       if (AM_MASTER(work))
+    /* Only do domain announcements if we are a master and it's
+       our name we're being asked to announce. */
+       if (AM_MASTER(work) && strequal(myname,name))
        {
                DEBUG(3,("sending local master announce to %s for %s(1e)\n",
                                                inet_ntoa(d->bcast_ip),work->work_group));
@@ -289,7 +292,6 @@ void announce_host(time_t t)
        {
          uint32 stype = work->ServerType;
          struct server_record *s;
-         BOOL announce = False;
          
          /* must work on the code that does announcements at up to
             30 seconds later if a master browser sends us a request
@@ -315,15 +317,15 @@ void announce_host(time_t t)
          work->lastannounce_time = t;
          
          for (s = work->serverlist; s; s = s->next) {
-           if (strequal(myname, s->serv.name)) { 
-             announce = True; 
-             break; 
-           }
-         }
-         
-         if (announce) {
-           announce_server(d,work,my_name,comment,
+           if (is_myname(s->serv.name)) { 
+              /* If we are any kind of browser or logon server, only 
+                 announce it for our primary name, not our aliases. */
+              if(!strequal(myname, s->serv.name))
+                stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
+                           SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
+             announce_server(d,work,s->serv.name,comment,
                            work->announce_interval,stype);
+           }
          }
          
          if (work->needannounce)
@@ -498,10 +500,12 @@ void announce_remote(time_t t)
   comment = lp_serverstring();
   workgroup = myworkgroup;
 
-  for (ptr=s; next_token(&ptr,s2,NULL); ) {
+  for (ptr=s; next_token(&ptr,s2,NULL); ) 
+  {
     /* the entries are of the form a.b.c.d/WORKGROUP with 
        WORKGROUP being optional */
     char *wgroup;
+    int n;
 
     wgroup = strchr(s2,'/');
     if (wgroup) *wgroup++ = 0;
@@ -510,10 +514,15 @@ void announce_remote(time_t t)
 
     addr = *interpret_addr2(s2);
     
-    do_announce_host(ANN_HostAnnouncement,myname,0x20,*iface_ip(addr),
+    /* Announce all our names including aliases */
+    for (n=0; my_netbios_names[n]; n++) 
+    {
+      char *name = my_netbios_names[n];
+      do_announce_host(ANN_HostAnnouncement,name,0x20,*iface_ip(addr),
                     wgroup,0x1e,addr,
                     REMOTE_ANNOUNCE_INTERVAL,
-                    myname,stype,comment);    
+                    name,stype,comment);    
+    }
   }
 
 }
index 5ddda0a28277c89862aecdf66f78f85a7e6ef87b..6364ebba543e023508bd3d8d01545977a37b3858 100644 (file)
@@ -41,6 +41,7 @@ extern struct in_addr ipzero;
 
 extern pstring myname;
 extern fstring myworkgroup;
+extern char **my_netbios_names;
 
 BOOL updatedlists = True;
 int updatecount = 0;
@@ -214,13 +215,28 @@ void add_workgroup_to_subnet( struct subnet_record *d, char *group)
    */
   if (strequal(myworkgroup, group))
   {
+    int n;
+
     add_my_name_entry(d,group,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
     add_my_name_entry(d,group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
-    /* add samba server name to workgroup list. */
-    add_server_entry(d,w,myname,w->ServerType|SV_TYPE_LOCAL_LIST_ONLY,0,
+
+    /* Add all our server names to the workgroup list. We remove any
+       browser or logon server flags from all but the primary name.
+     */
+    for( n = 0; my_netbios_names[n]; n++)
+    {    
+      char *name = my_netbios_names[n];
+      int stype = w->ServerType;
+
+      if(!strequal(myname, name))
+          stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
+                     SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
+
+      add_server_entry(d,w,name,stype|SV_TYPE_LOCAL_LIST_ONLY,0,
                lp_serverstring(),True);
-    DEBUG(3,("add_workgroup_to_subnet: Added server name entry %s to subnet %s\n",
-                myname, inet_ntoa(d->bcast_ip)));
+      DEBUG(3,("add_workgroup_to_subnet: Added server name entry %s \
+to subnet %s\n", name, inet_ntoa(d->bcast_ip)));
+    }
   }
 }
 
index abad9b28c2ab4e1822645bf7491aaa8a8636251a..96bb1c0eac818c5294d89909f24c9b3909a03091 100644 (file)
@@ -38,6 +38,7 @@ extern int DEBUGLEVEL;
 extern pstring scope;
 extern pstring myname;
 extern fstring myworkgroup;
+extern char **my_netbios_names;
 extern struct in_addr ipzero;
 extern struct in_addr wins_ip;
 
@@ -366,11 +367,16 @@ void add_my_names(void)
 
   for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
   {
+    int n;
     BOOL wins = (lp_wins_support() && (d == wins_subnet));
 
-    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 all our names including aliases. */
+    for (n=0; my_netbios_names[n]; n++) 
+    {
+      add_my_name_entry(d, my_netbios_names[n],0x20,nb_type|NB_ACTIVE);
+      add_my_name_entry(d, my_netbios_names[n],0x03,nb_type|NB_ACTIVE);
+      add_my_name_entry(d, my_netbios_names[n],0x00,nb_type|NB_ACTIVE);
+    }
     
     /* these names are added permanently (ttl of zero) and will NOT be
        refreshed with the WINS server  */
index 97934412e472e49920fda9b667a9346bd8a54237..3e1ac220058bd20b3578d745a46fc9fa7b61c99f 100644 (file)
@@ -112,7 +112,7 @@ void tell_become_backup(void)
              
              num_servers++;
              
-             if (strequal(myname, s->serv.name)) continue;
+             if (is_myname(s->serv.name)) continue;
              
              if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
                num_backups++;
@@ -153,7 +153,7 @@ void tell_become_backup(void)
 BOOL same_context(struct dgram_packet *dgram)
 {
   if (!strequal(dgram->dest_name  .scope,scope )) return(True);
-  if ( strequal(dgram->source_name.name ,myname)) return(True);
+  if ( is_myname(dgram->source_name.name)) return(True);
   
   return(False);
 }
@@ -624,7 +624,7 @@ static void process_announce_request(struct packet_struct *p,char *buf)
   DEBUG(3,("process_announce_request: Announce request from %s to %s token=0x%X\n",
           name,namestr(&dgram->dest_name), token));
   
-  if (strequal(dgram->source_name.name,myname)) return;
+  if (is_myname(dgram->source_name.name)) return;
   
   /* XXXX BUG or FEATURE?: need to ensure that we are a member of
      this workgroup before announcing, particularly as we only
index 10701c24d4153ba219b2538892c221492e86b940..925f975ffef48b5b2a45eb9b9bd3dd76af90799f 100644 (file)
@@ -41,6 +41,7 @@ extern pstring myhostname;
 static pstring host_file;
 extern pstring myname;
 extern fstring myworkgroup;
+extern char **my_netbios_names;
 
 /* are we running as a daemon ? */
 static BOOL is_daemon = False;
@@ -363,7 +364,11 @@ static BOOL open_sockets(BOOL isdaemon, int port)
 static BOOL init_structs()
 {
   extern fstring local_machine;
-  char *p;
+  char *p, *ptr;
+  int namecount;
+  int n;
+  int nodup;
+  pstring nbname;
 
   if (! *myname) {
     strcpy(myname,myhostname);
@@ -372,12 +377,62 @@ static BOOL init_structs()
   }
   strupper(myname);
 
+  /* Add any NETBIOS name aliases. Ensure that the first entry
+     is equal to myname. */
+  /* Work out the max number of netbios aliases that we have */
+  ptr=lp_netbios_aliases();
+  for (namecount=0; next_token(&ptr,nbname,NULL); namecount++)
+    ;
+  if (*myname)
+      namecount++;
+
+  /* Allocate space for the netbios aliases */
+  if((my_netbios_names=(char **)malloc(sizeof(char *)*(namecount+1))) == NULL)
+  {
+     DEBUG(0,("init_structs: malloc fail.\n"));
+     return False;
+  }
+  /* Use the myname string first */
+  namecount=0;
+  if (*myname)
+    my_netbios_names[namecount++] = myname;
+  
+  ptr=lp_netbios_aliases();
+  while (next_token(&ptr,nbname,NULL)) {
+    strupper(nbname);
+    /* Look for duplicates */
+    nodup=1;
+    for(n=0; n<namecount; n++) {
+      if (strcmp(nbname, my_netbios_names[n])==0)
+        nodup=0;
+    }
+    if (nodup)
+      my_netbios_names[namecount++]=strdup(nbname);
+  }
+  
+  /* Check the strdups succeeded. */
+  for(n = 0; n < namecount; n++)
+    if(my_netbios_names[n]==NULL)
+    {
+      DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
+      return False;
+    }
+  
+  /* Terminate name list */
+  my_netbios_names[namecount++]=NULL;
+  
   strcpy(local_machine,myname);
   trim_string(local_machine," "," ");
   p = strchr(local_machine,' ');
-  if (p) *p = 0;
+  if (p) 
+    *p = 0;
   strlower(local_machine);
 
+  DEBUG(5, ("Netbios name list:-\n"));
+  for (n=0; my_netbios_names[n]; n++)
+    DEBUG(5, ("my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n]));
+
   return True;
 }
 
@@ -493,14 +548,19 @@ static void usage(char *pname)
   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
   DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
 
-  get_myname(myhostname,NULL);
+  if(!get_myname(myhostname,NULL))
+  {
+    DEBUG(0,("Unable to get my hostname - exiting.\n"));
+    return -1;
+  }
 
   if (!reload_services(False))
     return(-1);        
 
   codepage_initialise(lp_client_code_page());
 
-  init_structs();
+  if(!init_structs())
+    return -1;
 
   reload_services(True);
 
index df6aff6f9c0fd2ee53b6b4a24794f7ae968c1a62..69204cc13fe1eecfa582c5cb1a2f443527ce0170 100644 (file)
@@ -136,6 +136,7 @@ typedef struct
   char *szSocketAddress;
   char *szNISHomeMapName;
   char *szAnnounceVersion; /* This is initialised in init_globals */
+  char *szNetbiosAliases;
   int max_log_size;
   int mangled_stack;
   int max_xmit;
@@ -403,6 +404,7 @@ struct parm_struct
   {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL},
   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
   {"netbios name",     P_UGSTRING,P_GLOBAL, myname,                     NULL},
+  {"netbios aliases",  P_STRING,  P_GLOBAL, &Globals.szNetbiosAliases,  NULL},
   {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL},
   {"log file",         P_STRING,  P_GLOBAL, &Globals.szLogFile,         NULL},
   {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL},
@@ -831,6 +833,7 @@ FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
 FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
 FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
 FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
+FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
 
 FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)