nmbd_packets.c: nmbd_subnetdb.c: Patch from Andrey Alekseyev <fetch@muffin.arcadia...
authorJeremy Allison <jra@samba.org>
Fri, 20 Feb 1998 19:48:01 +0000 (19:48 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 20 Feb 1998 19:48:01 +0000 (19:48 +0000)
to fix the fact that retransmit_or_expire_response_records() wasn't looking
at the WINS subnet.
server.c: Patch from jkf@soton.ac.uk to add %p (NIS server path) substitution.
smbpass.c: Fix to stop parsing failing on non-valid lines.
trans2.c: Fix for volume serial number code.
util.c:  Patch from jkf@soton.ac.uk to add %p (NIS server path) substitution.
         Fix for warnings under RH5. gcc 2.8.
Jeremy.

source/include/proto.h
source/lib/util.c
source/nmbd/nmbd_packets.c
source/nmbd/nmbd_subnetdb.c
source/passdb/smbpass.c
source/smbd/server.c
source/smbd/trans2.c

index 97017e77b0ba6a2af4be49dc30a36cb44b6d07d1..a5a7ceec6917f3dfe29900524d5e843a20388fab 100644 (file)
@@ -743,6 +743,7 @@ void write_browse_list(time_t t, BOOL force_write);
 BOOL create_subnets();
 BOOL we_are_a_wins_client();
 struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec);
+struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec);
 
 /*The following definitions come from  nmbd_winsproxy.c  */
 
@@ -1485,6 +1486,7 @@ void reset_globals_after_fork();
 char *client_name(void);
 char *client_addr(void);
 char *automount_server(char *user_name);
+char *automount_path(char *user_name);
 void standard_sub_basic(char *str);
 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
 int PutUniCode(char *dst,char *src);
index fa5f6ae40037136ea858072681f90a9946828d08..365a765174242ecb19e14c7d25022f53fc65e813 100644 (file)
@@ -1580,12 +1580,12 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
 #else
   pstring dir2;
   pstring wd;
-  pstring basename;
+  pstring base_name;
   pstring newname;
   char *p=NULL;
   BOOL relative = (*s != '/');
 
-  *dir2 = *wd = *basename = *newname = 0;
+  *dir2 = *wd = *base_name = *newname = 0;
 
   if (widelinks)
     {
@@ -1608,8 +1608,8 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
   /* remove any double slashes */
   string_sub(s,"//","/");
 
-  pstrcpy(basename,s);
-  p = strrchr(basename,'/');
+  pstrcpy(base_name,s);
+  p = strrchr(base_name,'/');
 
   if (!p)
     return(True);
@@ -1634,7 +1634,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
     }
 
 
-    if (p && (p != basename))
+    if (p && (p != base_name))
       {
        *p = 0;
        if (strcmp(p+1,".")==0)
@@ -1643,10 +1643,10 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
          *p = '/';
       }
 
-  if (ChDir(basename) != 0)
+  if (ChDir(base_name) != 0)
     {
       ChDir(wd);
-      DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
+      DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
       return(False);
     }
 
@@ -1657,7 +1657,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks)
       return(False);
     }
 
-  if (p && (p != basename))
+  if (p && (p != base_name))
     {
       strcat(newname,"/");
       strcat(newname,p+1);
@@ -3713,44 +3713,88 @@ char *client_addr(void)
   return addr_buf;
 }
 
