Slightly modified version of name mangle patch from Ulrik Dickow <ukd@kampsax.dk>.
authorJeremy Allison <jra@samba.org>
Wed, 17 Feb 1999 02:00:06 +0000 (02:00 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 17 Feb 1999 02:00:06 +0000 (02:00 +0000)
Exposes a parameter in name_map_mangle() to allow the caller to decide whether
to add the mapping to the mangle cache or not. This allows some callers not
to add to the cache in circumstances where the client is only sending the
mangled name (NT).
Jeremy.

source/include/proto.h
source/smbd/dir.c
source/smbd/filename.c
source/smbd/mangle.c
source/smbd/reply.c
source/smbd/trans2.c

index c28dd10dcb6a0e2372fb2abb3c8d0480c8145ac8..fcd4cc84e3552d86da06a862ff13b0af57c2c1a6 100644 (file)
@@ -2401,7 +2401,7 @@ BOOL is_8_3( char *fname, BOOL check_case );
 void reset_mangled_cache( void );
 BOOL check_mangled_cache( char *s );
 void mangle_name_83( char *s);
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum);
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum);
 
 /*The following definitions come from  smbd/message.c  */
 
index f4d25170081faa02aa8b73aba37d4908defcbe38..0512b0bad7561661b4369442fbe0ffb8bbd60ede 100644 (file)
@@ -558,7 +558,7 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
 }
 
 /****************************************************************************
- Get a directory entry.
+ Get an 8.3 directory entry.
 ****************************************************************************/
 
 BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
@@ -579,64 +579,71 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
               strequal(conn->dirpath,".") ||
               strequal(conn->dirpath,"/"));
   
-  needslash = 
-        ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+  needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
 
   if (!conn->dirptr)
     return(False);
   
   while (!found)
-    {
-      dname = ReadDirName(conn->dirptr);
+  {
+    BOOL filename_is_mask = False;
+    dname = ReadDirName(conn->dirptr);
 
-      DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
-              (long)conn->dirptr,TellDir(conn->dirptr)));
+    DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+          (long)conn->dirptr,TellDir(conn->dirptr)));
       
-      if (dname == NULL) 
-       return(False);
+    if (dname == NULL) 
+      return(False);
       
-      pstrcpy(filename,dname);      
-
-      if ((strcmp(filename,mask) == 0) ||
-         (name_map_mangle(filename,True,SNUM(conn)) &&
-          mask_match(filename,mask,False,False)))
-       {
-         if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
-           continue;
-
-         pstrcpy(fname,filename);
-         *path = 0;
-         pstrcpy(path,conn->dirpath);
-          if(needslash)
-           pstrcat(path,"/");
-         pstrcpy(pathreal,path);
-         pstrcat(path,fname);
-         pstrcat(pathreal,dname);
-         if (dos_stat(pathreal,&sbuf) != 0) 
-           {
-             DEBUG(5,("Couldn't stat 1 [%s]\n",path));
-             continue;
-           }
-
-         if (check_descend &&
-             !strequal(fname,".") && !strequal(fname,".."))
-           continue;
+    pstrcpy(filename,dname);      
+
+    if ((filename_is_mask = (strcmp(filename,mask) == 0)) ||
+        (name_map_mangle(filename,True,False,SNUM(conn)) &&
+         mask_match(filename,mask,False,False)))
+    {
+      if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+        continue;
+
+      pstrcpy(fname,filename);
+      *path = 0;
+      pstrcpy(path,conn->dirpath);
+      if(needslash)
+        pstrcat(path,"/");
+      pstrcpy(pathreal,path);
+      pstrcat(path,fname);
+      pstrcat(pathreal,dname);
+      if (dos_stat(pathreal,&sbuf) != 0) 
+      {
+        DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+        continue;
+      }
+
+      if (check_descend && !strequal(fname,".") && !strequal(fname,".."))
+        continue;
          
-         *mode = dos_mode(conn,pathreal,&sbuf);
+      *mode = dos_mode(conn,pathreal,&sbuf);
 
-         if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
-           DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
-           continue;
-         }
+      if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) 
+      {
+        DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+        continue;
+      }
 
-         *size = sbuf.st_size;
-         *date = sbuf.st_mtime;
+      if (!filename_is_mask)
+      {
+        /* Now we can allow the mangled cache to be updated */
+        pstrcpy(filename,dname);
+        name_map_mangle(filename,True,True,SNUM(conn));
+      }
 
-         DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
+      *size = sbuf.st_size;
+      *date = sbuf.st_mtime;
+
+      DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
          
-         found = True;
-       }
+      found = True;
     }
+  }
 
   return(found);
 }
index 134169ec2d9d7cdad072b158e61666cc478b749d..e941818dbb1cf3d547c493254092968da2cc9ebc 100644 (file)
@@ -730,7 +730,8 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
        continue;
 
       pstrcpy(name2,dname);
-      if (!name_map_mangle(name2,False,SNUM(conn))) continue;
+      if (!name_map_mangle(name2,False,True,SNUM(conn)))
+        continue;
 
       if ((mangled && mangled_equal(name,name2))
          || fname_equal(name, name2))
