mirror of
https://github.com/samba-team/samba.git
synced 2025-12-20 16:23:51 +03:00
Ok - this is a big patch - and it may break smbd a bit (although
I hope not). If you encounter strange file-serving behavior after this patch then back it out. I analysed our stat() usage and realised we were doing approx. 3 stat calls per open, and 2 per getattr/setattr. This patch should fix all that. It causes the stat struct returned from unix_convert() (which now *must* be passed a valid SMB_STRUCT_STAT pointer) to be passed through into the open code. This should prevent the multiple stats that were being done so as not to violate layer encapsulation in the API's. Herb - if you could run a NetBench test with this code and do a padc/par syscall test and also run with the current 2.2.0 code and test the padc/par syscalls I'd appreciate it - you should find the number of stat calls reduced - not sure by how much. The patch depends on unix_convert() actually finding the file and returning a stat struct, or returning a zero'd out stat struct if the file didn't exist. I believe we can guarentee this to be the case - I just wasn't confident enough to make this an assertion before. Ok ok - I did write this whilst at the Miami conference..... sometimes you get a little free time at these things :-). Jeremy.
This commit is contained in:
@@ -3608,12 +3608,12 @@ int reply_nttrans(connection_struct *conn,
|
|||||||
|
|
||||||
#if OLD_NTDOMAIN
|
#if OLD_NTDOMAIN
|
||||||
int fd_close(struct connection_struct *conn, files_struct *fsp);
|
int fd_close(struct connection_struct *conn, files_struct *fsp);
|
||||||
files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mode,int ofun,
|
files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
|
||||||
mode_t mode,int oplock_request, int *Access,int *action);
|
int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action);
|
||||||
files_struct *open_file_stat(connection_struct *conn,
|
files_struct *open_file_stat(connection_struct *conn, char *fname,
|
||||||
char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action);
|
SMB_STRUCT_STAT *psbuf, int smb_ofun, int *action);
|
||||||
files_struct *open_directory(connection_struct *conn,
|
files_struct *open_directory(connection_struct *conn, char *fname,
|
||||||
char *fname, int smb_ofun, mode_t unixmode, int *action);
|
SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action);
|
||||||
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
|
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -104,8 +104,8 @@
|
|||||||
* stat structure is valid.
|
* stat structure is valid.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VALID_STAT(st) (st.st_nlink != 0)
|
#define VALID_STAT(st) ((st).st_nlink != 0)
|
||||||
#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR(st.st_mode))
|
#define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode))
|
||||||
|
|
||||||
#define SMBENCRYPT() (lp_encrypted_passwords())
|
#define SMBENCRYPT() (lp_encrypted_passwords())
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,11 @@ The bad_path arg is set to True if the filename walk failed. This is
|
|||||||
used to pick the correct error code to return between ENOENT and ENOTDIR
|
used to pick the correct error code to return between ENOENT and ENOTDIR
|
||||||
as Windows applications depend on ERRbadpath being returned if a component
|
as Windows applications depend on ERRbadpath being returned if a component
|
||||||
of a pathname does not exist.
|
of a pathname does not exist.
|
||||||
|
|
||||||
|
On exit from unix_convert, if *pst was not null, then the file stat
|
||||||
|
struct will be returned if the file exists and was found, if not this
|
||||||
|
stat struct will be filled with zeros (and this can be detected by checking
|
||||||
|
for nlinks = 0, which can never be true for any file).
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
||||||
@@ -127,6 +132,13 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
extern char magic_char;
|
extern char magic_char;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ZERO_STRUCTP(pst);
|
||||||
|
|
||||||
|
*dirpath = 0;
|
||||||
|
*bad_path = False;
|
||||||
|
if(saved_last_component)
|
||||||
|
*saved_last_component = 0;
|
||||||
|
|
||||||
if (conn->printer) {
|
if (conn->printer) {
|
||||||
/* we don't ever use the filenames on a printer share as a
|
/* we don't ever use the filenames on a printer share as a
|
||||||
filename - so don't convert them */
|
filename - so don't convert them */
|
||||||
@@ -135,15 +147,6 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
|
|
||||||
DEBUG(5, ("unix_convert called on file \"%s\"\n", name));
|
DEBUG(5, ("unix_convert called on file \"%s\"\n", name));
|
||||||
|
|
||||||
*dirpath = 0;
|
|
||||||
*bad_path = False;
|
|
||||||
if(pst) {
|
|
||||||
ZERO_STRUCTP(pst);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(saved_last_component)
|
|
||||||
*saved_last_component = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert to basic unix format - removing \ chars and cleaning it up.
|
* Convert to basic unix format - removing \ chars and cleaning it up.
|
||||||
*/
|
*/
|
||||||
@@ -165,7 +168,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
* printing share.
|
* printing share.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!*name && (!conn -> printer)) {
|
if (!*name) {
|
||||||
name[0] = '.';
|
name[0] = '.';
|
||||||
name[1] = '\0';
|
name[1] = '\0';
|
||||||
}
|
}
|
||||||
@@ -202,7 +205,6 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
pstrcpy(orig_path, name);
|
pstrcpy(orig_path, name);
|
||||||
|
|
||||||
if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
|
if(stat_cache_lookup(conn, name, dirpath, &start, &st)) {
|
||||||
if(pst)
|
|
||||||
*pst = st;
|
*pst = st;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
@@ -211,10 +213,9 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
* stat the name - if it exists then we are all done!
|
* stat the name - if it exists then we are all done!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (conn->vfs_ops.stat(conn,dos_to_unix(name,False),&st) == 0) {
|
if (vfs_stat(conn,name,&st) == 0) {
|
||||||
stat_cache_add(orig_path, name);
|
stat_cache_add(orig_path, name);
|
||||||
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
|
DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
|
||||||
if(pst)
|
|
||||||
*pst = st;
|
*pst = st;
|
||||||
return(True);
|
return(True);
|
||||||
}
|
}
|
||||||
@@ -277,7 +278,8 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
* Check if the name exists up to this point.
|
* Check if the name exists up to this point.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (conn->vfs_ops.stat(conn,dos_to_unix(name,False), &st) == 0) {
|
ZERO_STRUCT(st);
|
||||||
|
if (vfs_stat(conn,name, &st) == 0) {
|
||||||
/*
|
/*
|
||||||
* It exists. it must either be a directory or this must be
|
* It exists. it must either be a directory or this must be
|
||||||
* the last part of the path for it to be OK.
|
* the last part of the path for it to be OK.
|
||||||
@@ -308,8 +310,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
* Try to find this part of the path in the directory.
|
* Try to find this part of the path in the directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ms_has_wild(start) ||
|
if (ms_has_wild(start) || !scan_directory(dirpath, start, conn, end?True:False)) {
|
||||||
!scan_directory(dirpath, start, conn, end?True:False)) {
|
|
||||||
if (end) {
|
if (end) {
|
||||||
/*
|
/*
|
||||||
* An intermediate part of the name can't be found.
|
* An intermediate part of the name can't be found.
|
||||||
@@ -392,6 +393,14 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
|
|||||||
if(!component_was_mangled && !name_has_wildcard)
|
if(!component_was_mangled && !name_has_wildcard)
|
||||||
stat_cache_add(orig_path, name);
|
stat_cache_add(orig_path, name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we ended up resolving the entire path then return a valid
|
||||||
|
* stat struct if we got one.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (VALID_STAT(st) && (strlen(orig_path) == strlen(name)))
|
||||||
|
*pst = st;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The name has been resolved.
|
* The name has been resolved.
|
||||||
*/
|
*/
|
||||||
@@ -426,12 +435,10 @@ BOOL check_name(char *name,connection_struct *conn)
|
|||||||
University of Geneva */
|
University of Geneva */
|
||||||
|
|
||||||
#ifdef S_ISLNK
|
#ifdef S_ISLNK
|
||||||
if (!lp_symlinks(SNUM(conn)))
|
if (!lp_symlinks(SNUM(conn))) {
|
||||||
{
|
|
||||||
SMB_STRUCT_STAT statbuf;
|
SMB_STRUCT_STAT statbuf;
|
||||||
if ( (conn->vfs_ops.lstat(conn,dos_to_unix(name,False),&statbuf) != -1) &&
|
if ( (conn->vfs_ops.lstat(conn,dos_to_unix(name,False),&statbuf) != -1) &&
|
||||||
(S_ISLNK(statbuf.st_mode)) )
|
(S_ISLNK(statbuf.st_mode)) ) {
|
||||||
{
|
|
||||||
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
|
DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
|
||||||
ret=0;
|
ret=0;
|
||||||
}
|
}
|
||||||
@@ -479,28 +486,24 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
|
|||||||
mangled = !check_mangled_cache( name );
|
mangled = !check_mangled_cache( name );
|
||||||
|
|
||||||
/* open the directory */
|
/* open the directory */
|
||||||
if (!(cur_dir = OpenDir(conn, path, True)))
|
if (!(cur_dir = OpenDir(conn, path, True))) {
|
||||||
{
|
|
||||||
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
|
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
|
||||||
return(False);
|
return(False);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now scan for matching names */
|
/* now scan for matching names */
|
||||||
while ((dname = ReadDirName(cur_dir)))
|
while ((dname = ReadDirName(cur_dir))) {
|
||||||
{
|
if (*dname == '.' && (strequal(dname,".") || strequal(dname,"..")))
|
||||||
if (*dname == '.' &&
|
|
||||||
(strequal(dname,".") || strequal(dname,"..")))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pstrcpy(name2,dname);
|
pstrcpy(name2,dname);
|
||||||
if (!name_map_mangle(name2,False,True,SNUM(conn)))
|
if (!name_map_mangle(name2,False,True,SNUM(conn)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((mangled && mangled_equal(name,name2))
|
if ((mangled && mangled_equal(name,name2)) || fname_equal(name, name2)) {
|
||||||
|| fname_equal(name, name2))
|
|
||||||
{
|
|
||||||
/* we've found the file, change it's name and return */
|
/* we've found the file, change it's name and return */
|
||||||
if (docache) DirCacheAdd(path,name,dname,SNUM(conn));
|
if (docache)
|
||||||
|
DirCacheAdd(path,name,dname,SNUM(conn));
|
||||||
pstrcpy(name, dname);
|
pstrcpy(name, dname);
|
||||||
CloseDir(cur_dir);
|
CloseDir(cur_dir);
|
||||||
return(True);
|
return(True);
|
||||||
|
|||||||
@@ -795,7 +795,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
|
|
||||||
set_posix_case_semantics(file_attributes);
|
set_posix_case_semantics(file_attributes);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||||
|
|
||||||
@@ -806,7 +806,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
if(create_options & FILE_DIRECTORY_FILE) {
|
if(create_options & FILE_DIRECTORY_FILE) {
|
||||||
oplock_request = 0;
|
oplock_request = 0;
|
||||||
|
|
||||||
fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
|
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||||
|
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
|
|
||||||
@@ -836,7 +836,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
* before issuing an oplock break request to
|
* before issuing an oplock break request to
|
||||||
* our client. JRA. */
|
* our client. JRA. */
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,smb_open_mode,
|
fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,
|
||||||
smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
|
smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
@@ -873,7 +873,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
oplock_request = 0;
|
oplock_request = 0;
|
||||||
fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
|
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||||
|
|
||||||
if(!fsp) {
|
if(!fsp) {
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
@@ -896,7 +896,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
|
|
||||||
oplock_request = 0;
|
oplock_request = 0;
|
||||||
|
|
||||||
fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
|
fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
|
||||||
|
|
||||||
if(!fsp) {
|
if(!fsp) {
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
@@ -919,22 +919,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fsp->is_directory) {
|
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
|
|
||||||
close_file(fsp,True);
|
|
||||||
restore_case_semantics(file_attributes);
|
|
||||||
END_PROFILE(SMBntcreateX);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
|
|
||||||
close_file(fsp,False);
|
|
||||||
restore_case_semantics(file_attributes);
|
|
||||||
END_PROFILE(SMBntcreateX);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
|
|
||||||
file_len = sbuf.st_size;
|
file_len = sbuf.st_size;
|
||||||
@@ -1231,7 +1215,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
|
|
||||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||||
|
|
||||||
@@ -1249,7 +1233,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
* CreateDirectory() call.
|
* CreateDirectory() call.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
|
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||||
|
|
||||||
if(!fsp) {
|
if(!fsp) {
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
@@ -1260,20 +1244,13 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name, False),
|
|
||||||
&sbuf) != 0) {
|
|
||||||
close_file(fsp,True);
|
|
||||||
restore_case_semantics(file_attributes);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ordinary file case.
|
* Ordinary file case.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,smb_open_mode,smb_ofun,unixmode,
|
fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,smb_ofun,unixmode,
|
||||||
oplock_request,&rmode,&smb_action);
|
oplock_request,&rmode,&smb_action);
|
||||||
|
|
||||||
if (!fsp) {
|
if (!fsp) {
|
||||||
@@ -1291,7 +1268,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
oplock_request = 0;
|
oplock_request = 0;
|
||||||
fsp = open_directory(conn, fname, smb_ofun, unixmode, &smb_action);
|
fsp = open_directory(conn, fname, &sbuf, smb_ofun, unixmode, &smb_action);
|
||||||
|
|
||||||
if(!fsp) {
|
if(!fsp) {
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
@@ -1314,7 +1291,7 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
|
|
||||||
oplock_request = 0;
|
oplock_request = 0;
|
||||||
|
|
||||||
fsp = open_file_stat(conn,fname,smb_open_mode,&sbuf,&smb_action);
|
fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
|
||||||
|
|
||||||
if(!fsp) {
|
if(!fsp) {
|
||||||
restore_case_semantics(file_attributes);
|
restore_case_semantics(file_attributes);
|
||||||
@@ -1333,20 +1310,6 @@ static int call_nt_transact_create(connection_struct *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fsp->is_directory) {
|
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
|
|
||||||
close_file(fsp,True);
|
|
||||||
restore_case_semantics(file_attributes);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!fsp->stat_open && conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
|
|
||||||
close_file(fsp,False);
|
|
||||||
restore_case_semantics(file_attributes);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file_len = sbuf.st_size;
|
file_len = sbuf.st_size;
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fmode = dos_mode(conn,fname,&sbuf);
|
||||||
if(fmode == 0)
|
if(fmode == 0)
|
||||||
|
|||||||
@@ -88,12 +88,11 @@ static void check_for_pipe(char *fname)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL open_file(files_struct *fsp,connection_struct *conn,
|
static BOOL open_file(files_struct *fsp,connection_struct *conn,
|
||||||
char *fname1,int flags,mode_t mode)
|
char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode)
|
||||||
{
|
{
|
||||||
extern struct current_user current_user;
|
extern struct current_user current_user;
|
||||||
pstring fname;
|
pstring fname;
|
||||||
int accmode = (flags & O_ACCMODE);
|
int accmode = (flags & O_ACCMODE);
|
||||||
SMB_STRUCT_STAT sbuf;
|
|
||||||
|
|
||||||
fsp->fd = -1;
|
fsp->fd = -1;
|
||||||
fsp->oplock_type = NO_OPLOCK;
|
fsp->oplock_type = NO_OPLOCK;
|
||||||
@@ -138,11 +137,13 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf) == -1) {
|
if (!VALID_STAT(*psbuf)) {
|
||||||
|
if (vfs_fstat(fsp,fsp->fd,psbuf) == -1) {
|
||||||
DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
|
DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
|
||||||
fd_close(conn, fsp);
|
fd_close(conn, fsp);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* POSIX allows read-only opens of directories. We don't
|
* POSIX allows read-only opens of directories. We don't
|
||||||
@@ -150,18 +151,18 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
|
|||||||
* so catch a directory open and return an EISDIR. JRA.
|
* so catch a directory open and return an EISDIR. JRA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(S_ISDIR(sbuf.st_mode)) {
|
if(S_ISDIR(psbuf->st_mode)) {
|
||||||
fd_close(conn, fsp);
|
fd_close(conn, fsp);
|
||||||
errno = EISDIR;
|
errno = EISDIR;
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
fsp->mode = sbuf.st_mode;
|
fsp->mode = psbuf->st_mode;
|
||||||
fsp->inode = sbuf.st_ino;
|
fsp->inode = psbuf->st_ino;
|
||||||
fsp->dev = sbuf.st_dev;
|
fsp->dev = psbuf->st_dev;
|
||||||
GetTimeOfDay(&fsp->open_time);
|
GetTimeOfDay(&fsp->open_time);
|
||||||
fsp->vuid = current_user.vuid;
|
fsp->vuid = current_user.vuid;
|
||||||
fsp->size = 0;
|
fsp->size = psbuf->st_size;
|
||||||
fsp->pos = -1;
|
fsp->pos = -1;
|
||||||
fsp->can_lock = True;
|
fsp->can_lock = True;
|
||||||
fsp->can_read = ((flags & O_WRONLY)==0);
|
fsp->can_read = ((flags & O_WRONLY)==0);
|
||||||
@@ -513,17 +514,17 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
|
|||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Open a file with a share mode.
|
Open a file with a share mode. On output from this open we are guarenteeing
|
||||||
|
that
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mode,int ofun,
|
files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
|
||||||
mode_t mode,int oplock_request, int *Access,int *action)
|
int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action)
|
||||||
{
|
{
|
||||||
int flags=0;
|
int flags=0;
|
||||||
int flags2=0;
|
int flags2=0;
|
||||||
int deny_mode = GET_DENY_MODE(share_mode);
|
int deny_mode = GET_DENY_MODE(share_mode);
|
||||||
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
|
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
|
||||||
SMB_STRUCT_STAT sbuf;
|
BOOL file_existed = VALID_STAT(*psbuf);
|
||||||
BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
|
|
||||||
BOOL fcbopen = False;
|
BOOL fcbopen = False;
|
||||||
SMB_DEV_T dev = 0;
|
SMB_DEV_T dev = 0;
|
||||||
SMB_INO_T inode = 0;
|
SMB_INO_T inode = 0;
|
||||||
@@ -619,7 +620,7 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
|
|||||||
#endif /* O_SYNC */
|
#endif /* O_SYNC */
|
||||||
|
|
||||||
if (flags != O_RDONLY && file_existed &&
|
if (flags != O_RDONLY && file_existed &&
|
||||||
(!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,&sbuf)))) {
|
(!CAN_WRITE(conn) || IS_DOS_READONLY(dos_mode(conn,fname,psbuf)))) {
|
||||||
if (!fcbopen) {
|
if (!fcbopen) {
|
||||||
DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
|
DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n",
|
||||||
fname, !CAN_WRITE(conn) ? "share" : "file" ));
|
fname, !CAN_WRITE(conn) ? "share" : "file" ));
|
||||||
@@ -638,8 +639,9 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (file_existed) {
|
if (file_existed) {
|
||||||
dev = sbuf.st_dev;
|
|
||||||
inode = sbuf.st_ino;
|
dev = psbuf->st_dev;
|
||||||
|
inode = psbuf->st_ino;
|
||||||
|
|
||||||
lock_share_entry(conn, dev, inode);
|
lock_share_entry(conn, dev, inode);
|
||||||
|
|
||||||
@@ -659,10 +661,10 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
|
|||||||
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
|
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
|
||||||
flags,flags2,(int)mode));
|
flags,flags2,(int)mode));
|
||||||
|
|
||||||
fsp_open = open_file(fsp,conn,fname,flags|(flags2&~(O_TRUNC)),mode);
|
fsp_open = open_file(fsp,conn,fname,psbuf,flags|(flags2&~(O_TRUNC)),mode);
|
||||||
|
|
||||||
if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
|
if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
|
||||||
if((fsp_open = open_file(fsp,conn,fname,O_RDONLY,mode)) == True)
|
if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode)) == True)
|
||||||
flags = O_RDONLY;
|
flags = O_RDONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,12 +719,17 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
|
|||||||
* If requested, truncate the file.
|
* If requested, truncate the file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((flags2&O_TRUNC) && (truncate_unless_locked(conn,fsp) == -1)) {
|
if (flags2&O_TRUNC) {
|
||||||
|
/*
|
||||||
|
* We are modifing the file after open - update the stat struct..
|
||||||
|
*/
|
||||||
|
if ((truncate_unless_locked(conn,fsp) == -1) || (vfs_fstat(fsp,fsp->fd,psbuf)==-1)) {
|
||||||
unlock_share_entry_fsp(fsp);
|
unlock_share_entry_fsp(fsp);
|
||||||
fd_close(conn,fsp);
|
fd_close(conn,fsp);
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
case O_RDONLY:
|
case O_RDONLY:
|
||||||
@@ -783,28 +790,26 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod
|
|||||||
with the 'stat_open' flag set
|
with the 'stat_open' flag set
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
files_struct *open_file_stat(connection_struct *conn,
|
files_struct *open_file_stat(connection_struct *conn, char *fname,
|
||||||
char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
|
SMB_STRUCT_STAT *psbuf, int smb_ofun, int *action)
|
||||||
{
|
{
|
||||||
extern struct current_user current_user;
|
extern struct current_user current_user;
|
||||||
files_struct *fsp = file_new();
|
files_struct *fsp = NULL;
|
||||||
|
|
||||||
|
if (!VALID_STAT(*psbuf)) {
|
||||||
|
DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n", fname, strerror(errno) ));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(S_ISDIR(psbuf->st_mode)) {
|
||||||
|
DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsp = file_new();
|
||||||
if(!fsp)
|
if(!fsp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), pst) < 0) {
|
|
||||||
DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
|
|
||||||
fname, strerror(errno) ));
|
|
||||||
file_free(fsp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(S_ISDIR(pst->st_mode)) {
|
|
||||||
DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
|
|
||||||
file_free(fsp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*action = FILE_WAS_OPENED;
|
*action = FILE_WAS_OPENED;
|
||||||
|
|
||||||
DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
|
DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
|
||||||
@@ -814,10 +819,12 @@ files_struct *open_file_stat(connection_struct *conn,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
fsp->fd = -1;
|
fsp->fd = -1;
|
||||||
fsp->mode = 0;
|
fsp->mode = psbuf->st_mode;
|
||||||
|
fsp->inode = psbuf->st_ino;
|
||||||
|
fsp->dev = psbuf->st_dev;
|
||||||
GetTimeOfDay(&fsp->open_time);
|
GetTimeOfDay(&fsp->open_time);
|
||||||
|
fsp->size = psbuf->st_size;
|
||||||
fsp->vuid = current_user.vuid;
|
fsp->vuid = current_user.vuid;
|
||||||
fsp->size = 0;
|
|
||||||
fsp->pos = -1;
|
fsp->pos = -1;
|
||||||
fsp->can_lock = False;
|
fsp->can_lock = False;
|
||||||
fsp->can_read = False;
|
fsp->can_read = False;
|
||||||
@@ -851,20 +858,18 @@ files_struct *open_file_stat(connection_struct *conn,
|
|||||||
Open a directory from an NT SMB call.
|
Open a directory from an NT SMB call.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
files_struct *open_directory(connection_struct *conn,
|
files_struct *open_directory(connection_struct *conn, char *fname,
|
||||||
char *fname, int smb_ofun, mode_t unixmode, int *action)
|
SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action)
|
||||||
{
|
{
|
||||||
extern struct current_user current_user;
|
extern struct current_user current_user;
|
||||||
SMB_STRUCT_STAT st;
|
|
||||||
BOOL got_stat = False;
|
BOOL got_stat = False;
|
||||||
files_struct *fsp = file_new();
|
files_struct *fsp = file_new();
|
||||||
|
|
||||||
if(!fsp)
|
if(!fsp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), &st) == 0) {
|
if (VALID_STAT(*psbuf))
|
||||||
got_stat = True;
|
got_stat = True;
|
||||||
}
|
|
||||||
|
|
||||||
if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
|
if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
@@ -876,7 +881,7 @@ files_struct *open_directory(connection_struct *conn,
|
|||||||
|
|
||||||
if (got_stat) {
|
if (got_stat) {
|
||||||
|
|
||||||
if(!S_ISDIR(st.st_mode)) {
|
if(!S_ISDIR(psbuf->st_mode)) {
|
||||||
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
|
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
@@ -903,6 +908,12 @@ files_struct *open_directory(connection_struct *conn,
|
|||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vfs_stat(conn,fname, psbuf) != 0) {
|
||||||
|
file_free(fsp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
*action = FILE_WAS_CREATED;
|
*action = FILE_WAS_CREATED;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -919,7 +930,7 @@ files_struct *open_directory(connection_struct *conn,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!S_ISDIR(st.st_mode)) {
|
if(!S_ISDIR(psbuf->st_mode)) {
|
||||||
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
|
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -928,18 +939,19 @@ files_struct *open_directory(connection_struct *conn,
|
|||||||
*action = FILE_WAS_OPENED;
|
*action = FILE_WAS_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(5,("open_directory: opening directory %s\n",
|
DEBUG(5,("open_directory: opening directory %s\n", fname));
|
||||||
fname));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the files_struct for it.
|
* Setup the files_struct for it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fsp->fd = -1;
|
fsp->fd = -1;
|
||||||
fsp->mode = 0;
|
fsp->mode = psbuf->st_mode;
|
||||||
|
fsp->inode = psbuf->st_ino;
|
||||||
|
fsp->dev = psbuf->st_dev;
|
||||||
GetTimeOfDay(&fsp->open_time);
|
GetTimeOfDay(&fsp->open_time);
|
||||||
|
fsp->size = psbuf->st_size;
|
||||||
fsp->vuid = current_user.vuid;
|
fsp->vuid = current_user.vuid;
|
||||||
fsp->size = 0;
|
|
||||||
fsp->pos = -1;
|
fsp->pos = -1;
|
||||||
fsp->can_lock = True;
|
fsp->can_lock = True;
|
||||||
fsp->can_read = False;
|
fsp->can_read = False;
|
||||||
@@ -983,7 +995,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
|
|||||||
SMB_DEV_T dev;
|
SMB_DEV_T dev;
|
||||||
SMB_INO_T inode;
|
SMB_INO_T inode;
|
||||||
|
|
||||||
if (conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf) == -1)
|
if (vfs_stat(conn,fname,&sbuf) == -1)
|
||||||
return(True);
|
return(True);
|
||||||
|
|
||||||
dev = sbuf.st_dev;
|
dev = sbuf.st_dev;
|
||||||
|
|||||||
@@ -1033,22 +1033,20 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
pstring name;
|
pstring name;
|
||||||
BOOL ok = False;
|
BOOL ok = False;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT sbuf;
|
||||||
START_PROFILE(SMBchkpth);
|
START_PROFILE(SMBchkpth);
|
||||||
|
|
||||||
pstrcpy(name,smb_buf(inbuf) + 1);
|
pstrcpy(name,smb_buf(inbuf) + 1);
|
||||||
|
|
||||||
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(name,conn,0,&bad_path,&st);
|
unix_convert(name,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
mode = SVAL(inbuf,smb_vwv0);
|
mode = SVAL(inbuf,smb_vwv0);
|
||||||
|
|
||||||
if (check_name(name,conn)) {
|
if (check_name(name,conn)) {
|
||||||
if(VALID_STAT(st))
|
if(VALID_STAT(sbuf))
|
||||||
ok = S_ISDIR(st.st_mode);
|
ok = S_ISDIR(sbuf.st_mode);
|
||||||
else
|
|
||||||
ok = vfs_directory_exist(conn,name,NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
@@ -1182,17 +1180,17 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
BOOL ok=False;
|
BOOL ok=False;
|
||||||
int mode;
|
int mode;
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT sbuf;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
START_PROFILE(SMBsetatr);
|
START_PROFILE(SMBsetatr);
|
||||||
|
|
||||||
pstrcpy(fname,smb_buf(inbuf) + 1);
|
pstrcpy(fname,smb_buf(inbuf) + 1);
|
||||||
unix_convert(fname,conn,0,&bad_path,&st);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
mode = SVAL(inbuf,smb_vwv0);
|
mode = SVAL(inbuf,smb_vwv0);
|
||||||
mtime = make_unix_date3(inbuf+smb_vwv1);
|
mtime = make_unix_date3(inbuf+smb_vwv1);
|
||||||
|
|
||||||
if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, fname, NULL))
|
if (VALID_STAT_OF_DIR(sbuf))
|
||||||
mode |= aDIR;
|
mode |= aDIR;
|
||||||
if (check_name(fname,conn))
|
if (check_name(fname,conn))
|
||||||
ok = (file_chmod(conn,fname,mode,NULL) == 0);
|
ok = (file_chmod(conn,fname,mode,NULL) == 0);
|
||||||
@@ -1292,11 +1290,12 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
|
|
||||||
if (status_len == 0)
|
if (status_len == 0)
|
||||||
{
|
{
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
pstring dir2;
|
pstring dir2;
|
||||||
|
|
||||||
pstrcpy(directory,smb_buf(inbuf)+1);
|
pstrcpy(directory,smb_buf(inbuf)+1);
|
||||||
pstrcpy(dir2,smb_buf(inbuf)+1);
|
pstrcpy(dir2,smb_buf(inbuf)+1);
|
||||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
unix_convert(directory,conn,0,&bad_path,&sbuf);
|
||||||
unix_format(dir2);
|
unix_format(dir2);
|
||||||
|
|
||||||
if (!check_name(directory,conn))
|
if (!check_name(directory,conn))
|
||||||
@@ -1517,11 +1516,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
|
|
||||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
unixmode = unix_mode(conn,aARCH,fname);
|
unixmode = unix_mode(conn,aARCH,fname);
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
fsp = open_file_shared(conn,fname,&sbuf,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
|
||||||
unixmode, oplock_request,&rmode,NULL);
|
unixmode, oplock_request,&rmode,NULL);
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
@@ -1535,12 +1534,6 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
|
|
||||||
close_file(fsp,False);
|
|
||||||
END_PROFILE(SMBopen);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
size = sbuf.st_size;
|
size = sbuf.st_size;
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fmode = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
@@ -1618,11 +1611,11 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
|||||||
|
|
||||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
unixmode = unix_mode(conn,smb_attr | aARCH, fname);
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,smb_mode,smb_ofun,unixmode,
|
fsp = open_file_shared(conn,fname,&sbuf,smb_mode,smb_ofun,unixmode,
|
||||||
oplock_request, &rmode,&smb_action);
|
oplock_request, &rmode,&smb_action);
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
@@ -1636,12 +1629,6 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
|||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
|
|
||||||
close_file(fsp,False);
|
|
||||||
END_PROFILE(SMBopenX);
|
|
||||||
return(ERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
size = sbuf.st_size;
|
size = sbuf.st_size;
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fmode = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
@@ -1737,6 +1724,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
START_PROFILE(SMBcreate);
|
START_PROFILE(SMBcreate);
|
||||||
|
|
||||||
com = SVAL(inbuf,smb_com);
|
com = SVAL(inbuf,smb_com);
|
||||||
@@ -1746,10 +1734,9 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
|
|
||||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
if (createmode & aVOLID)
|
if (createmode & aVOLID) {
|
||||||
{
|
|
||||||
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
|
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1767,7 +1754,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Open file in dos compatibility share mode. */
|
/* Open file in dos compatibility share mode. */
|
||||||
fsp = open_file_shared(conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
fsp = open_file_shared(conn,fname,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
||||||
ofun, unixmode, oplock_request, NULL, NULL);
|
ofun, unixmode, oplock_request, NULL, NULL);
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
@@ -1813,6 +1800,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
files_struct *fsp;
|
files_struct *fsp;
|
||||||
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
START_PROFILE(SMBctemp);
|
START_PROFILE(SMBctemp);
|
||||||
|
|
||||||
createmode = SVAL(inbuf,smb_vwv0);
|
createmode = SVAL(inbuf,smb_vwv0);
|
||||||
@@ -1821,15 +1809,18 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
|
|
||||||
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
unixmode = unix_mode(conn,createmode,fname);
|
unixmode = unix_mode(conn,createmode,fname);
|
||||||
|
|
||||||
pstrcpy(fname2,(char *)smbd_mktemp(fname));
|
pstrcpy(fname2,(char *)smbd_mktemp(fname));
|
||||||
|
/* This file should not exist. */
|
||||||
|
ZERO_STRUCT(sbuf);
|
||||||
|
vfs_stat(conn,fname2,&sbuf);
|
||||||
|
|
||||||
/* Open file in dos compatibility share mode. */
|
/* Open file in dos compatibility share mode. */
|
||||||
/* We should fail if file exists. */
|
/* We should fail if file exists. */
|
||||||
fsp = open_file_shared(conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
fsp = open_file_shared(conn,fname2,&sbuf,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
|
||||||
(FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
|
(FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
@@ -1904,6 +1895,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
BOOL exists=False;
|
BOOL exists=False;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
BOOL rc = True;
|
BOOL rc = True;
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
START_PROFILE(SMBunlink);
|
START_PROFILE(SMBunlink);
|
||||||
|
|
||||||
*directory = *mask = 0;
|
*directory = *mask = 0;
|
||||||
@@ -1916,7 +1908,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
|
|
||||||
DEBUG(3,("reply_unlink : %s\n",name));
|
DEBUG(3,("reply_unlink : %s\n",name));
|
||||||
|
|
||||||
rc = unix_convert(name,conn,0,&bad_path,NULL);
|
rc = unix_convert(name,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
p = strrchr(name,'/');
|
p = strrchr(name,'/');
|
||||||
if (!p) {
|
if (!p) {
|
||||||
@@ -1948,7 +1940,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
|||||||
if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory))
|
if (can_delete(directory,conn,dirtype) && !vfs_unlink(conn,directory))
|
||||||
count++;
|
count++;
|
||||||
if (!count)
|
if (!count)
|
||||||
exists = vfs_file_exist(conn,directory,NULL);
|
exists = vfs_file_exist(conn,directory,&sbuf);
|
||||||
} else {
|
} else {
|
||||||
void *dirptr = NULL;
|
void *dirptr = NULL;
|
||||||
char *dname;
|
char *dname;
|
||||||
@@ -3281,9 +3273,10 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
|
|||||||
int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory)
|
int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory)
|
||||||
{
|
{
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
int ret= -1;
|
int ret= -1;
|
||||||
|
|
||||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
unix_convert(directory,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
if (check_name(directory, conn))
|
if (check_name(directory, conn))
|
||||||
ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
|
ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
|
||||||
@@ -3482,13 +3475,14 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
int outsize = 0;
|
int outsize = 0;
|
||||||
BOOL ok = False;
|
BOOL ok = False;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
START_PROFILE(SMBrmdir);
|
START_PROFILE(SMBrmdir);
|
||||||
|
|
||||||
pstrcpy(directory,smb_buf(inbuf) + 1);
|
pstrcpy(directory,smb_buf(inbuf) + 1);
|
||||||
|
|
||||||
RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
|
RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
|
||||||
|
|
||||||
unix_convert(directory,conn, NULL,&bad_path,NULL);
|
unix_convert(directory,conn, NULL,&bad_path,&sbuf);
|
||||||
|
|
||||||
if (check_name(directory,conn))
|
if (check_name(directory,conn))
|
||||||
{
|
{
|
||||||
@@ -3614,12 +3608,13 @@ int rename_internals(connection_struct *conn,
|
|||||||
int error = ERRnoaccess;
|
int error = ERRnoaccess;
|
||||||
BOOL exists=False;
|
BOOL exists=False;
|
||||||
BOOL rc = True;
|
BOOL rc = True;
|
||||||
|
SMB_STRUCT_STAT sbuf1, sbuf2;
|
||||||
pstring zdirectory;
|
pstring zdirectory;
|
||||||
|
|
||||||
*directory = *mask = 0;
|
*directory = *mask = 0;
|
||||||
|
|
||||||
rc = unix_convert(name,conn,0,&bad_path1,NULL);
|
rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
|
||||||
unix_convert(newname,conn,newname_last_component,&bad_path2,NULL);
|
unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Split the old name into directory and last component
|
* Split the old name into directory and last component
|
||||||
@@ -3855,7 +3850,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
|||||||
int count,BOOL target_is_directory, int *err_ret)
|
int count,BOOL target_is_directory, int *err_ret)
|
||||||
{
|
{
|
||||||
int Access,action;
|
int Access,action;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT src_sbuf, sbuf2;
|
||||||
SMB_OFF_T ret=-1;
|
SMB_OFF_T ret=-1;
|
||||||
files_struct *fsp1,*fsp2;
|
files_struct *fsp1,*fsp2;
|
||||||
pstring dest;
|
pstring dest;
|
||||||
@@ -3873,10 +3868,10 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
|||||||
pstrcat(dest,p);
|
pstrcat(dest,p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vfs_file_exist(conn,src,&st))
|
if (!vfs_file_exist(conn,src,&src_sbuf))
|
||||||
return(False);
|
return(False);
|
||||||
|
|
||||||
fsp1 = open_file_shared(conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
fsp1 = open_file_shared(conn,src,&src_sbuf,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
|
||||||
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
|
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
|
||||||
|
|
||||||
if (!fsp1) {
|
if (!fsp1) {
|
||||||
@@ -3884,10 +3879,11 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!target_is_directory && count)
|
if (!target_is_directory && count)
|
||||||
ofun = 1;
|
ofun = FILE_EXISTS_OPEN;
|
||||||
|
|
||||||
fsp2 = open_file_shared(conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
|
vfs_stat(conn,dest,&sbuf2);
|
||||||
ofun,st.st_mode,0,&Access,&action);
|
fsp2 = open_file_shared(conn,dest,&sbuf2,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
|
||||||
|
ofun,src_sbuf.st_mode,0,&Access,&action);
|
||||||
|
|
||||||
if (!fsp2) {
|
if (!fsp2) {
|
||||||
close_file(fsp1,False);
|
close_file(fsp1,False);
|
||||||
@@ -3902,12 +3898,12 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
|||||||
* Stop the copy from occurring.
|
* Stop the copy from occurring.
|
||||||
*/
|
*/
|
||||||
ret = -1;
|
ret = -1;
|
||||||
st.st_size = 0;
|
src_sbuf.st_size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size)
|
if (src_sbuf.st_size)
|
||||||
ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0);
|
ret = vfs_transfer_file(-1, fsp1, -1, fsp2, src_sbuf.st_size, NULL, 0, 0);
|
||||||
|
|
||||||
close_file(fsp1,False);
|
close_file(fsp1,False);
|
||||||
/*
|
/*
|
||||||
@@ -3918,7 +3914,7 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
|
|||||||
*/
|
*/
|
||||||
*err_ret = close_file(fsp2,False);
|
*err_ret = close_file(fsp2,False);
|
||||||
|
|
||||||
return(ret == (SMB_OFF_T)st.st_size);
|
return(ret == (SMB_OFF_T)src_sbuf.st_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3945,6 +3941,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
BOOL bad_path1 = False;
|
BOOL bad_path1 = False;
|
||||||
BOOL bad_path2 = False;
|
BOOL bad_path2 = False;
|
||||||
BOOL rc = True;
|
BOOL rc = True;
|
||||||
|
SMB_STRUCT_STAT sbuf1, sbuf2;
|
||||||
START_PROFILE(SMBcopy);
|
START_PROFILE(SMBcopy);
|
||||||
|
|
||||||
*directory = *mask = 0;
|
*directory = *mask = 0;
|
||||||
@@ -3964,10 +3961,10 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
|
||||||
RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
|
RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
|
||||||
|
|
||||||
rc = unix_convert(name,conn,0,&bad_path1,NULL);
|
rc = unix_convert(name,conn,0,&bad_path1,&sbuf1);
|
||||||
unix_convert(newname,conn,0,&bad_path2,NULL);
|
unix_convert(newname,conn,0,&bad_path2,&sbuf2);
|
||||||
|
|
||||||
target_is_directory = vfs_directory_exist(conn,False,NULL);
|
target_is_directory = VALID_STAT_OF_DIR(sbuf2);
|
||||||
|
|
||||||
if ((flags&1) && target_is_directory) {
|
if ((flags&1) && target_is_directory) {
|
||||||
END_PROFILE(SMBcopy);
|
END_PROFILE(SMBcopy);
|
||||||
@@ -3979,7 +3976,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
|||||||
return(ERROR(ERRDOS,ERRbadpath));
|
return(ERROR(ERRDOS,ERRbadpath));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags&(1<<5)) && vfs_directory_exist(conn,name,NULL)) {
|
if ((flags&(1<<5)) && VALID_STAT_OF_DIR(sbuf1)) {
|
||||||
/* wants a tree copy! XXXX */
|
/* wants a tree copy! XXXX */
|
||||||
DEBUG(3,("Rejecting tree copy\n"));
|
DEBUG(3,("Rejecting tree copy\n"));
|
||||||
END_PROFILE(SMBcopy);
|
END_PROFILE(SMBcopy);
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
|
|||||||
scp = (stat_cache_entry *)(hash_elem->value);
|
scp = (stat_cache_entry *)(hash_elem->value);
|
||||||
DO_PROFILE_INC(statcache_hits);
|
DO_PROFILE_INC(statcache_hits);
|
||||||
trans_name = scp->names+scp->name_len+1;
|
trans_name = scp->names+scp->name_len+1;
|
||||||
if(conn->vfs_ops.stat(conn,dos_to_unix(trans_name,False), pst) != 0) {
|
if(vfs_stat(conn,trans_name, pst) != 0) {
|
||||||
/* Discard this entry - it doesn't exist in the filesystem. */
|
/* Discard this entry - it doesn't exist in the filesystem. */
|
||||||
hash_remove(&stat_cache, hash_elem);
|
hash_remove(&stat_cache, hash_elem);
|
||||||
return False;
|
return False;
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
|
|
||||||
/* XXXX we need to handle passed times, sattr and flags */
|
/* XXXX we need to handle passed times, sattr and flags */
|
||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,NULL);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
|
|
||||||
if (!check_name(fname,conn))
|
if (!check_name(fname,conn))
|
||||||
{
|
{
|
||||||
@@ -238,7 +238,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
|
|
||||||
unixmode = unix_mode(conn,open_attr | aARCH, fname);
|
unixmode = unix_mode(conn,open_attr | aARCH, fname);
|
||||||
|
|
||||||
fsp = open_file_shared(conn,fname,open_mode,open_ofun,unixmode,
|
fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
|
||||||
oplock_request, &rmode,&smb_action);
|
oplock_request, &rmode,&smb_action);
|
||||||
|
|
||||||
if (!fsp)
|
if (!fsp)
|
||||||
@@ -251,11 +251,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
|
|
||||||
close_file(fsp,False);
|
|
||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
|
||||||
}
|
|
||||||
|
|
||||||
size = sbuf.st_size;
|
size = sbuf.st_size;
|
||||||
fmode = dos_mode(conn,fname,&sbuf);
|
fmode = dos_mode(conn,fname,&sbuf);
|
||||||
mtime = sbuf.st_mtime;
|
mtime = sbuf.st_mtime;
|
||||||
@@ -407,7 +402,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
|||||||
if(needslash)
|
if(needslash)
|
||||||
pstrcat(pathreal,"/");
|
pstrcat(pathreal,"/");
|
||||||
pstrcat(pathreal,dname);
|
pstrcat(pathreal,dname);
|
||||||
if (conn->vfs_ops.stat(conn,dos_to_unix(pathreal,False),&sbuf) != 0)
|
if (vfs_stat(conn,pathreal,&sbuf) != 0)
|
||||||
{
|
{
|
||||||
/* Needed to show the msdfs symlinks as directories */
|
/* Needed to show the msdfs symlinks as directories */
|
||||||
if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
|
if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
|
||||||
@@ -657,6 +652,7 @@ static int call_trans2findfirst(connection_struct *conn,
|
|||||||
BOOL out_of_space = False;
|
BOOL out_of_space = False;
|
||||||
int space_remaining;
|
int space_remaining;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
|
|
||||||
*directory = *mask = 0;
|
*directory = *mask = 0;
|
||||||
|
|
||||||
@@ -686,7 +682,7 @@ static int call_trans2findfirst(connection_struct *conn,
|
|||||||
|
|
||||||
DEBUG(5,("path=%s\n",directory));
|
DEBUG(5,("path=%s\n",directory));
|
||||||
|
|
||||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
unix_convert(directory,conn,0,&bad_path,&sbuf);
|
||||||
if(!check_name(directory,conn)) {
|
if(!check_name(directory,conn)) {
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
{
|
{
|
||||||
@@ -1112,7 +1108,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
|
|||||||
|
|
||||||
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
|
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
|
||||||
|
|
||||||
if(conn->vfs_ops.stat(conn,".",&st)!=0) {
|
if(vfs_stat(conn,".",&st)!=0) {
|
||||||
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
|
DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
|
||||||
return (ERROR(ERRSRV,ERRinvdevice));
|
return (ERROR(ERRSRV,ERRinvdevice));
|
||||||
}
|
}
|
||||||
@@ -1308,7 +1304,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
|||||||
fname = fsp->fsp_name;
|
fname = fsp->fsp_name;
|
||||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
if (!check_name(fname,conn) ||
|
if (!check_name(fname,conn) ||
|
||||||
(!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
|
(!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
|
||||||
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
{
|
{
|
||||||
@@ -1328,7 +1324,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
|||||||
CHECK_ERROR(fsp);
|
CHECK_ERROR(fsp);
|
||||||
|
|
||||||
fname = fsp->fsp_name;
|
fname = fsp->fsp_name;
|
||||||
if (fsp->conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) {
|
if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
|
||||||
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
||||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||||
}
|
}
|
||||||
@@ -1350,7 +1346,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
|||||||
|
|
||||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
if (!check_name(fname,conn) ||
|
if (!check_name(fname,conn) ||
|
||||||
(!VALID_STAT(sbuf) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&sbuf))) {
|
(!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
|
||||||
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
{
|
{
|
||||||
@@ -1567,7 +1563,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
int mode=0;
|
int mode=0;
|
||||||
SMB_OFF_T size=0;
|
SMB_OFF_T size=0;
|
||||||
struct utimbuf tvs;
|
struct utimbuf tvs;
|
||||||
SMB_STRUCT_STAT st;
|
SMB_STRUCT_STAT sbuf;
|
||||||
pstring fname1;
|
pstring fname1;
|
||||||
char *fname;
|
char *fname;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
@@ -1588,9 +1584,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
* to do this call. JRA.
|
* to do this call. JRA.
|
||||||
*/
|
*/
|
||||||
fname = fsp->fsp_name;
|
fname = fsp->fsp_name;
|
||||||
unix_convert(fname,conn,0,&bad_path,&st);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
if (!check_name(fname,conn) ||
|
if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
|
||||||
(!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st))) {
|
|
||||||
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
{
|
{
|
||||||
@@ -1609,7 +1604,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
fname = fsp->fsp_name;
|
fname = fsp->fsp_name;
|
||||||
fd = fsp->fd;
|
fd = fsp->fd;
|
||||||
|
|
||||||
if (fsp->conn->vfs_ops.fstat(fsp,fd,&st) != 0) {
|
if (vfs_fstat(fsp,fd,&sbuf) != 0) {
|
||||||
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
|
||||||
return(UNIXERROR(ERRDOS,ERRbadfid));
|
return(UNIXERROR(ERRDOS,ERRbadfid));
|
||||||
}
|
}
|
||||||
@@ -1619,7 +1614,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
info_level = SVAL(params,0);
|
info_level = SVAL(params,0);
|
||||||
fname = fname1;
|
fname = fname1;
|
||||||
pstrcpy(fname,¶ms[6]);
|
pstrcpy(fname,¶ms[6]);
|
||||||
unix_convert(fname,conn,0,&bad_path,&st);
|
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||||
if(!check_name(fname, conn))
|
if(!check_name(fname, conn))
|
||||||
{
|
{
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
@@ -1630,7 +1625,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!VALID_STAT(st) && conn->vfs_ops.stat(conn,dos_to_unix(fname,False),&st)!=0) {
|
if(!VALID_STAT(sbuf)) {
|
||||||
DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
|
DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
|
||||||
if((errno == ENOENT) && bad_path)
|
if((errno == ENOENT) && bad_path)
|
||||||
{
|
{
|
||||||
@@ -1651,10 +1646,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
|||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
|
|
||||||
size = st.st_size;
|
size = sbuf.st_size;
|
||||||
tvs.modtime = st.st_mtime;
|
tvs.modtime = sbuf.st_mtime;
|
||||||
tvs.actime = st.st_atime;
|
tvs.actime = sbuf.st_atime;
|
||||||
mode = dos_mode(conn,fname,&st);
|
mode = dos_mode(conn,fname,&sbuf);
|
||||||
|
|
||||||
if (total_data > 0 && IVAL(pdata,0) == total_data) {
|
if (total_data > 0 && IVAL(pdata,0) == total_data) {
|
||||||
/* uggh, EAs for OS2 */
|
/* uggh, EAs for OS2 */
|
||||||
@@ -1908,10 +1903,10 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
|
|||||||
|
|
||||||
/* get some defaults (no modifications) if any info is zero or -1. */
|
/* get some defaults (no modifications) if any info is zero or -1. */
|
||||||
if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
|
if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
|
||||||
tvs.actime = st.st_atime;
|
tvs.actime = sbuf.st_atime;
|
||||||
|
|
||||||
if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
|
if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
|
||||||
tvs.modtime = st.st_mtime;
|
tvs.modtime = sbuf.st_mtime;
|
||||||
|
|
||||||
DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
|
DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
|
||||||
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
|
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
|
||||||
@@ -1925,13 +1920,13 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
|
|||||||
* changing the size of a file.
|
* changing the size of a file.
|
||||||
*/
|
*/
|
||||||
if (!size)
|
if (!size)
|
||||||
size = st.st_size;
|
size = sbuf.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try and set the times, size and mode of this file -
|
/* Try and set the times, size and mode of this file -
|
||||||
if they are different from the current values
|
if they are different from the current values
|
||||||
*/
|
*/
|
||||||
if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
|
if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
|
||||||
if(fsp != NULL) {
|
if(fsp != NULL) {
|
||||||
/*
|
/*
|
||||||
* This was a setfileinfo on an open file.
|
* This was a setfileinfo on an open file.
|
||||||
@@ -1957,7 +1952,7 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check the mode isn't different, before changing it */
|
/* check the mode isn't different, before changing it */
|
||||||
if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
|
if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
|
||||||
|
|
||||||
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
|
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
|
||||||
fname, mode ));
|
fname, mode ));
|
||||||
@@ -1968,7 +1963,7 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size != st.st_size) {
|
if(size != sbuf.st_size) {
|
||||||
|
|
||||||
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
|
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
|
||||||
fname, (double)size ));
|
fname, (double)size ));
|
||||||
@@ -2004,6 +1999,7 @@ static int call_trans2mkdir(connection_struct *conn,
|
|||||||
char *params = *pparams;
|
char *params = *pparams;
|
||||||
pstring directory;
|
pstring directory;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
SMB_STRUCT_STAT sbuf;
|
||||||
BOOL bad_path = False;
|
BOOL bad_path = False;
|
||||||
|
|
||||||
if (!CAN_WRITE(conn))
|
if (!CAN_WRITE(conn))
|
||||||
@@ -2013,7 +2009,7 @@ static int call_trans2mkdir(connection_struct *conn,
|
|||||||
|
|
||||||
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
|
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
|
||||||
|
|
||||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
unix_convert(directory,conn,0,&bad_path,&sbuf);
|
||||||
if (check_name(directory,conn))
|
if (check_name(directory,conn))
|
||||||
ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
|
ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,8 @@ BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf)
|
|||||||
if (!sbuf)
|
if (!sbuf)
|
||||||
sbuf = &st;
|
sbuf = &st;
|
||||||
|
|
||||||
|
ZERO_STRUCTP(sbuf);
|
||||||
|
|
||||||
if (vfs_stat(conn,fname,sbuf) != 0)
|
if (vfs_stat(conn,fname,sbuf) != 0)
|
||||||
return(False);
|
return(False);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user