+/*******************************************************************
+ Patch from jkf@soton.ac.uk
+ Split Luke's automount_server into YP lookup and string splitter
+ so can easily implement automount_path(). 
+ As we may end up doing both, cache the last YP result. 
+*******************************************************************/
+
+#if (defined(NETGROUP) && defined(AUTOMOUNT))
+static char *automount_lookup(char *user_name)
+{
+  static fstring last_key = "";
+  static pstring last_value = "";
+
+  int nis_error;        /* returned by yp all functions */
+  char *nis_result;     /* yp_match inits this */
+  int nis_result_len;  /* and set this */
+  char *nis_domain;     /* yp_get_default_domain inits this */
+  char *nis_map = (char *)lp_nis_home_map_name();
+
+  if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
+  {
+    DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
+    return last_value;
+  }
+
+  DEBUG(5, ("NIS Domain: %s\n", nis_domain));
+
+  if (!strcmp(user_name, last_key))
+  {
+    nis_result = last_value;
+    nis_result_len = strlen(last_value);
+    nis_error = 0;
+  }
+  else
+  {
+    if ((nis_error = yp_match(nis_domain, nis_map,
+                              user_name, strlen(user_name),
+                              &nis_result, &nis_result_len)) != 0)
+    {
+      DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
+               yperr_string(nis_error), user_name, nis_map));
+    }
+    if (!nis_error && nis_result_len >= sizeof(pstring))
+    {
+      nis_result_len = sizeof(pstring)-1;
+    }
+    fstrcpy(last_key, user_name);
+    strncpy(last_value, nis_result, nis_result_len);
+    last_value[nis_result_len] = '\0';
+  }
+
+  DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
+  return last_value;
+}
+#endif
+
+/*******************************************************************
+ Patch from jkf@soton.ac.uk
+ This is Luke's original function with the NIS lookup code
+ moved out to a separate function.
+*******************************************************************/
+
 char *automount_server(char *user_name)
 {
        static pstring server_name;
 
 #if (defined(NETGROUP) && defined (AUTOMOUNT))
-       int nis_error;        /* returned by yp all functions */
-       char *nis_result;     /* yp_match inits this */
-       int nis_result_len;  /* and set this */
-       char *nis_domain;     /* yp_get_default_domain inits this */
-       char *nis_map = (char *)lp_nis_home_map_name();
        int home_server_len;
 
        /* set to default of local machine */
        pstrcpy(server_name, local_machine);
 
-       if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
+       if (lp_nis_home_map())
        {
-               DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
-       }
-
-       DEBUG(5, ("NIS Domain: %s\n", nis_domain));
-
-       if ((nis_error = yp_match(nis_domain, nis_map,
-                       user_name, strlen(user_name),
-                       &nis_result, &nis_result_len)) != 0)
-       {
-               DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
-       }
-
-       if (!nis_error && lp_nis_home_map())
-       {
-               home_server_len = strcspn(nis_result,":");
+               char *automount_value = automount_lookup(user_name);
+               home_server_len = strcspn(automount_value,":");
                DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
                if (home_server_len > sizeof(pstring))
                {
                        home_server_len = sizeof(pstring);
                }
-               strncpy(server_name, nis_result, home_server_len);
+               strncpy(server_name, automount_value, home_server_len);
                 server_name[home_server_len] = '\0';
        }
 #else
@@ -3763,6 +3807,44 @@ char *automount_server(char *user_name)
        return server_name;
 }
 
+/*******************************************************************
+ Patch from jkf@soton.ac.uk
+ Added this to implement %p (NIS auto-map version of %H)
+*******************************************************************/
+
+char *automount_path(char *user_name)
+{
+       static pstring server_path;
+
+#if (defined(NETGROUP) && defined (AUTOMOUNT))
+       char *home_path_start;
+
+       /* set to default of no string */
+       server_path[0] = 0;
+
+       if (lp_nis_home_map())
+       {
+               char *automount_value = automount_lookup(user_name);
+               home_path_start = strchr(automount_value,':');
+               if (home_path_start != NULL)
+               {
+                 DEBUG(5, ("NIS lookup succeeded.  Home path is: %s\n",
+                       home_path_start?(home_path_start+1):""));
+                 strcpy(server_path, home_path_start+1);
+               }
+       }
+#else
+       /* use the passwd entry instead of the auto-map server entry */
+       /* pstrcpy() copes with get_home_dir() returning NULL */
+       pstrcpy(server_path, get_home_dir(user_name));
+#endif
+
+       DEBUG(4,("Home server path: %s\n", server_path));
+
+       return server_path;
+}
+
+
 /*******************************************************************
 sub strings with useful parameters
 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
index 9dad5ddaa990fb3d43719ff2fa30cd356a259a00..cd99343e709249a5d37bd42ca7903bcd4814ced4 100644 (file)
@@ -1486,14 +1486,18 @@ void run_packet_queue()
 
 /*******************************************************************
  Retransmit or timeout elements from all the outgoing subnet response
- record queues.
+ record queues. NOTE that this code must also check the WINS server
+ subnet for response records to timeout as the WINS server code
+ can send requests to check if a client still owns a name.
+ (Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>).
 ******************************************************************/
 
 void retransmit_or_expire_response_records(time_t t)
 {
   struct subnet_record *subrec;
 
-  for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+  for (subrec = FIRST_SUBNET; subrec; 
+               subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec))
   {
     struct response_record *rrec, *nextrrec;
 
index 5e18fe9cc0c730e75a662e52823fa4bfea1d2a71..07692cc82c299173fd98dcb4bcb7a1fd5b0dac94 100644 (file)
@@ -289,3 +289,27 @@ struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec
   else
     return subrec->next;
 }
