mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
Merge in mangle fixes from 2.2.
Jeremy.
(This used to be commit 5e2571f424
)
This commit is contained in:
parent
bad738e653
commit
5d452f0d00
@ -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_ */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
void *cur_dir;
|
||||
char *dname;
|
||||
BOOL mangled;
|
||||
|
||||
mangled = mangle_is_mangled(name);
|
||||
mangled = mangle_is_mangled(name);
|
||||
|
||||
/* handle null paths */
|
||||
if (*path == 0)
|
||||
path = ".";
|
||||
/* handle null paths */
|
||||
if (*path == 0)
|
||||
path = ".";
|
||||
|
||||
if (docache && (dname = DirCacheCheck(path,name,SNUM(conn)))) {
|
||||
pstrcpy(name, dname);
|
||||
return(True);
|
||||
}
|
||||
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 );
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
/* 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;
|
||||
/* 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;
|
||||
/*
|
||||
* At this point dname is the unmangled name.
|
||||
* name is either mangled or not, depending on the state of the "mangled"
|
||||
* variable. JRA.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check mangled name against mangled name, or unmangled name
|
||||
* against unmangled name.
|
||||
*/
|
||||
|
||||
CloseDir(cur_dir);
|
||||
return(False);
|
||||
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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
{
|
||||
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 */
|
||||
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;
|
||||
{
|
||||
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;
|
||||
/* 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 );
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
/* 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 */
|
||||
/* 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;
|
||||
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 );
|
||||
/* If the cache isn't initialized, give up. */
|
||||
if( !mc_initialized )
|
||||
return( False );
|
||||
|
||||
FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
|
||||
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;
|
||||
/* 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.
|
||||
*/
|
||||
}
|
||||
}
|
||||
*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 );
|
||||
}
|
||||
/* 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);
|
||||
/* 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 */
|
||||
(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;
|
||||
{
|
||||
int csum;
|
||||
char *p;
|
||||
char extension[4];
|
||||
char base[9];
|
||||
int baselen = 0;
|
||||
int extlen = 0;
|
||||
|
||||
extension[0] = 0;
|
||||
base[0] = 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 */
|
||||
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);
|
||||
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 );
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
p = s;
|
||||
|
||||
while( *p && baselen < 5 )
|
||||
{
|
||||
if (*p != '.') {
|
||||
base[baselen++] = p[0];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
base[baselen] = 0;
|
||||
while( *p && baselen < 5 ) {
|
||||
if (*p != '.') {
|
||||
base[baselen++] = p[0];
|
||||
}
|
||||
p++;
|
||||
}
|
||||
base[baselen] = 0;
|
||||
|
||||
csum = csum % (MANGLE_BASE*MANGLE_BASE);
|
||||
csum = csum % (MANGLE_BASE*MANGLE_BASE);
|
||||
|
||||
(void)slprintf(s, 12, "%s%c%c%c",
|
||||
base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
|
||||
(void)slprintf(s, 12, "%s%c%c%c",
|
||||
base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
|
||||
|
||||
if( *extension )
|
||||
{
|
||||
(void)pstrcat( s, "." );
|
||||
(void)pstrcat( s, extension );
|
||||
}
|
||||
|
||||
} /* 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user