diff options
author | Andrew Tridgell <tridge@samba.org> | 1999-12-13 13:27:58 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1999-12-13 13:27:58 +0000 |
commit | 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 (patch) | |
tree | 866dd15416c3d8554bb207709f433a87ad0c012d /source3/smbd/mangle.c | |
parent | f6276724bafdb6145c0c7b565172d80cb04516ea (diff) | |
download | samba-3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7.tar.gz samba-3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7.tar.bz2 samba-3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7.zip |
first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
(This used to be commit 453a822a76780063dff23526c35408866d0c0154)
Diffstat (limited to 'source3/smbd/mangle.c')
-rw-r--r-- | source3/smbd/mangle.c | 101 |
1 files changed, 71 insertions, 30 deletions
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index b829746a32..48e16e5332 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -63,11 +63,13 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */ * global. There is a call to lp_magicchar() in server.c * that is used to override the initial value. * - * basechars - The set of 36 characters used for name mangling. This + * MANGLE_BASE - This is the number of characters we use for name mangling. + * + * basechars - The set characters used for name mangling. This * is static (scope is this file only). * - * base36() - Macro used to select a character from basechars (i.e., - * base36(n) will return the nth digit, modulo 36). + * mangle() - Macro used to select a character from basechars (i.e., + * mangle(n) will return the nth digit, modulo MANGLE_BASE). * * chartest - array 0..255. The index range is the set of all possible * values of a byte. For each byte value, the content is a @@ -110,12 +112,13 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */ char magic_char = '~'; -static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%"; +#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1) static unsigned char chartest[256] = { 0 }; static BOOL ct_initialized = False; -#define base36(V) ((char)(basechars[(V) % 36])) +#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE])) #define BASECHAR_MASK 0xf0 #define ILLEGAL_MASK 0x0f #define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK ) @@ -148,7 +151,7 @@ static void init_chartest( void ) char *illegalchars = "*\\/?<>|\":"; unsigned char *s; - bzero( (char *)chartest, 256 ); + memset( (char *)chartest, '\0', 256 ); for( s = (unsigned char *)illegalchars; *s; s++ ) chartest[*s] = ILLEGAL_MASK; @@ -514,7 +517,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: @@ -533,9 +536,9 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) ubi_cacheEntryPtr new_entry; char *s1; char *s2; - int mangled_len; - int raw_len; - int i; + size_t mangled_len; + size_t raw_len; + size_t i; /* If the cache isn't initialized, give up. */ if( !mc_initialized ) @@ -561,7 +564,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 ) @@ -589,11 +592,13 @@ static void cache_mangled_name( char *mangled_name, char *raw_name ) * * ************************************************************************** ** */ + BOOL check_mangled_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 ) @@ -603,19 +608,34 @@ BOOL check_mangled_cache( char *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 ); - *ext_start = '.'; - } + /* + * 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 ); + free(saved_ext); + } return( False ); + } /* If we *did* find it, we need to copy it into the string buffer. */ found_name = (char *)(FoundPtr + 1); @@ -624,13 +644,17 @@ BOOL check_mangled_cache( char *s ) DEBUG( 3, ("Found %s on mangled stack ", s) ); (void)pstrcpy( s, found_name ); - if( ext_start ) - (void)pstrcat( s, ext_start ); + if( saved_ext ) + { + /* Replace the saved_ext as it was truncated. */ + (void)pstrcat( s, saved_ext ); + free(saved_ext); + } DEBUG( 3, ("as %s\n", s) ); return( True ); - } /* check_mangled_cache */ +} /* check_mangled_cache */ /* ************************************************************************** ** @@ -652,6 +676,12 @@ static char *map_filename( char *s, /* This is null terminated */ pstrcpy( matching_bit, "" ); /* Match but no star gets this. */ pp = pat; /* Initialize the pointers. */ sp = s; + + if( strequal(s, ".") || strequal(s, "..")) + { + return NULL; /* Do not map '.' and '..' */ + } + if( (len == 1) && (*pattern == '*') ) { return NULL; /* Impossible, too ambiguous for */ @@ -807,7 +837,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) */ void mangle_name_83( char *s) { - int csum = str_checksum(s); + int csum; char *p; char extension[4]; char base[9]; @@ -829,7 +859,11 @@ void mangle_name_83( char *s) csum = str_checksum( s ); *p = '.'; } + else + csum = str_checksum(s); } + else + csum = str_checksum(s); strupper( s ); @@ -855,7 +889,7 @@ void mangle_name_83( char *s) } else { - extension[extlen++] = base36( (unsigned char)*p ); + extension[extlen++] = mangle( (unsigned char)*p ); } p += 2; break; @@ -889,7 +923,7 @@ void mangle_name_83( char *s) } else { - base[baselen++] = base36( (unsigned char)*p ); + base[baselen++] = mangle( (unsigned char)*p ); } p += 2; break; @@ -906,10 +940,10 @@ void mangle_name_83( char *s) } base[baselen] = 0; - csum = csum % (36*36); + csum = csum % (MANGLE_BASE*MANGLE_BASE); (void)slprintf(s, 12, "%s%c%c%c", - base, magic_char, base36( csum/36 ), base36( csum ) ); + base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) ); if( *extension ) { @@ -935,6 +969,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. * @@ -943,11 +982,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) ) @@ -963,17 +1002,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); } |