index fd0a622e4d045e774d107c20bd44947d0ae0c3f2..f11ed0a7ebe5e054fc330e4ed9abca226a294fda 100644 (file)
@@ -514,7 +514,7 @@ void reset_mangled_cache( void )
  *
  *          If the extension of the raw name maps directly to the
  *          extension of the mangled name, then we'll store both names
- *          *without* extensions.  That way, we can provide consistant
+ *          *without* extensions.  That way, we can provide consistent
  *          reverse mangling for all names that match.  The test here is
  *          a bit more careful than the one done in earlier versions of
  *          mangle.c:
@@ -561,7 +561,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
       }
     }
 
-  /* Allocate a new cache entry.  If the allcoation fails, just return. */
+  /* Allocate a new cache entry.  If the allocation fails, just return. */
   i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
   new_entry = malloc( i );
   if( !new_entry )
@@ -956,6 +956,11 @@ void mangle_name_83( char *s)
  *                    signal that a client does not require name mangling,
  *                    thus skipping the name mangling even on shares which
  *                    have name-mangling turned on.
+ *          cache83 - If False, the mangled name cache will not be updated.
+ *                    This is usually used to prevent that we overwrite
+ *                    a conflicting cache entry prematurely, i.e. before
+ *                    we know whether the client is really interested in the
+ *                    current name.  (See PR#13758).  UKD.
  *          snum    - Share number.  This identifies the share in which the
  *                    name exists.
  *
@@ -964,11 +969,11 @@ void mangle_name_83( char *s)
  *
  * ****************************************************************************
  */
-BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
+BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
 {
        char *map;
-       DEBUG(5,("name_map_mangle( %s, %s, %d )\n", 
-                OutName, need83?"TRUE":"FALSE", snum));
+       DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
+               need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum));
 
 #ifdef MANGLE_LONG_FILENAMES
        if( !need83 && is_illegal_name(OutName) )
@@ -984,17 +989,19 @@ BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
 
        /* check if it's already in 8.3 format */
        if (need83 && !is_8_3(OutName, True)) {
-               char *tmp; 
+               char *tmp = NULL
 
                if (!lp_manglednames(snum)) {
                        return(False);
                }
 
                /* mangle it into 8.3 */
-               tmp = strdup(OutName);
+               if (cache83)
+                       tmp = strdup(OutName);
+
                mangle_name_83(OutName);
 
-               if(tmp) {
+               if(tmp != NULL) {
                        cache_mangled_name(OutName, tmp);
                        free(tmp);
                }
index 6728ef61e3c1cee3ce8e5337edbff48aba9d9825..3d5062f228f7bbf68e27592a8b90db4c47f33997 100644 (file)
@@ -1646,12 +1646,12 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
   if(com == SMBmknew)
   {
     /* We should fail if file exists. */
-    ofun = 0x10;
+    ofun = FILE_CREATE_IF_NOT_EXIST;
   }
   else
   {
     /* SMBcreate - Create if file doesn't exist, truncate if it does. */
-    ofun = 0x12;
+    ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
   }
 
   /* Open file in dos compatibility share mode. */
index f249421dd19b4432d4817e51e569ded25d4b0d25..c1796574cf0153d6789f5388e79228fc64e74caa 100644 (file)
@@ -376,7 +376,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
 
       pstring newname;
       pstrcpy( newname, fname);
-      name_map_mangle( newname, True, SNUM(conn));
+      name_map_mangle( newname, True, False, SNUM(conn));
       got_match = mask_match(newname, mask, case_sensitive, True);
     }
 
@@ -419,7 +419,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
     }
   }
 
-  name_map_mangle(fname,False,SNUM(conn));
+  name_map_mangle(fname,False,True,SNUM(conn));
 
   p = pdata;
   nameptr = p;
@@ -515,7 +515,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
       SIVAL(p,0,0); p += 4;
       if (!was_8_3) {
         pstrcpy(p+2,fname);
-        if (!name_map_mangle(p+2,True,SNUM(conn)))
+        if (!name_map_mangle(p+2,True,True,SNUM(conn)))
           (p+2)[12] = 0;
       } else
         *(p+2) = 0;
@@ -828,7 +828,7 @@ static int call_trans2findfirst(connection_struct *conn,
    */
 
   if(!is_8_3( mask, False))
-    name_map_mangle(mask, True, SNUM(conn));
+    name_map_mangle(mask, True, True, SNUM(conn));
 
   return(-1);
 }
@@ -975,7 +975,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
        */
 
       if(dname != NULL)
-        name_map_mangle( dname, False, SNUM(conn));
+        name_map_mangle( dname, False, True, SNUM(conn));
 
       if(dname && strcsequal( resume_name, dname))
       {
@@ -1003,7 +1003,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
          */
 
         if(dname != NULL)
-          name_map_mangle( dname, False, SNUM(conn));
+          name_map_mangle( dname, False, True, SNUM(conn));
 
         if(dname && strcsequal( resume_name, dname))
         {
@@ -1425,7 +1425,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
         /* Mangle if not already 8.3 */
         if(!is_8_3(short_name, True))
         {
-          if(!name_map_mangle(short_name,True,SNUM(conn)))
+          if(!name_map_mangle(short_name,True,True,SNUM(conn)))
             *short_name = '\0';
         }
         strupper(short_name);