mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
r18547: Add in fixes to mangling dir code - ensure don't
look in the paths for wcard - always read directly
from incoming packet.
Jeremy.
(This used to be commit 3745a1af4e
)
This commit is contained in:
parent
8e7799889f
commit
315ad641c3
@ -61,6 +61,7 @@ struct dptr_struct {
|
||||
uint32 attr;
|
||||
char *path;
|
||||
BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */
|
||||
BOOL did_stat; /* Optimisation for non-wcard searches. */
|
||||
};
|
||||
|
||||
static struct bitmap *dptr_bmap;
|
||||
@ -535,6 +536,11 @@ long dptr_TellDir(struct dptr_struct *dptr)
|
||||
return TellDir(dptr->dir_hnd);
|
||||
}
|
||||
|
||||
BOOL dptr_has_wild(struct dptr_struct *dptr)
|
||||
{
|
||||
return dptr->has_wild;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Return the next visible file name, skipping veto'd and invisible files.
|
||||
****************************************************************************/
|
||||
@ -557,8 +563,6 @@ static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffs
|
||||
|
||||
const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
pstring pathreal;
|
||||
|
||||
SET_STAT_INVALID(*pst);
|
||||
|
||||
if (dptr->has_wild) {
|
||||
@ -571,55 +575,62 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We know the stored wcard contains no wildcard characters. See if we can match
|
||||
with a stat call. If we can't, then set has_wild to true to
|
||||
prevent us from doing this on every call. */
|
||||
if (!dptr->did_stat) {
|
||||
pstring pathreal;
|
||||
|
||||
/* First check if it should be visible. */
|
||||
if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
|
||||
dptr->has_wild = True;
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
}
|
||||
/* We know the stored wcard contains no wildcard characters. See if we can match
|
||||
with a stat call. If we can't, then set did_stat to true to
|
||||
ensure we only do this once and keep searching. */
|
||||
|
||||
if (VALID_STAT(*pst)) {
|
||||
/* We need to set the underlying dir_hdn offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return dptr->wcard;
|
||||
}
|
||||
dptr->did_stat = True;
|
||||
|
||||
pstrcpy(pathreal,dptr->path);
|
||||
pstrcat(pathreal,"/");
|
||||
pstrcat(pathreal,dptr->wcard);
|
||||
/* First check if it should be visible. */
|
||||
if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
|
||||
/* This only returns False if the file was found, but
|
||||
is explicitly not visible. Set us to end of directory,
|
||||
but return NULL as we know we can't ever find it. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
|
||||
/* We need to set the underlying dir_hdn offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return dptr->wcard;
|
||||
} else {
|
||||
/* If we get any other error than ENOENT or ENOTDIR
|
||||
then the file exists we just can't stat it. */
|
||||
if (errno != ENOENT && errno != ENOTDIR) {
|
||||
/* We need to set the underlying dir_hdn offset to -1 also as
|
||||
if (VALID_STAT(*pst)) {
|
||||
/* We need to set the underlying dir_hnd offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return dptr->wcard;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case sensitive mode we don't search - we know if it doesn't exist
|
||||
with a stat we will fail. */
|
||||
pstrcpy(pathreal,dptr->path);
|
||||
pstrcat(pathreal,"/");
|
||||
pstrcat(pathreal,dptr->wcard);
|
||||
|
||||
if (dptr->conn->case_sensitive) {
|
||||
/* We need to set the underlying dir_hdn offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return NULL;
|
||||
} else {
|
||||
dptr->has_wild = True;
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
|
||||
/* We need to set the underlying dir_hnd offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return dptr->wcard;
|
||||
} else {
|
||||
/* If we get any other error than ENOENT or ENOTDIR
|
||||
then the file exists we just can't stat it. */
|
||||
if (errno != ENOENT && errno != ENOTDIR) {
|
||||
/* We need to set the underlying dir_hdn offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return dptr->wcard;
|
||||
}
|
||||
}
|
||||
|
||||
/* In case sensitive mode we don't search - we know if it doesn't exist
|
||||
with a stat we will fail. */
|
||||
|
||||
if (dptr->conn->case_sensitive) {
|
||||
/* We need to set the underlying dir_hnd offset to -1 also as
|
||||
this function is usually called with the output from TellDir. */
|
||||
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -957,16 +957,16 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
Case can be significant or not.
|
||||
**********************************************************/
|
||||
|
||||
static BOOL exact_match(char *str,char *mask, BOOL case_sig)
|
||||
static BOOL exact_match(connection_struct *conn, char *str, char *mask)
|
||||
{
|
||||
if (mask[0] == '.' && mask[1] == 0)
|
||||
return False;
|
||||
if (case_sig)
|
||||
if (conn->case_sensitive)
|
||||
return strcmp(str,mask)==0;
|
||||
if (StrCaseCmp(str,mask) != 0) {
|
||||
return False;
|
||||
}
|
||||
if (ms_has_wild(str)) {
|
||||
if (dptr_has_wild(conn->dirptr)) {
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
@ -1132,7 +1132,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
||||
|
||||
pstrcpy(fname,dname);
|
||||
|
||||
if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
|
||||
if(!(got_match = *got_exact_match = exact_match(conn, fname, mask)))
|
||||
got_match = mask_match(fname, mask, conn->case_sensitive);
|
||||
|
||||
if(!got_match && check_mangled_names &&
|
||||
@ -1148,7 +1148,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
||||
pstring newname;
|
||||
pstrcpy( newname, fname);
|
||||
mangle_map( newname, True, False, conn->params);
|
||||
if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
|
||||
if(!(got_match = *got_exact_match = exact_match(conn, newname, mask)))
|
||||
got_match = mask_match(newname, mask, conn->case_sensitive);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user