Ignore:
Timestamp:
Sep 30, 2007, 3:42:50 AM (18 years ago)
Author:
Paul Smedley
Message:

Update trunk to 3.2.0pre1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/samba/source/smbd/mangle_hash.c

    r1 r77  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Name mangling
     
    55   Copyright (C) Simo Sorce 2001
    66   Copyright (C) Andrew Bartlett 2002
    7    
     7   Copyright (C) Jeremy Allison 2007
     8
    89   This program is free software; you can redistribute it and/or modify
    910   it under the terms of the GNU General Public License as published by
    10    the Free Software Foundation; either version 2 of the License, or
     11   the Free Software Foundation; either version 3 of the License, or
    1112   (at your option) any later version.
    12    
     13
    1314   This program is distributed in the hope that it will be useful,
    1415   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1516   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1617   GNU General Public License for more details.
    17    
     18
    1819   You should have received a copy of the GNU General Public License
    19    along with this program; if not, write to the Free Software
    20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     20   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    2121*/
    2222
     
    246246        if (strlen_w(fname) > 12)
    247247                return NT_STATUS_UNSUCCESSFUL;
    248        
     248
    249249        if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
    250250                return NT_STATUS_OK;
     
    253253        if (*fname == UCS2_CHAR('.'))
    254254                return NT_STATUS_UNSUCCESSFUL;
    255        
     255
    256256        if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
    257257                goto done;
     
    295295        if (strlen(f) > 12)
    296296                return False;
    297        
     297
    298298        size = push_ucs2_allocate(&ucs2name, f);
    299299        if (size == (size_t)-1) {
     
    307307        SAFE_FREE(ucs2name);
    308308
    309         if (!NT_STATUS_IS_OK(ret)) { 
    310                 return False;
    311         }
    312        
     309        if (!NT_STATUS_IS_OK(ret)) {
     310                return False;
     311        }
     312
    313313        return True;
    314314}
    315 
    316 
    317315
    318316/* -------------------------------------------------------------------------- **
     
    332330 * ************************************************************************** **
    333331 */
     332
    334333static void init_chartest( void )
    335334{
    336335        const unsigned char *s;
    337  
     336
    338337        memset( (char *)chartest, '\0', 256 );
    339338
     
    362361 * ************************************************************************** **
    363362 */
     363
    364364static BOOL is_mangled(const char *s, const struct share_params *p)
    365365{
     
    408408**************************************************************************/
    409409
    410 static void cache_mangled_name( const char mangled_name[13], char *raw_name )
     410static void cache_mangled_name( const char mangled_name[13],
     411                                const char *raw_name )
    411412{
    412413        TDB_DATA data_val;
     
    438439
    439440        /* Allocate a new cache entry.  If the allocation fails, just return. */
    440         data_val.dptr = raw_name;
    441         data_val.dsize = strlen(raw_name)+1;
     441        data_val = string_term_tdb_data(raw_name);
    442442        if (tdb_store_bystring(tdb_mangled_cache, mangled_name_key, data_val, TDB_REPLACE) != 0) {
    443443                DEBUG(0,("cache_mangled_name: Error storing entry %s -> %s\n", mangled_name_key, raw_name));
     
    462462 */
    463463
    464 static BOOL check_cache( char *s, size_t maxlen, const struct share_params *p )
     464static BOOL lookup_name_from_8_3(TALLOC_CTX *ctx,
     465                                const char *in,
     466                                char **out, /* talloced on the given context. */
     467                                const struct share_params *p)
    465468{
    466469        TDB_DATA data_val;
    467         char *ext_start = NULL;
    468470        char *saved_ext = NULL;
     471        char *s = talloc_strdup(ctx, in);
    469472
    470473        magic_char = lp_magicchar(p);
    471474
    472475        /* If the cache isn't initialized, give up. */
    473         if( !tdb_mangled_cache )
    474                 return( False );
     476        if(!s || !tdb_mangled_cache ) {
     477                TALLOC_FREE(s);
     478                return False;
     479        }
    475480
    476481        data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
     
    478483        /* If we didn't find the name *with* the extension, try without. */
    479484        if(data_val.dptr == NULL || data_val.dsize == 0) {
    480                 ext_start = strrchr( s, '.' );
     485                char *ext_start = strrchr( s, '.' );
    481486                if( ext_start ) {
    482                         if((saved_ext = SMB_STRDUP(ext_start)) == NULL)
     487                        if((saved_ext = talloc_strdup(ctx,ext_start)) == NULL) {
     488                                TALLOC_FREE(s);
    483489                                return False;
     490                        }
    484491
    485492                        *ext_start = '\0';
    486493                        data_val = tdb_fetch_bystring(tdb_mangled_cache, s);
    487                         /* 
     494                        /*
    488495                         * At this point s is the name without the
    489496                         * extension. We re-add the extension if saved_ext
     
    495502        /* Okay, if we haven't found it we're done. */
    496503        if(data_val.dptr == NULL || data_val.dsize == 0) {
    497                 if(saved_ext) {
    498                         /* Replace the saved_ext as it was truncated. */
    499                         (void)safe_strcat( s, saved_ext, maxlen );
    500                         SAFE_FREE(saved_ext);
    501                 }
    502                 return( False );
    503         }
    504 
    505         /* If we *did* find it, we need to copy it into the string buffer. */
    506         (void)safe_strcpy( s, data_val.dptr, maxlen );
    507         if( saved_ext ) {
    508                 /* Replace the saved_ext as it was truncated. */
    509                 (void)safe_strcat( s, saved_ext, maxlen );
    510                 SAFE_FREE(saved_ext);
    511         }
     504                TALLOC_FREE(saved_ext);
     505                TALLOC_FREE(s);
     506                return False;
     507        }
     508
     509        /* If we *did* find it, we need to talloc it on the given ctx. */
     510        if (saved_ext) {
     511                *out = talloc_asprintf(ctx, "%s%s",
     512                                        (char *)data_val.dptr,
     513                                        saved_ext);
     514        } else {
     515                *out = talloc_strdup(ctx, (char *)data_val.dptr);
     516        }
     517
     518        TALLOC_FREE(s);
     519        TALLOC_FREE(saved_ext);
    512520        SAFE_FREE(data_val.dptr);
    513         return( True );
     521
     522        return *out ? True : False;
    514523}
    515524
    516525/*****************************************************************************
    517  * do the actual mangling to 8.3 format
    518  * the buffer must be able to hold 13 characters (including the null)
    519  *****************************************************************************
    520  */
    521 static void to_8_3(char *s, int default_case)
     526 Do the actual mangling to 8.3 format.
     527*****************************************************************************/
     528
     529static BOOL to_8_3(const char *in, char out[13], int default_case)
    522530{
    523531        int csum;
     
    527535        int baselen = 0;
    528536        int extlen = 0;
     537        char *s = SMB_STRDUP(in);
    529538
    530539        extension[0] = 0;
    531540        base[0] = 0;
    532541
    533         p = strrchr(s,'.'); 
     542        if (!s) {
     543                return False;
     544        }
     545
     546        p = strrchr(s,'.');
    534547        if( p && (strlen(p+1) < (size_t)4) ) {
    535548                BOOL all_normal = ( strisnormal(p+1, default_case) ); /* XXXXXXXXX */
     
    560573                }
    561574        }
    562  
     575
    563576        p = s;
    564577
     
    570583        }
    571584        base[baselen] = 0;
    572  
     585
    573586        csum = csum % (MANGLE_BASE*MANGLE_BASE);
    574  
    575         (void)slprintf(s, 12, "%s%c%c%c",
    576                 base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
    577  
     587
     588        memcpy(out, base, baselen);
     589        out[baselen] = magic_char;
     590        out[baselen+1] = mangle( csum/MANGLE_BASE );
     591        out[baselen+2] = mangle( csum );
     592
    578593        if( *extension ) {
    579                 (void)pstrcat( s, "." );
    580                 (void)pstrcat( s, extension );
    581         }
     594                out[baselen+3] = '.';
     595                safe_strcpy(&out[baselen+4], extension, 3);
     596        }
     597
     598        SAFE_FREE(s);
     599        return True;
     600}
     601
     602static BOOL must_mangle(const char *name,
     603                        const struct share_params *p)
     604{
     605        smb_ucs2_t *name_ucs2 = NULL;
     606        NTSTATUS status;
     607        magic_char = lp_magicchar(p);
     608
     609        if (push_ucs2_allocate(&name_ucs2, name) == (size_t)-1) {
     610                DEBUG(0, ("push_ucs2_allocate failed!\n"));
     611                return False;
     612        }
     613        status = is_valid_name(name_ucs2, False, False);
     614        SAFE_FREE(name_ucs2);
     615        return NT_STATUS_IS_OK(status);
    582616}
    583617
    584618/*****************************************************************************
    585619 * Convert a filename to DOS format.  Return True if successful.
    586  *
    587  *  Input:  OutName - Source *and* destination buffer.
    588  *
    589  *                    NOTE that OutName must point to a memory space that
    590  *                    is at least 13 bytes in size!
    591  *
    592  *          need83  - If False, name mangling will be skipped unless the
    593  *                    name contains illegal characters.  Mapping will still
    594  *                    be done, if appropriate.  This is probably used to
    595  *                    signal that a client does not require name mangling,
    596  *                    thus skipping the name mangling even on shares which
    597  *                    have name-mangling turned on.
     620 *  Input:  in        Incoming name.
     621 *
     622 *          out       8.3 DOS name.
     623 *
    598624 *          cache83 - If False, the mangled name cache will not be updated.
    599625 *                    This is usually used to prevent that we overwrite
     
    602628 *                    current name.  (See PR#13758).  UKD.
    603629 *
    604  *  Output: Returns False only if the name wanted mangling but the share does
    605  *          not have name mangling turned on.
    606  *
    607630 * ****************************************************************************
    608631 */
    609632
    610 static void name_map(char *OutName, BOOL need83, BOOL cache83,
    611                      int default_case, const struct share_params *p)
    612 {
    613         smb_ucs2_t *OutName_ucs2;
     633static BOOL hash_name_to_8_3(const char *in,
     634                        char out[13],
     635                        BOOL cache83,
     636                        int default_case,
     637                        const struct share_params *p)
     638{
     639        smb_ucs2_t *in_ucs2 = NULL;
    614640        magic_char = lp_magicchar(p);
    615641
    616         DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName,
    617                  need83 ? "True" : "False", cache83 ? "True" : "False"));
    618        
    619         if (push_ucs2_allocate(&OutName_ucs2, OutName) == (size_t)-1) {
     642        DEBUG(5,("hash_name_to_8_3( %s, cache83 = %s)\n", in,
     643                 cache83 ? "True" : "False"));
     644
     645        if (push_ucs2_allocate(&in_ucs2, in) == (size_t)-1) {
    620646                DEBUG(0, ("push_ucs2_allocate failed!\n"));
    621                 return;
    622         }
    623 
    624         if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False)))
    625                 need83 = True;
    626 
    627         /* check if it's already in 8.3 format */
    628         if (need83 && !NT_STATUS_IS_OK(is_8_3_w(OutName_ucs2, False))) {
    629                 char *tmp = NULL;
    630 
    631                 /* mangle it into 8.3 */
    632                 if (cache83)
    633                         tmp = SMB_STRDUP(OutName);
    634 
    635                 to_8_3(OutName, default_case);
    636 
    637                 if(tmp != NULL) {
    638                         cache_mangled_name(OutName, tmp);
    639                         SAFE_FREE(tmp);
    640                 }
    641         }
    642 
    643         DEBUG(5,("name_map() ==> [%s]\n", OutName));
    644         SAFE_FREE(OutName_ucs2);
     647                return False;
     648        }
     649
     650        /* If it's already 8.3, just copy. */
     651        if (NT_STATUS_IS_OK(is_valid_name(in_ucs2, False, False)) &&
     652                                NT_STATUS_IS_OK(is_8_3_w(in_ucs2, False))) {
     653                SAFE_FREE(in_ucs2);
     654                safe_strcpy(out, in, 12);
     655                return True;
     656        }
     657
     658        SAFE_FREE(in_ucs2);
     659        if (!to_8_3(in, out, default_case)) {
     660                return False;
     661        }
     662
     663        cache_mangled_name(out, in);
     664
     665        DEBUG(5,("hash_name_to_8_3(%s) ==> [%s]\n", in, out));
     666        return True;
    645667}
    646668
     
    652674        mangle_reset,
    653675        is_mangled,
     676        must_mangle,
    654677        is_8_3,
    655         check_cache,
    656         name_map
     678        lookup_name_from_8_3,
     679        hash_name_to_8_3
    657680};
    658681
Note: See TracChangeset for help on using the changeset viewer.