summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2002-03-20 00:46:53 +0000
committerJeremy Allison <jra@samba.org>2002-03-20 00:46:53 +0000
commitb9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329 (patch)
treebd74664377abf0b1d0745476d88f6668d06c5718 /source3/smbd
parent0cd5dd67ce12f02d3d20568e901ef7666caa8472 (diff)
downloadsamba-b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329.tar.gz
samba-b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329.tar.bz2
samba-b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329.zip
Remove the "stat open" code - make it inline. This should fix the
bugs with opening and renaming mp3 files, also the word rename problems that people have had for a while. Needs a make clean :-) make. Also added JohnR's printing fix. Jeremy. (This used to be commit 504e5ef0494c54efbd0357e334cb2aa5a9eb9c14)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c30
-rw-r--r--source3/smbd/dir.c27
-rw-r--r--source3/smbd/fileio.c12
-rw-r--r--source3/smbd/nttrans.c53
-rw-r--r--source3/smbd/open.c101
-rw-r--r--source3/smbd/reply.c156
-rw-r--r--source3/smbd/trans2.c9
-rw-r--r--source3/smbd/vfs-wrap.c6
8 files changed, 140 insertions, 254 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 79b627e924..dc52327cb4 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -75,7 +75,7 @@ static void check_magic(files_struct *fsp,connection_struct *conn)
return;
}
- transfer_file(tmp_fd,outfd,st.st_size);
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
close(tmp_fd);
close(outfd);
}
@@ -90,15 +90,17 @@ static int close_filestruct(files_struct *fsp)
connection_struct *conn = fsp->conn;
int ret = 0;
- if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
- ret = -1;
+ if (fsp->fd != -1) {
+ if(flush_write_cache(fsp, CLOSE_FLUSH) == -1)
+ ret = -1;
- delete_write_cache(fsp);
+ delete_write_cache(fsp);
+ }
fsp->is_directory = False;
- fsp->stat_open = False;
conn->num_files_open--;
+ SAFE_FREE(fsp->wbmpx_ptr);
return ret;
}
@@ -261,22 +263,6 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
}
/****************************************************************************
- Close a file opened with null permissions in order to read permissions.
-****************************************************************************/
-
-static int close_statfile(files_struct *fsp, BOOL normal_close)
-{
- close_filestruct(fsp);
-
- if (fsp->fsp_name)
- string_free(&fsp->fsp_name);
-
- file_free(fsp);
-
- return 0;
-}
-
-/****************************************************************************
Close a directory opened by an NT SMB call.
****************************************************************************/
@@ -284,7 +270,5 @@ int close_file(files_struct *fsp, BOOL normal_close)
{
if(fsp->is_directory)
return close_directory(fsp, normal_close);
- else if(fsp->stat_open)
- return close_statfile(fsp, normal_close);
return close_normal_file(fsp, normal_close);
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 2b2683caa5..3a7b697d75 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -674,6 +674,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
size_t sd_size;
files_struct *fsp;
int smb_action;
+ int access_mode;
NTSTATUS status;
uint32 access_granted;
@@ -686,10 +687,12 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
/* Pseudo-open the file (note - no fd's created). */
if(S_ISDIR(ste.st_mode))
- fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), FILE_OPEN,
+ fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
unix_mode(conn,aRONLY|aDIR, name), &smb_action);
else
- fsp = open_file_stat(conn,name,&ste,DOS_OPEN_RDONLY,&smb_action);
+ fsp = open_file_shared1(conn, name, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+
if (!fsp)
return False;
@@ -703,26 +706,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
&access_granted, &status);
-
-#if 0
- /* Old - crappy check :-). JRA */
-
- if (ste.st_uid == conn->uid) {
- return (ste.st_mode & S_IRUSR) == S_IRUSR;
- } else {
- int i;
- if (ste.st_gid == conn->gid) {
- return (ste.st_mode & S_IRGRP) == S_IRGRP;
- }
- for (i=0; i<conn->ngroups; i++) {
- if (conn->groups[i] == ste.st_gid) {
- return (ste.st_mode & S_IRGRP) == S_IRGRP;
- }
- }
- }
-
- return (ste.st_mode & S_IROTH) == S_IROTH;
-#endif
}
/*******************************************************************
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index acbbb73352..addbcb0b3c 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -645,3 +645,15 @@ void sync_file(connection_struct *conn, files_struct *fsp)
conn->vfs_ops.fsync(fsp,fsp->fd);
}
}
+
+/************************************************************
+ Perform a stat whether a valid fd or not.
+************************************************************/
+
+int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
+{
+ if (fsp->fd == -1)
+ return vfs_stat(fsp->conn, fsp->fsp_name, pst);
+ else
+ return vfs_fstat(fsp,fsp->fd, pst);
+}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index d9b90c14cb..fb985bb325 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -329,13 +329,11 @@ static int map_create_disposition( uint32 create_disposition)
Utility function to map share modes.
****************************************************************************/
-static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_options,
+static int map_share_mode( char *fname, uint32 create_options,
uint32 *desired_access, uint32 share_access, uint32 file_attributes)
{
int smb_open_mode = -1;
- *pstat_open_only = False;
-
/*
* Convert GENERIC bits to specific bits.
*/
@@ -374,9 +372,6 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_opt
if (smb_open_mode == -1) {
- if(*desired_access == WRITE_DAC_ACCESS || *desired_access == READ_CONTROL_ACCESS)
- *pstat_open_only = True;
-
if(*desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
FILE_EXECUTE|FILE_READ_ATTRIBUTES|
FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
@@ -389,7 +384,6 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_opt
* and map to a stat open.
*/
- *pstat_open_only = True;
smb_open_mode = DOS_OPEN_RDONLY;
} else {
@@ -569,7 +563,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
BOOL bad_path = False;
files_struct *fsp=NULL;
char *p = NULL;
- BOOL stat_open_only = False;
time_t c_time;
START_PROFILE(SMBntcreateX);
@@ -655,7 +648,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
*/
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
- if((smb_open_mode = map_share_mode(&stat_open_only, fname, create_options, &desired_access,
+ if((smb_open_mode = map_share_mode(fname, create_options, &desired_access,
share_access,
file_attributes)) == -1) {
END_PROFILE(SMBntcreateX);
@@ -770,26 +763,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
END_PROFILE(SMBntcreateX);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
-#ifdef EROFS
- } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
-#else /* !EROFS */
- } else if (errno == EACCES && stat_open_only) {
-#endif
- /*
- * We couldn't open normally and all we want
- * are the permissions. Try and do a stat open.
- */
-
- oplock_request = 0;
-
- fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
-
- if(!fsp) {
- restore_case_semantics(file_attributes);
- END_PROFILE(SMBntcreateX);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
} else {
if((errno == ENOENT) && bad_path) {
@@ -1059,7 +1032,6 @@ static int call_nt_transact_create(connection_struct *conn,
BOOL bad_path = False;
files_struct *fsp = NULL;
char *p = NULL;
- BOOL stat_open_only = False;
uint32 flags;
uint32 desired_access;
uint32 file_attributes;
@@ -1172,7 +1144,7 @@ static int call_nt_transact_create(connection_struct *conn,
* and the share access.
*/
- if((smb_open_mode = map_share_mode( &stat_open_only, fname, create_options, &desired_access,
+ if((smb_open_mode = map_share_mode( fname, create_options, &desired_access,
share_access, file_attributes)) == -1)
return ERROR_DOS(ERRDOS,ERRbadaccess);
@@ -1252,25 +1224,6 @@ static int call_nt_transact_create(connection_struct *conn,
}
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
-#ifdef EROFS
- } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
-#else /* !EROFS */
- } else if (errno == EACCES && stat_open_only) {
-#endif
-
- /*
- * We couldn't open normally and all we want
- * are the permissions. Try and do a stat open.
- */
-
- oplock_request = 0;
-
- fsp = open_file_stat(conn,fname,&sbuf,smb_open_mode,&smb_action);
-
- if(!fsp) {
- restore_case_semantics(file_attributes);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
} else {
if((errno == ENOENT) && bad_path) {
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b86d9763a4..0aaf5fd1c7 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -60,7 +60,7 @@ static int fd_open(struct connection_struct *conn, char *fname,
int fd_close(struct connection_struct *conn, files_struct *fsp)
{
if (fsp->fd == -1)
- return -1;
+ return 0; /* what we used to call a stat open. */
return fd_close_posix(conn, fsp);
}
@@ -87,7 +87,7 @@ static void check_for_pipe(char *fname)
****************************************************************************/
static BOOL open_file(files_struct *fsp,connection_struct *conn,
- char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode)
+ char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
{
extern struct current_user current_user;
pstring fname;
@@ -149,18 +149,30 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
local_flags &= ~O_TRUNC;
- /* actually do the open */
- fsp->fd = fd_open(conn, fname, local_flags, mode);
+ if (desired_access == 0 || (desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
+ (local_flags & O_CREAT)) {
- if (fsp->fd == -1) {
- DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
- fname,strerror(errno),local_flags,flags));
- check_for_pipe(fname);
- return False;
+ /* actually do the open */
+ fsp->fd = fd_open(conn, fname, local_flags, mode);
+
+ if (fsp->fd == -1) {
+ DEBUG(3,("Error opening file %s (%s) (local_flags=%d) (flags=%d)\n",
+ fname,strerror(errno),local_flags,flags));
+ check_for_pipe(fname);
+ return False;
+ }
}
+ fsp->fd == -1; /* What we used to call a stat open. */
if (!VALID_STAT(*psbuf)) {
- if (vfs_fstat(fsp,fsp->fd,psbuf) == -1) {
+ int ret;
+
+ if (fsp->fd == -1)
+ ret = vfs_stat(conn, fname, psbuf);
+ else
+ ret = vfs_fstat(fsp,fsp->fd,psbuf);
+
+ if (ret == -1) {
DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) ));
fd_close(conn, fsp);
return False;
@@ -194,7 +206,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
- fsp->stat_open = False;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
@@ -783,7 +794,8 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
* we can do. We also ensure we're not going to create or tuncate
* the file as we only want an access decision at this stage. JRA.
*/
- fsp_open = open_file(fsp,conn,fname,psbuf,flags|(flags2&~(O_TRUNC|O_CREAT)),mode);
+ fsp_open = open_file(fsp,conn,fname,psbuf,
+ flags|(flags2&~(O_TRUNC|O_CREAT)),mode,desired_access);
DEBUG(4,("open_file_shared : share_mode deny - calling open_file with \
flags=0x%X flags2=0x%X mode=0%o returned %d\n",
@@ -816,10 +828,10 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
* open_file strips any O_TRUNC flags itself.
*/
- fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode);
+ fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,mode,desired_access);
if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT) && fcbopen) {
- if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode)) == True)
+ if((fsp_open = open_file(fsp,conn,fname,psbuf,O_RDONLY,mode,desired_access)) == True)
flags = O_RDONLY;
}
@@ -978,65 +990,6 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
}
/****************************************************************************
- Open a file for permissions read only. Return a pseudo file entry
- with the 'stat_open' flag set
-****************************************************************************/
-
-files_struct *open_file_stat(connection_struct *conn, char *fname,
- SMB_STRUCT_STAT *psbuf, int smb_ofun, int *action)
-{
- extern struct current_user current_user;
- 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(conn);
- if(!fsp)
- return NULL;
-
- *action = FILE_WAS_OPENED;
-
- DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
-
- /*
- * Setup the files_struct for it.
- */
-
- fsp->mode = psbuf->st_mode;
- fsp->inode = psbuf->st_ino;
- fsp->dev = psbuf->st_dev;
- fsp->size = psbuf->st_size;
- fsp->vuid = current_user.vuid;
- fsp->pos = -1;
- fsp->can_lock = False;
- fsp->can_read = False;
- fsp->can_write = False;
- fsp->share_mode = 0;
- fsp->print_file = False;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->stat_open = True;
- fsp->directory_delete_on_close = False;
- fsp->conn = conn;
- string_set(&fsp->fsp_name,fname);
- fsp->wcp = NULL; /* Write cache pointer. */
-
- conn->num_files_open++;
-
- return fsp;
-}
-
-/****************************************************************************
Open a file for for write to ensure that we can fchmod it.
****************************************************************************/
@@ -1052,7 +1005,7 @@ files_struct *open_file_fchmod(connection_struct *conn, char *fname, SMB_STRUCT_
if(!fsp)
return NULL;
- fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0);
+ fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,0);
/*
* This is not a user visible file open.
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 0af2ea3716..4dcb674ff1 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2230,10 +2230,9 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
return ERROR_DOS(ERRDOS,ERRbadfid);
}
- if(fsp->is_directory || fsp->stat_open) {
+ if(fsp->is_directory) {
/*
- * Special case - close NT SMB directory or stat file
- * handle.
+ * Special case - close NT SMB directory handle.
*/
DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
close_file(fsp,True);
@@ -3969,54 +3968,55 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- struct utimbuf unix_times;
- int outsize = 0;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBsetattrE);
+ struct utimbuf unix_times;
+ int outsize = 0;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBsetattrE);
- outsize = set_message(outbuf,0,0,True);
+ outsize = set_message(outbuf,0,0,True);
- CHECK_FSP(fsp,conn);
+ if(!fsp || (fsp->conn != conn)) {
+ END_PROFILE(SMBgetattrE);
+ return ERROR_DOS(ERRDOS,ERRbadfid);
+ }
- /* Convert the DOS times into unix times. Ignore create
- time as UNIX can't set this.
- */
- unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
- unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
+ /*
+ * Convert the DOS times into unix times. Ignore create
+ * time as UNIX can't set this.
+ */
+
+ unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
+ unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
- /*
- * Patch from Ray Frush <frush@engr.colostate.edu>
- * Sometimes times are sent as zero - ignore them.
- */
+ /*
+ * Patch from Ray Frush <frush@engr.colostate.edu>
+ * Sometimes times are sent as zero - ignore them.
+ */
- if ((unix_times.actime == 0) && (unix_times.modtime == 0))
- {
- /* Ignore request */
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
- dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
- }
- END_PROFILE(SMBsetattrE);
- return(outsize);
- }
- else if ((unix_times.actime != 0) && (unix_times.modtime == 0))
- {
- /* set modify time = to access time if modify time was 0 */
- unix_times.modtime = unix_times.actime;
- }
+ if ((unix_times.actime == 0) && (unix_times.modtime == 0)) {
+ /* Ignore request */
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
+ dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
+ }
+ END_PROFILE(SMBsetattrE);
+ return(outsize);
+ } else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) {
+ /* set modify time = to access time if modify time was 0 */
+ unix_times.modtime = unix_times.actime;
+ }
- /* Set the date on this file */
- if(file_utime(conn, fsp->fsp_name, &unix_times)) {
- END_PROFILE(SMBsetattrE);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
- }
+ /* Set the date on this file */
+ if(file_utime(conn, fsp->fsp_name, &unix_times)) {
+ END_PROFILE(SMBsetattrE);
+ return ERROR_DOS(ERRDOS,ERRnoaccess);
+ }
- DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
- fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
+ DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
+ fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
- END_PROFILE(SMBsetattrE);
- return(outsize);
+ END_PROFILE(SMBsetattrE);
+ return(outsize);
}
@@ -4217,44 +4217,48 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- SMB_STRUCT_STAT sbuf;
- int outsize = 0;
- int mode;
- files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- START_PROFILE(SMBgetattrE);
+ SMB_STRUCT_STAT sbuf;
+ int outsize = 0;
+ int mode;
+ files_struct *fsp = file_fsp(inbuf,smb_vwv0);
+ START_PROFILE(SMBgetattrE);
- outsize = set_message(outbuf,11,0,True);
+ outsize = set_message(outbuf,11,0,True);
- CHECK_FSP(fsp,conn);
+ if(!fsp || (fsp->conn != conn)) {
+ END_PROFILE(SMBgetattrE);
+ return ERROR_DOS(ERRDOS,ERRbadfid);
+ }
- /* Do an fstat on this file */
- if(vfs_fstat(fsp,fsp->fd, &sbuf)) {
- END_PROFILE(SMBgetattrE);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ /* Do an fstat on this file */
+ if(fsp_stat(fsp, &sbuf)) {
+ END_PROFILE(SMBgetattrE);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- mode = dos_mode(conn,fsp->fsp_name,&sbuf);
+ mode = dos_mode(conn,fsp->fsp_name,&sbuf);
- /* Convert the times into dos times. Set create
- date to be last modify date as UNIX doesn't save
- this */
- put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
- put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
- put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
- if (mode & aDIR)
- {
- SIVAL(outbuf,smb_vwv6,0);
- SIVAL(outbuf,smb_vwv8,0);
- }
- else
- {
- SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
- SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
- }
- SSVAL(outbuf,smb_vwv10, mode);
+ /*
+ * Convert the times into dos times. Set create
+ * date to be last modify date as UNIX doesn't save
+ * this.
+ */
+
+ put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
+ put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
+ put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
+
+ if (mode & aDIR) {
+ SIVAL(outbuf,smb_vwv6,0);
+ SIVAL(outbuf,smb_vwv8,0);
+ } else {
+ SIVAL(outbuf,smb_vwv6,(uint32)sbuf.st_size);
+ SIVAL(outbuf,smb_vwv8,SMB_ROUNDUP(sbuf.st_size,1024));
+ }
+ SSVAL(outbuf,smb_vwv10, mode);
- DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
+ DEBUG( 3, ( "reply_getattrE fnum=%d\n", fsp->fnum));
- END_PROFILE(SMBgetattrE);
- return(outsize);
+ END_PROFILE(SMBgetattrE);
+ return(outsize);
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index d08e3419f9..660363a7f1 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1452,7 +1452,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
- if(fsp && (fsp->is_directory || fsp->stat_open)) {
+ if(fsp && (fsp->is_directory || fsp->fd == -1)) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
@@ -1871,11 +1871,6 @@ NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
fsp->directory_delete_on_close = delete_on_close;
DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
- } else if(fsp->stat_open) {
-
- DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
-
} else {
files_struct *iterate_fsp;
@@ -1959,7 +1954,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
- if(fsp && (fsp->is_directory || fsp->stat_open)) {
+ if(fsp && (fsp->is_directory || fsp->fd == -1)) {
/*
* This is actually a SETFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
diff --git a/source3/smbd/vfs-wrap.c b/source3/smbd/vfs-wrap.c
index 1d94e18e5b..fadc435a2f 100644
--- a/source3/smbd/vfs-wrap.c
+++ b/source3/smbd/vfs-wrap.c
@@ -164,11 +164,13 @@ ssize_t vfswrap_write(files_struct *fsp, int fd, const void *data, size_t n)
SMB_OFF_T vfswrap_lseek(files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
{
- SMB_OFF_T result;
+ SMB_OFF_T result = 0;
START_PROFILE(syscall_lseek);
- result = sys_lseek(filedes, offset, whence);
+ /* Cope with 'stat' file opens. */
+ if (filedes != -1)
+ result = sys_lseek(filedes, offset, whence);
/*
* We want to maintain the fiction that we can seek