BOOL modified;
BOOL is_directory;
BOOL directory_delete_on_close;
- BOOL stat_open;
char *fsp_name;
} files_struct;
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));
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);
}
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;
}
return 0;
}
-/****************************************************************************
- 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.
****************************************************************************/
{
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);
}
size_t sd_size;
files_struct *fsp;
int smb_action;
+ int access_mode;
NTSTATUS status;
uint32 access_granted;
/* 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;
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
}
/*******************************************************************
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);
+}
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.
*/
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|
* and map to a stat open.
*/
- *pstat_open_only = True;
smb_open_mode = DOS_OPEN_RDONLY;
} else {
BOOL bad_path = False;
files_struct *fsp=NULL;
char *p = NULL;
- BOOL stat_open_only = False;
time_t c_time;
START_PROFILE(SMBntcreateX);
*/
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);
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) {
BOOL bad_path = False;
files_struct *fsp = NULL;
char *p = NULL;
- BOOL stat_open_only = False;
uint32 flags;
uint32 desired_access;
uint32 file_attributes;
* 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);
}
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) {
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);
}
****************************************************************************/
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;
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;
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);
* 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",
* 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;
}
return fsp;
}
-/****************************************************************************
- 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.
****************************************************************************/
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.
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);
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);
}
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);
}
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
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;
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
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