+
+/*******************************************************************
+ Access function used by retransmit_or_expire_response_records() in
+ nmbd_packets.c. Patch from Andrey Alekseyev <fetch@muffin.arcadia.spb.ru>
+ Needed when we need to enumerate all the broadcast, unicast and
+ WINS subnets.
+******************************************************************/
+
+struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
+{
+  if(subrec == unicast_subnet)
+    if(wins_server_subnet)
+      return wins_server_subnet;
+    else
+      return NULL;
+
+  if(wins_server_subnet && subrec == wins_server_subnet)
+    return NULL;
+
+  if((subrec->next == NULL) && we_are_a_wins_client())
+    return unicast_subnet;
+  else
+    return subrec->next;
+}
index ea386bfa9df0dd319dca8fdaba88fdbf211f8aa3..fbda8949bcb00686744d1de83d9dafd7d4360338 100644 (file)
@@ -225,9 +225,7 @@ struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
                p++;            /* Go past ':' */
                if (!isdigit(*p)) {
                        DEBUG(0, ("get_smbpwd_entry: malformed password entry (uid not number)\n"));
-                       fclose(fp);
-                       pw_file_unlock(lockfd);
-                       return NULL;
+                       continue;
                }
 
                uidval = atoi((char *) p);
@@ -240,9 +238,7 @@ struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
                if (*p != ':')
                {
                        DEBUG(0, ("get_smbpwd_entry: malformed password entry (no : after uid)\n"));
-                       fclose(fp);
-                       pw_file_unlock(lockfd);
-                       return NULL;
+                       continue;
                }
 
                if (name != NULL)
index c2880b0e890cc0c11c4bbe23fe32cde0de7b07ec..9c25a21000f65e66239a9d68dd36e3f31ddd9935 100644 (file)
@@ -4569,6 +4569,15 @@ void standard_sub(int cnum,char *str)
         case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
         case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
         case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
+       /* 
+         * Patch from jkf@soton.ac.uk
+        * Left the %N (NIS server name) in standard_sub_basic as it 
+        * is a feature for logon servers, hence uses the username. 
+        * The %p (NIS server path) code is here as it is used
+        * instead of the default "path =" string in [homes] and so
+        * needs the service name, not the username. 
+         */
+       case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break;
         case '\0' : p++; break; /* don't run off the end of the string */
         default  : p+=2; break;
       }
index 6eda891e328601770de7bfdd880c05a06417001a..893f1adc66b0c28fd207c22ebe423a3e87664d1e 100644 (file)
@@ -977,7 +977,7 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize
        * Add volume serial number - hash of a combination of
        * the called hostname and the service name.
        */
-      SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) );
+      SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
       SCVAL(pdata,l2_vol_cch,volname_len);
       StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
       DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
@@ -1002,7 +1002,7 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize
        * Add volume serial number - hash of a combination of
        * the called hostname and the service name.
        */
-      SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) );
+      SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
       SIVAL(pdata,12,2*strlen(vname));
       PutUniCode(pdata+18,vname);      
       DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),