diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/mangle.h | 7 | ||||
-rw-r--r-- | source3/smbd/dir.c | 9 | ||||
-rw-r--r-- | source3/smbd/filename.c | 178 | ||||
-rw-r--r-- | source3/smbd/mangle.c | 20 | ||||
-rw-r--r-- | source3/smbd/mangle_hash.c | 515 | ||||
-rw-r--r-- | source3/smbd/mangle_hash2.c | 15 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 3 |
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; |