summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/mangle.h7
-rw-r--r--source3/smbd/dir.c9
-rw-r--r--source3/smbd/filename.c178
-rw-r--r--source3/smbd/mangle.c20
-rw-r--r--source3/smbd/mangle_hash.c515
-rw-r--r--source3/smbd/mangle_hash2.c15
-rw-r--r--source3/smbd/trans2.c3
7 files changed, 376 insertions, 371 deletions
diff --git a/source3/include/mangle.h b/source3/include/mangle.h
index d3218519f8..769278d828 100644
--- a/source3/include/mangle.h
+++ b/source3/include/mangle.h
@@ -1,11 +1,14 @@
+#ifndef _MANGLE_H_
+#define _MANGLE_H_
/*
header for 8.3 name mangling interface
*/
struct mangle_fns {
BOOL (*is_mangled)(const char *s);
- BOOL (*is_8_3)(const char *fname, BOOL check_case);
+ BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards);
void (*reset)(void);
BOOL (*check_cache)(char *s);
- BOOL (*name_map)(char *OutName, BOOL need83, BOOL cache83);
+ void (*name_map)(char *OutName, BOOL need83, BOOL cache83);
};
+#endif /* _MANGLE_H_ */
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 2f641e34fa..7dd425ef8a 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -558,6 +558,12 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
return True;
}
+static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask)
+{
+ mangle_map(filename,True,False,SNUM(conn));
+ return mask_match(filename,mask,False);
+}
+
/****************************************************************************
Get an 8.3 directory entry.
****************************************************************************/
@@ -603,8 +609,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
*/
if ((strcmp(mask,"*.*") == 0) ||
mask_match(filename,mask,False) ||
- (mangle_map(filename,True,False,SNUM(conn)) &&
- mask_match(filename,mask,False)))
+ mangle_mask_match(conn,filename,mask))
{
if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
continue;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index fa2ce893ad..522163d8e1 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -52,16 +52,14 @@ static BOOL fname_equal(char *name1, char *name2)
/****************************************************************************
Mangle the 2nd name and check if it is then equal to the first name.
****************************************************************************/
-static BOOL mangled_equal(char *name1, char *name2, int snum)
+
+static BOOL mangled_equal(char *name1, const char *name2, int snum)
{
pstring tmpname;
- if (mangle_is_8_3(name2, True)) {
- return False;
- }
pstrcpy(tmpname, name2);
- return mangle_map(tmpname, True, False, snum) &&
- strequal(name1, tmpname);
+ mangle_map(tmpname, True, False, snum);
+ return strequal(name1, tmpname);
}
@@ -375,107 +373,111 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
return(True);
}
-
/****************************************************************************
-check a filename - possibly caling reducename
-
-This is called by every routine before it allows an operation on a filename.
-It does any final confirmation necessary to ensure that the filename is
-a valid one for the user to access.
+ Check a filename - possibly caling reducename.
+ This is called by every routine before it allows an operation on a filename.
+ It does any final confirmation necessary to ensure that the filename is
+ a valid one for the user to access.
****************************************************************************/
+
BOOL check_name(char *name,connection_struct *conn)
{
- BOOL ret;
+ BOOL ret;
- errno = 0;
+ errno = 0;
- if (IS_VETO_PATH(conn, name)) {
- DEBUG(5,("file path name %s vetoed\n",name));
- return(0);
- }
+ if (IS_VETO_PATH(conn, name)) {
+ DEBUG(5,("file path name %s vetoed\n",name));
+ return(0);
+ }
- ret = reduce_name(conn,name,conn->connectpath,lp_widelinks(SNUM(conn)));
+ ret = reduce_name(conn,name,conn->connectpath,lp_widelinks(SNUM(conn)));
- /* Check if we are allowing users to follow symlinks */
- /* Patch from David Clerc <David.Clerc@cui.unige.ch>
- University of Geneva */
+ /* Check if we are allowing users to follow symlinks */
+ /* Patch from David Clerc <David.Clerc@cui.unige.ch>
+ University of Geneva */
#ifdef S_ISLNK
- if (!lp_symlinks(SNUM(conn))) {
- SMB_STRUCT_STAT statbuf;
- if ( (conn->vfs_ops.lstat(conn,name,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_mode)) ) {
- DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
- ret=0;
- }
- }
+ if (!lp_symlinks(SNUM(conn))) {
+ SMB_STRUCT_STAT statbuf;
+ if ( (conn->vfs_ops.lstat(conn,name,&statbuf) != -1) &&
+ (S_ISLNK(statbuf.st_mode)) ) {
+ DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
+ ret=0;
+ }
+ }
#endif
- if (!ret)
- DEBUG(5,("check_name on %s failed\n",name));
+ if (!ret)
+ DEBUG(5,("check_name on %s failed\n",name));
- return(ret);
+ return(ret);
}
-
/****************************************************************************
-scan a directory to find a filename, matching without case sensitivity
-
-If the name looks like a mangled name then try via the mangling functions
+ Scan a directory to find a filename, matching without case sensitivity.
+ If the name looks like a mangled name then try via the mangling functions
****************************************************************************/
+
static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache)
{
- void *cur_dir;
- char *dname;
- BOOL mangled;
- pstring name2;
-
- mangled = mangle_is_mangled(name);
-
- /* handle null paths */
- if (*path == 0)
- path = ".";
-
- if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) {
- pstrcpy(name, dname);
- return(True);
- }
-
- /*
- * The incoming name can be mangled, and if we de-mangle it
- * here it will not compare correctly against the filename (name2)
- * read from the directory and then mangled by the mangle_map()
- * call. We need to mangle both names or neither.
- * (JRA).
- */
- if (mangled)
- mangled = !mangle_check_cache( name );
-
- /* open the directory */
- if (!(cur_dir = OpenDir(conn, path, True))) {
- DEBUG(3,("scan dir didn't open dir [%s]\n",path));
- return(False);
- }
+ void *cur_dir;
+ char *dname;
+ BOOL mangled;
+
+ mangled = mangle_is_mangled(name);
+
+ /* handle null paths */
+ if (*path == 0)
+ path = ".";
+
+ if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) {
+ pstrcpy(name, dname);
+ return(True);
+ }
+
+ /*
+ * The incoming name can be mangled, and if we de-mangle it
+ * here it will not compare correctly against the filename (name2)
+ * read from the directory and then mangled by the mangle_map()
+ * call. We need to mangle both names or neither.
+ * (JRA).
+ */
+ if (mangled)
+ mangled = !mangle_check_cache( name );
+
+ /* open the directory */
+ if (!(cur_dir = OpenDir(conn, path, True))) {
+ DEBUG(3,("scan dir didn't open dir [%s]\n",path));
+ return(False);
+ }
- /* now scan for matching names */
- while ((dname = ReadDirName(cur_dir))) {
- if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
- continue;
-
- pstrcpy(name2,dname);
- if (!mangle_map(name2,False,True,SNUM(conn)))
- continue;
-
- if ((mangled && mangled_equal(name,name2,SNUM(conn))) || fname_equal(name, dname)) {
- /* we've found the file, change it's name and return */
- if (docache)
- DirCacheAdd(path,name,dname,SNUM(conn));
- pstrcpy(name, dname);
- CloseDir(cur_dir);
- return(True);
- }
- }
+ /* now scan for matching names */
+ while ((dname = ReadDirName(cur_dir))) {
+ if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
+ continue;
+
+ /*
+ * At this point dname is the unmangled name.
+ * name is either mangled or not, depending on the state of the "mangled"
+ * variable. JRA.
+ */
+
+ /*
+ * Check mangled name against mangled name, or unmangled name
+ * against unmangled name.
+ */
+
+ if ((mangled && mangled_equal(name,dname,SNUM(conn))) || fname_equal(name, dname)) {
+ /* we've found the file, change it's name and return */
+ if (docache)
+ DirCacheAdd(path,name,dname,SNUM(conn));
+ pstrcpy(name, dname);
+ CloseDir(cur_dir);
+ return(True);
+ }
+ }
- CloseDir(cur_dir);
- return(False);
+ CloseDir(cur_dir);
+ return(False);
}
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c
index 66dd2c00b7..392e48afc1 100644
--- a/source3/smbd/mangle.c
+++ b/source3/smbd/mangle.c
@@ -41,11 +41,12 @@ static void mangle_init(void)
int i;
char *method;
- if (mangle_fns) return;
+ if (mangle_fns)
+ return;
method = lp_mangling_method();
- /* find the first mangling method that manages to initialise and
+ /* find the first mangling method that manages to initialise and
matches the "mangling method" parameter */
for (i=0; mangle_backends[i].name && !mangle_fns; i++) {
if (!method || !*method || strcmp(method, mangle_backends[i].name) == 0) {
@@ -83,7 +84,12 @@ BOOL mangle_is_mangled(const char *s)
*/
BOOL mangle_is_8_3(const char *fname, BOOL check_case)
{
- return mangle_fns->is_8_3(fname, check_case);
+ return mangle_fns->is_8_3(fname, check_case, False);
+}
+
+BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case)
+{
+ return mangle_fns->is_8_3(fname, check_case, True);
}
/*
@@ -100,7 +106,8 @@ BOOL mangle_check_cache(char *s)
/*
map a long filename to a 8.3 name.
*/
-BOOL mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum)
+
+void mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum)
{
/* name mangling can be disabled for speed, in which case
we just truncate the string */
@@ -108,11 +115,10 @@ BOOL mangle_map(char *OutName, BOOL need83, BOOL cache83, int snum)
if (need83) {
string_truncate(OutName, 12);
}
- return True;
+ return;
}
/* invoke the inane "mangled map" code */
mangle_map_filename(OutName, snum);
-
- return mangle_fns->name_map(OutName, need83, cache83);
+ mangle_fns->name_map(OutName, need83, cache83);
}
diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c
index 25f0c4dcc9..1d4697474c 100644
--- a/source3/smbd/mangle_hash.c
+++ b/source3/smbd/mangle_hash.c
@@ -139,16 +139,19 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
/* -------------------------------------------------------------------- */
-static NTSTATUS has_valid_chars(const smb_ucs2_t *s)
+static NTSTATUS has_valid_chars(const smb_ucs2_t *s, BOOL allow_wildcards)
{
- if (!s || !*s) return NT_STATUS_INVALID_PARAMETER;
+ if (!s || !*s)
+ return NT_STATUS_INVALID_PARAMETER;
/* CHECK: this should not be necessary if the ms wild chars
are not valid in valid.dat --- simo */
- if (ms_has_wild_w(s)) return NT_STATUS_UNSUCCESSFUL;
+ if (!allow_wildcards && ms_has_wild_w(s))
+ return NT_STATUS_UNSUCCESSFUL;
while (*s) {
- if(!isvalid83_w(*s)) return NT_STATUS_UNSUCCESSFUL;
+ if(!isvalid83_w(*s))
+ return NT_STATUS_UNSUCCESSFUL;
s++;
}
@@ -158,7 +161,9 @@ static NTSTATUS has_valid_chars(const smb_ucs2_t *s)
/* return False if something fail and
* return 2 alloced unicode strings that contain prefix and extension
*/
-static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **prefix, smb_ucs2_t **extension)
+
+static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **prefix,
+ smb_ucs2_t **extension, BOOL allow_wildcards)
{
size_t ext_len;
smb_ucs2_t *p;
@@ -168,12 +173,10 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr
if (!*prefix) {
return NT_STATUS_NO_MEMORY;
}
- if ((p = strrchr_w(*prefix, UCS2_CHAR('.'))))
- {
+ if ((p = strrchr_w(*prefix, UCS2_CHAR('.')))) {
ext_len = strlen_w(p+1);
if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) &&
- (NT_STATUS_IS_OK(has_valid_chars(p+1)))) /* check extension */
- {
+ (NT_STATUS_IS_OK(has_valid_chars(p+1,allow_wildcards)))) /* check extension */ {
*p = 0;
*extension = strdup_w(p+1);
if (!*extension) {
@@ -196,12 +199,14 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr
*
* ************************************************************************** **
*/
-static NTSTATUS is_valid_name(const smb_ucs2_t *fname)
+
+static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards)
{
smb_ucs2_t *str, *p;
NTSTATUS ret = NT_STATUS_OK;
- if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER;
+ if (!fname || !*fname)
+ return NT_STATUS_INVALID_PARAMETER;
/* . and .. are valid names. */
if (strcmp_wa(fname, ".")==0 || strcmp_wa(fname, "..")==0)
@@ -211,8 +216,9 @@ static NTSTATUS is_valid_name(const smb_ucs2_t *fname)
if (*fname == UCS2_CHAR('.'))
return NT_STATUS_UNSUCCESSFUL;
- ret = has_valid_chars(fname);
- if (NT_STATUS_IS_ERR(ret)) return ret;
+ ret = has_valid_chars(fname, allow_wildcards);
+ if (NT_STATUS_IS_ERR(ret))
+ return ret;
str = strdup_w(fname);
p = strchr_w(str, UCS2_CHAR('.'));
@@ -264,27 +270,34 @@ static NTSTATUS is_valid_name(const smb_ucs2_t *fname)
return ret;
}
-static NTSTATUS is_8_3_w(const smb_ucs2_t *fname)
+static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards)
{
smb_ucs2_t *pref = 0, *ext = 0;
size_t plen;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- if (!fname || !*fname) return NT_STATUS_INVALID_PARAMETER;
+ if (!fname || !*fname)
+ return NT_STATUS_INVALID_PARAMETER;
- if (strlen_w(fname) > 12) return NT_STATUS_UNSUCCESSFUL;
+ if (strlen_w(fname) > 12)
+ return NT_STATUS_UNSUCCESSFUL;
if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
return NT_STATUS_OK;
- if (NT_STATUS_IS_ERR(is_valid_name(fname))) goto done;
+ if (NT_STATUS_IS_ERR(is_valid_name(fname, allow_wildcards)))
+ goto done;
- if (NT_STATUS_IS_ERR(mangle_get_prefix(fname, &pref, &ext))) goto done;
+ if (NT_STATUS_IS_ERR(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
+ goto done;
plen = strlen_w(pref);
- if (strchr_wa(pref, '.')) goto done;
- if (plen < 1 || plen > 8) goto done;
- if (ext) if (strlen_w(ext) > 3) goto done;
+ if (strchr_wa(pref, '.'))
+ goto done;
+ if (plen < 1 || plen > 8)
+ goto done;
+ if (ext && (strlen_w(ext) > 3))
+ goto done;
ret = NT_STATUS_OK;
@@ -294,26 +307,29 @@ done:
return ret;
}
-static BOOL is_8_3(const char *fname, BOOL check_case)
+static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards)
{
const char *f;
smb_ucs2_t *ucs2name;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- if (!fname || !*fname) return False;
- if ((f = strrchr(fname, '/')) == NULL) f = fname;
- else f++;
+ if (!fname || !*fname)
+ return False;
+ if ((f = strrchr(fname, '/')) == NULL)
+ f = fname;
+ else
+ f++;
- if (strlen(f) > 12) return False;
+ if (strlen(f) > 12)
+ return False;
ucs2name = acnv_uxu2(f);
- if (!ucs2name)
- {
+ if (!ucs2name) {
DEBUG(0,("is_8_3: internal error acnv_uxu2() failed!\n"));
goto done;
}
- ret = is_8_3_w(ucs2name);
+ ret = is_8_3_w(ucs2name, allow_wildcards);
done:
SAFE_FREE(ucs2name);
@@ -344,21 +360,20 @@ done:
* ************************************************************************** **
*/
static void init_chartest( void )
- {
- char *illegalchars = "*\\/?<>|\":";
- unsigned char *s;
+{
+ char *illegalchars = "*\\/?<>|\":";
+ unsigned char *s;
- memset( (char *)chartest, '\0', 256 );
+ memset( (char *)chartest, '\0', 256 );
- for( s = (unsigned char *)illegalchars; *s; s++ )
- chartest[*s] = ILLEGAL_MASK;
+ for( s = (unsigned char *)illegalchars; *s; s++ )
+ chartest[*s] = ILLEGAL_MASK;
- for( s = (unsigned char *)basechars; *s; s++ )
- chartest[*s] |= BASECHAR_MASK;
-
- ct_initialized = True;
- } /* init_chartest */
+ for( s = (unsigned char *)basechars; *s; s++ )
+ chartest[*s] |= BASECHAR_MASK;
+ ct_initialized = True;
+}
/* ************************************************************************** **
* Return True if the name *could be* a mangled name.
@@ -378,24 +393,22 @@ static void init_chartest( void )
* ************************************************************************** **
*/
static BOOL is_mangled(const char *s)
- {
- char *magic;
-
- if( !ct_initialized )
- init_chartest();
-
- magic = strchr_m( s, magic_char );
- while( magic && magic[1] && magic[2] ) /* 3 chars, 1st is magic. */
- {
- if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
- && isbasechar( toupper(magic[1]) ) /* is 2nd char basechar? */
- && isbasechar( toupper(magic[2]) ) ) /* is 3rd char basechar? */
- return( True ); /* If all above, then true, */
- magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */
- }
- return( False );
- } /* is_mangled */
-
+{
+ char *magic;
+
+ if( !ct_initialized )
+ init_chartest();
+
+ magic = strchr_m( s, magic_char );
+ while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */
+ if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
+ && isbasechar( toupper(magic[1]) ) /* is 2nd char basechar? */
+ && isbasechar( toupper(magic[2]) ) ) /* is 3rd char basechar? */
+ return( True ); /* If all above, then true, */
+ magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */
+ }
+ return( False );
+}
/* ************************************************************************** **
* Compare two cache keys and return a value indicating their ordinal
@@ -417,12 +430,12 @@ static BOOL is_mangled(const char *s)
* ************************************************************************** **
*/
static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
- {
- char *Key1 = (char *)ItemPtr;
- char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1);
+{
+ char *Key1 = (char *)ItemPtr;
+ char *Key2 = (char *)(((ubi_cacheEntryPtr)NodePtr) + 1);
- return( StrCaseCmp( Key1, Key2 ) );
- } /* cache_compare */
+ return( StrCaseCmp( Key1, Key2 ) );
+}
/* ************************************************************************** **
* Free a cache entry.
@@ -438,10 +451,10 @@ static signed int cache_compare( ubi_btItemPtr ItemPtr, ubi_btNodePtr NodePtr )
* ************************************************************************** **
*/
static void cache_free_entry( ubi_trNodePtr WarrenZevon )
- {
- ZERO_STRUCTP(WarrenZevon);
- SAFE_FREE( WarrenZevon );
- } /* cache_free_entry */
+{
+ ZERO_STRUCTP(WarrenZevon);
+ SAFE_FREE( WarrenZevon );
+}
/* ************************************************************************** **
* Initializes or clears the mangled cache.
@@ -459,28 +472,25 @@ static void cache_free_entry( ubi_trNodePtr WarrenZevon )
*
* ************************************************************************** **
*/
+
static void mangle_reset( void )
- {
- if( !mc_initialized )
- {
- (void)ubi_cacheInit( mangled_cache,
- cache_compare,
- cache_free_entry,
- MANGLED_CACHE_MAX_ENTRIES,
- MANGLED_CACHE_MAX_MEMORY );
- mc_initialized = True;
- }
- else
- {
- (void)ubi_cacheClear( mangled_cache );
- }
-
- /*
- (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
- (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
- */
- } /* reset_mangled_cache */
+{
+ if( !mc_initialized ) {
+ (void)ubi_cacheInit( mangled_cache,
+ cache_compare,
+ cache_free_entry,
+ MANGLED_CACHE_MAX_ENTRIES,
+ MANGLED_CACHE_MAX_MEMORY );
+ mc_initialized = True;
+ } else {
+ (void)ubi_cacheClear( mangled_cache );
+ }
+ /*
+ (void)ubi_cacheSetMaxEntries( mangled_cache, lp_mangled_cache_entries() );
+ (void)ubi_cacheSetMaxMemory( mangled_cache, lp_mangled_cache_memory() );
+ */
+}
/* ************************************************************************** **
* Add a mangled name into the cache.
@@ -507,51 +517,49 @@ static void mangle_reset( void )
* ************************************************************************** **
*/
static void cache_mangled_name( char *mangled_name, char *raw_name )
- {
- ubi_cacheEntryPtr new_entry;
- char *s1;
- char *s2;
- size_t mangled_len;
- size_t raw_len;
- size_t i;
-
- /* If the cache isn't initialized, give up. */
- if( !mc_initialized )
- return;
-
- /* Init the string lengths. */
- mangled_len = strlen( mangled_name );
- raw_len = strlen( raw_name );
-
- /* See if the extensions are unmangled. If so, store the entry
- * without the extension, thus creating a "group" reverse map.
- */
- s1 = strrchr( mangled_name, '.' );
- if( s1 && (s2 = strrchr( raw_name, '.' )) )
- {
- i = 1;
- while( s1[i] && (tolower( s1[i] ) == s2[i]) )
- i++;
- if( !s1[i] && !s2[i] )
- {
- mangled_len -= i;
- raw_len -= i;
- }
- }
-
- /* 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 )
- return;
-
- /* Fill the new cache entry, and add it to the cache. */
- s1 = (char *)(new_entry + 1);
- s2 = (char *)&(s1[mangled_len + 1]);
- (void)StrnCpy( s1, mangled_name, mangled_len );
- (void)StrnCpy( s2, raw_name, raw_len );
- ubi_cachePut( mangled_cache, i, new_entry, s1 );
- } /* cache_mangled_name */
+{
+ ubi_cacheEntryPtr new_entry;
+ char *s1;
+ char *s2;
+ size_t mangled_len;
+ size_t raw_len;
+ size_t i;
+
+ /* If the cache isn't initialized, give up. */
+ if( !mc_initialized )
+ return;
+
+ /* Init the string lengths. */
+ mangled_len = strlen( mangled_name );
+ raw_len = strlen( raw_name );
+
+ /* See if the extensions are unmangled. If so, store the entry
+ * without the extension, thus creating a "group" reverse map.
+ */
+ s1 = strrchr( mangled_name, '.' );
+ if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
+ i = 1;
+ while( s1[i] && (tolower( s1[i] ) == s2[i]) )
+ i++;
+ if( !s1[i] && !s2[i] ) {
+ mangled_len -= i;
+ raw_len -= i;
+ }
+ }
+
+ /* 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 )
+ return;
+
+ /* Fill the new cache entry, and add it to the cache. */
+ s1 = (char *)(new_entry + 1);
+ s2 = (char *)&(s1[mangled_len + 1]);
+ (void)StrnCpy( s1, mangled_name, mangled_len );
+ (void)StrnCpy( s2, raw_name, raw_len );
+ ubi_cachePut( mangled_cache, i, new_entry, s1 );
+}
/* ************************************************************************** **
* Check for a name on the mangled name stack
@@ -570,63 +578,57 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
static BOOL check_cache( char *s )
{
- ubi_cacheEntryPtr FoundPtr;
- char *ext_start = NULL;
- char *found_name;
- char *saved_ext = NULL;
-
- /* If the cache isn't initialized, give up. */
- if( !mc_initialized )
- return( False );
-
- FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
-
- /* If we didn't find the name *with* the extension, try without. */
- if( !FoundPtr )
- {
- ext_start = strrchr( s, '.' );
- if( ext_start )
- {
- if((saved_ext = strdup(ext_start)) == NULL)
- return False;
-
- *ext_start = '\0';
- FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
- /*
- * At this point s is the name without the
- * extension. We re-add the extension if saved_ext
- * is not null, before freeing saved_ext.
- */
- }
- }
-
- /* Okay, if we haven't found it we're done. */
- if( !FoundPtr )
- {
- if(saved_ext)
- {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- SAFE_FREE(saved_ext);
- }
- return( False );
- }
-
- /* If we *did* find it, we need to copy it into the string buffer. */
- found_name = (char *)(FoundPtr + 1);
- found_name += (strlen( found_name ) + 1);
-
- (void)pstrcpy( s, found_name );
- if( saved_ext )
- {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- SAFE_FREE(saved_ext);
- }
-
- return( True );
-} /* check_mangled_cache */
+ ubi_cacheEntryPtr FoundPtr;
+ char *ext_start = NULL;
+ char *found_name;
+ char *saved_ext = NULL;
+
+ /* If the cache isn't initialized, give up. */
+ if( !mc_initialized )
+ return( False );
+
+ FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
+
+ /* If we didn't find the name *with* the extension, try without. */
+ if( !FoundPtr ) {
+ ext_start = strrchr( s, '.' );
+ if( ext_start ) {
+ if((saved_ext = strdup(ext_start)) == NULL)
+ return False;
+
+ *ext_start = '\0';
+ FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
+ /*
+ * At this point s is the name without the
+ * extension. We re-add the extension if saved_ext
+ * is not null, before freeing saved_ext.
+ */
+ }
+ }
+
+ /* Okay, if we haven't found it we're done. */
+ if( !FoundPtr ) {
+ if(saved_ext) {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ SAFE_FREE(saved_ext);
+ }
+ return( False );
+ }
+
+ /* If we *did* find it, we need to copy it into the string buffer. */
+ found_name = (char *)(FoundPtr + 1);
+ found_name += (strlen( found_name ) + 1);
+
+ (void)pstrcpy( s, found_name );
+ if( saved_ext ) {
+ /* Replace the saved_ext as it was truncated. */
+ (void)pstrcat( s, saved_ext );
+ SAFE_FREE(saved_ext);
+ }
+ return( True );
+}
/*****************************************************************************
* do the actual mangling to 8.3 format
@@ -634,77 +636,67 @@ static BOOL check_cache( char *s )
*****************************************************************************
*/
static void to_8_3(char *s)
- {
- int csum;
- char *p;
- char extension[4];
- char base[9];
- int baselen = 0;
- int extlen = 0;
-
- extension[0] = 0;
- base[0] = 0;
-
- p = strrchr(s,'.');
- if( p && (strlen(p+1) < (size_t)4) )
- {
- BOOL all_normal = ( strisnormal(p+1) ); /* XXXXXXXXX */
-
- if( all_normal && p[1] != 0 )
- {
- *p = 0;
- csum = str_checksum( s );
- *p = '.';
- }
- else
- csum = str_checksum(s);
- }
- else
- csum = str_checksum(s);
-
- strupper( s );
-
- if( p )
- {
- if( p == s )
- safe_strcpy( extension, "___", 3 );
- else
- {
- *p++ = 0;
- while( *p && extlen < 3 )
- {
- if ( *p != '.') {
- extension[extlen++] = p[0];
- }
- p++;
- }
- extension[extlen] = 0;
- }
- }
-
- p = s;
-
- while( *p && baselen < 5 )
- {
- if (*p != '.') {
- base[baselen++] = p[0];
- }
- p++;
- }
- base[baselen] = 0;
+{
+ int csum;
+ char *p;
+ char extension[4];
+ char base[9];
+ int baselen = 0;
+ int extlen = 0;
+
+ extension[0] = 0;
+ base[0] = 0;
+
+ p = strrchr(s,'.');
+ if( p && (strlen(p+1) < (size_t)4) ) {
+ BOOL all_normal = ( strisnormal(p+1) ); /* XXXXXXXXX */
+
+ if( all_normal && p[1] != 0 ) {
+ *p = 0;
+ csum = str_checksum( s );
+ *p = '.';
+ } else
+ csum = str_checksum(s);
+ } else
+ csum = str_checksum(s);
+
+ strupper( s );
+
+ if( p ) {
+ if( p == s )
+ safe_strcpy( extension, "___", 3 );
+ else {
+ *p++ = 0;
+ while( *p && extlen < 3 ) {
+ if ( *p != '.') {
+ extension[extlen++] = p[0];
+ }
+ p++;
+ }
+ extension[extlen] = 0;
+ }
+ }
- csum = csum % (MANGLE_BASE*MANGLE_BASE);
+ p = s;
+
+ while( *p && baselen < 5 ) {
+ if (*p != '.') {
+ base[baselen++] = p[0];
+ }
+ p++;
+ }
+ base[baselen] = 0;
- (void)slprintf(s, 12, "%s%c%c%c",
- base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
+ csum = csum % (MANGLE_BASE*MANGLE_BASE);
- if( *extension )
- {
- (void)pstrcat( s, "." );
- (void)pstrcat( s, extension );
- }
+ (void)slprintf(s, 12, "%s%c%c%c",
+ base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
- } /* mangle_name_83 */
+ if( *extension ) {
+ (void)pstrcat( s, "." );
+ (void)pstrcat( s, extension );
+ }
+}
/*****************************************************************************
* Convert a filename to DOS format. Return True if successful.
@@ -731,7 +723,8 @@ static void to_8_3(char *s)
*
* ****************************************************************************
*/
-static BOOL name_map(char *OutName, BOOL need83, BOOL cache83)
+
+static void name_map(char *OutName, BOOL need83, BOOL cache83)
{
smb_ucs2_t *OutName_ucs2;
DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName,
@@ -739,14 +732,14 @@ static BOOL name_map(char *OutName, BOOL need83, BOOL cache83)
if (push_ucs2_allocate((void **)&OutName_ucs2, OutName) < 0) {
DEBUG(0, ("push_ucs2_allocate failed!\n"));
- return False;
+ return;
}
- if( !need83 && NT_STATUS_IS_ERR(is_valid_name(OutName_ucs2)))
+ if( !need83 && NT_STATUS_IS_ERR(is_valid_name(OutName_ucs2, False)))
need83 = True;
/* check if it's already in 8.3 format */
- if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2))) {
+ if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2, False))) {
char *tmp = NULL;
/* mangle it into 8.3 */
@@ -763,9 +756,7 @@ static BOOL name_map(char *OutName, BOOL need83, BOOL cache83)
DEBUG(5,("name_map() ==> [%s]\n", OutName));
SAFE_FREE(OutName_ucs2);
- return(True);
-} /* name_map */
-
+}
/*
the following provides the abstraction layer to make it easier
diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c
index 1d81602641..e2c4b43bc3 100644
--- a/source3/smbd/mangle_hash2.c
+++ b/source3/smbd/mangle_hash2.c
@@ -280,7 +280,7 @@ static BOOL is_mangled(const char *name)
simplifies things greatly (it means that we know the string won't
get larger when converted from UNIX to DOS formats)
*/
-static BOOL is_8_3(const char *name, BOOL check_case)
+static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
{
int len, i;
char *dot_p;
@@ -330,8 +330,8 @@ static BOOL is_8_3(const char *name, BOOL check_case)
/* the length are all OK. Now check to see if the characters themselves are OK */
for (i=0; name[i]; i++) {
- /* note that we allow wildcard petterns! */
- if (!FLAG_CHECK(name[i], FLAG_ASCII|FLAG_WILDCARD) && name[i] != '.') {
+ /* note that we may allow wildcard petterns! */
+ if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') {
return False;
}
}
@@ -477,7 +477,7 @@ static BOOL is_legal_name(const char *name)
the name parameter must be able to hold 13 bytes
*/
-static BOOL name_map(char *name, BOOL need83, BOOL cache83)
+static void name_map(char *name, BOOL need83, BOOL cache83)
{
char *dot_p;
char lead_char;
@@ -491,14 +491,14 @@ static BOOL name_map(char *name, BOOL need83, BOOL cache83)
if (!is_reserved_name(name)) {
/* if the name is already a valid 8.3 name then we don't need to
do anything */
- if (is_8_3(name, False)) {
- return True;
+ if (is_8_3(name, False, False)) {
+ return;
}
/* if the caller doesn't strictly need 8.3 then just check for illegal
filenames */
if (!need83 && is_legal_name(name)) {
- return True;
+ return;
}
}
@@ -580,7 +580,6 @@ static BOOL name_map(char *name, BOOL need83, BOOL cache83)
fstrcpy(name, new_name);
/* all done, we've managed to mangle it */
- return True;
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index d5c445c5f3..efb0864a11 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1666,8 +1666,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pstrcpy(short_name,base_name);
/* Mangle if not already 8.3 */
if(!mangle_is_8_3(short_name, True)) {
- if(!mangle_map(short_name,True,True,SNUM(conn)))
- *short_name = '\0';
+ mangle_map(short_name,True,True,SNUM(conn));
}
len = srvstr_push(outbuf, pdata+4, short_name, -1, STR_TERMINATE|STR_UPPER);
data_size = 4 + len;