diff options
author | Jeremy Allison <jra@samba.org> | 2002-03-20 00:46:53 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-03-20 00:46:53 +0000 |
commit | b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329 (patch) | |
tree | bd74664377abf0b1d0745476d88f6668d06c5718 /source3 | |
parent | 0cd5dd67ce12f02d3d20568e901ef7666caa8472 (diff) | |
download | samba-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')
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/printing/printfsp.c | 1 | ||||
-rw-r--r-- | source3/smbd/close.c | 30 | ||||
-rw-r--r-- | source3/smbd/dir.c | 27 | ||||
-rw-r--r-- | source3/smbd/fileio.c | 12 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 53 | ||||
-rw-r--r-- | source3/smbd/open.c | 101 | ||||
-rw-r--r-- | source3/smbd/reply.c | 156 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 9 | ||||
-rw-r--r-- | source3/smbd/vfs-wrap.c | 6 |
10 files changed, 140 insertions, 256 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index 34832edc79..62a7198d35 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -392,7 +392,6 @@ typedef struct files_struct BOOL modified; BOOL is_directory; BOOL directory_delete_on_close; - BOOL stat_open; char *fsp_name; } files_struct; diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index 2560e1c2fe..9f33d57ad5 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -68,7 +68,6 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) 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,print_job_fname(jobid)); 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 |