diff options
Diffstat (limited to 'source3/smbd/open.c')
-rw-r--r-- | source3/smbd/open.c | 116 |
1 files changed, 64 insertions, 52 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index edd94bd865..12f6d12948 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -88,12 +88,11 @@ static void check_for_pipe(char *fname) ****************************************************************************/ 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; pstring fname; int accmode = (flags & O_ACCMODE); - SMB_STRUCT_STAT sbuf; fsp->fd = -1; fsp->oplock_type = NO_OPLOCK; @@ -138,10 +137,12 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, return False; } - if (conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf) == -1) { - DEBUG(0,("Error doing fstat on open file %s (%s)\n", fname,strerror(errno) )); - fd_close(conn, fsp); - return False; + 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) )); + fd_close(conn, fsp); + return False; + } } /* @@ -150,18 +151,18 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn, * 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); errno = EISDIR; return False; } - fsp->mode = sbuf.st_mode; - fsp->inode = sbuf.st_ino; - fsp->dev = sbuf.st_dev; + fsp->mode = psbuf->st_mode; + fsp->inode = psbuf->st_ino; + fsp->dev = psbuf->st_dev; GetTimeOfDay(&fsp->open_time); fsp->vuid = current_user.vuid; - fsp->size = 0; + fsp->size = psbuf->st_size; fsp->pos = -1; fsp->can_lock = True; 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, - mode_t mode,int oplock_request, int *Access,int *action) +files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf, + int share_mode,int ofun, mode_t mode,int oplock_request, int *Access,int *action) { int flags=0; int flags2=0; int deny_mode = GET_DENY_MODE(share_mode); BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode); - SMB_STRUCT_STAT sbuf; - BOOL file_existed = vfs_file_exist(conn, fname, &sbuf); + BOOL file_existed = VALID_STAT(*psbuf); BOOL fcbopen = False; SMB_DEV_T dev = 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 */ 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) { DEBUG(5,("open_file_shared: read/write access requested for file %s on read only %s\n", 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) { - dev = sbuf.st_dev; - inode = sbuf.st_ino; + + dev = psbuf->st_dev; + inode = psbuf->st_ino; 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", 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 = 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; } @@ -717,11 +719,16 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod * If requested, truncate the file. */ - if ((flags2&O_TRUNC) && (truncate_unless_locked(conn,fsp) == -1)) { - unlock_share_entry_fsp(fsp); - fd_close(conn,fsp); - file_free(fsp); - return NULL; + 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); + fd_close(conn,fsp); + file_free(fsp); + return NULL; + } } switch (flags) { @@ -783,28 +790,26 @@ files_struct *open_file_shared(connection_struct *conn,char *fname,int share_mod with the 'stat_open' flag set ****************************************************************************/ -files_struct *open_file_stat(connection_struct *conn, - char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action) +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 = file_new(); - - if(!fsp) - return NULL; + files_struct *fsp = 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); + 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(pst->st_mode)) { + if(S_ISDIR(psbuf->st_mode)) { DEBUG(0,("open_file_stat: %s is a directory !\n", fname )); - file_free(fsp); return NULL; } + fsp = file_new(); + if(!fsp) + return NULL; + *action = FILE_WAS_OPENED; 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->mode = 0; + fsp->mode = psbuf->st_mode; + fsp->inode = psbuf->st_ino; + fsp->dev = psbuf->st_dev; GetTimeOfDay(&fsp->open_time); + fsp->size = psbuf->st_size; fsp->vuid = current_user.vuid; - fsp->size = 0; fsp->pos = -1; fsp->can_lock = 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. ****************************************************************************/ -files_struct *open_directory(connection_struct *conn, - char *fname, int smb_ofun, mode_t unixmode, int *action) +files_struct *open_directory(connection_struct *conn, char *fname, + SMB_STRUCT_STAT *psbuf, int smb_ofun, mode_t unixmode, int *action) { extern struct current_user current_user; - SMB_STRUCT_STAT st; BOOL got_stat = False; files_struct *fsp = file_new(); if(!fsp) return NULL; - if(conn->vfs_ops.stat(conn,dos_to_unix(fname, False), &st) == 0) { + if (VALID_STAT(*psbuf)) got_stat = True; - } if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) { file_free(fsp); @@ -876,7 +881,7 @@ files_struct *open_directory(connection_struct *conn, 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 )); file_free(fsp); errno = EACCES; @@ -903,6 +908,12 @@ files_struct *open_directory(connection_struct *conn, file_free(fsp); return NULL; } + + if(vfs_stat(conn,fname, psbuf) != 0) { + file_free(fsp); + return NULL; + } + *action = FILE_WAS_CREATED; } @@ -919,7 +930,7 @@ files_struct *open_directory(connection_struct *conn, 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 )); file_free(fsp); return NULL; @@ -928,18 +939,19 @@ files_struct *open_directory(connection_struct *conn, *action = FILE_WAS_OPENED; } - DEBUG(5,("open_directory: opening directory %s\n", - fname)); + DEBUG(5,("open_directory: opening directory %s\n", fname)); /* * Setup the files_struct for it. */ 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); + fsp->size = psbuf->st_size; fsp->vuid = current_user.vuid; - fsp->size = 0; fsp->pos = -1; fsp->can_lock = True; 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_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); dev = sbuf.st_dev; |