diff options
author | Samba Release Account <samba-bugs@samba.org> | 1997-05-27 20:28:45 +0000 |
---|---|---|
committer | Samba Release Account <samba-bugs@samba.org> | 1997-05-27 20:28:45 +0000 |
commit | ccf4314fe73fb035f6941f00ce952ba3a308c2da (patch) | |
tree | 0f511263cd97ae0774877347cf5667d5b23dbe8e /source3/smbd | |
parent | 36693ec1100ffc00d534b20aaae401ea8cbd77c7 (diff) | |
download | samba-ccf4314fe73fb035f6941f00ce952ba3a308c2da.tar.gz samba-ccf4314fe73fb035f6941f00ce952ba3a308c2da.tar.bz2 samba-ccf4314fe73fb035f6941f00ce952ba3a308c2da.zip |
loadparm.c: Ensure printer services cannot be read only and don't use share mode locking.
locking.c: Changed aborts to returns so not so drastic on PANIC errors.
proto.h: Removed definition of open_file as this is now never externally called.
reply.c: Changed reply_mknew, reply_ctemp, reply_printopen to go through open_file_shared.
server.c: Modified open_file_shared to be more robust and be useful for printer & temp files.
Removed truncate option from open_file (now all truncates are done in open_file_shared).
util.c: Added EAGAIN to errors checked in open_socket_out().
version.h: Updated to 1.9.17alpha2.
jallison@whistle.com
(This used to be commit d8471909b79fd591be2b789485b65d2e636d4745)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/reply.c | 30 | ||||
-rw-r--r-- | source3/smbd/server.c | 31 |
2 files changed, 38 insertions, 23 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 639c386c2f..530ce84895 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1135,7 +1135,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) /**************************************************************************** - reply to a mknew + reply to a mknew or a create ****************************************************************************/ int reply_mknew(char *inbuf,char *outbuf) { @@ -1145,7 +1145,8 @@ int reply_mknew(char *inbuf,char *outbuf) int outsize = 0; int createmode; mode_t unixmode; - + int ofun = 0; + com = SVAL(inbuf,smb_com); cnum = SVAL(inbuf,smb_tid); @@ -1160,9 +1161,6 @@ int reply_mknew(char *inbuf,char *outbuf) unixmode = unix_mode(cnum,createmode); - if (com == SMBmknew && file_exist(fname,NULL)) - return(ERROR(ERRDOS,ERRfilexists)); - fnum = find_free_file(); if (fnum < 0) return(ERROR(ERRSRV,ERRnofids)); @@ -1170,7 +1168,19 @@ int reply_mknew(char *inbuf,char *outbuf) if (!check_name(fname,cnum)) return(UNIXERROR(ERRDOS,ERRnoaccess)); - open_file(fnum,cnum,fname,O_RDWR | O_CREAT | O_TRUNC,unixmode, 0); + if(com == SMBmknew) + { + /* We should fail if file exists. */ + ofun = 0x10; + } + else + { + /* SMBcreate - Create if file doesn't exist, truncate if it does. */ + ofun = 0x12; + } + + /* Open file in dos compatibility share mode. */ + open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, NULL, NULL); if (!Files[fnum].open) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -1218,7 +1228,9 @@ int reply_ctemp(char *inbuf,char *outbuf) strcpy(fname2,(char *)mktemp(fname)); - open_file(fnum,cnum,fname2,O_RDWR | O_CREAT | O_TRUNC,unixmode, 0); + /* Open file in dos compatibility share mode. */ + /* We should fail if file exists. */ + open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, NULL, NULL); if (!Files[fnum].open) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2219,8 +2231,8 @@ int reply_printopen(char *inbuf,char *outbuf) if (!check_name(fname2,cnum)) return(ERROR(ERRDOS,ERRnoaccess)); - open_file(fnum,cnum,fname2,O_WRONLY | O_CREAT | O_TRUNC, - unix_mode(cnum,0), 0); + /* Open for exclusive use, write only. */ + open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), NULL, NULL); if (!Files[fnum].open) return(UNIXERROR(ERRDOS,ERRnoaccess)); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 65e620c7f0..4ae139fc58 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -937,7 +937,7 @@ int fd_attempt_close(file_fd_struct *fd_ptr) /**************************************************************************** open a file ****************************************************************************/ -void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf) +static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf) { extern struct current_user current_user; pstring fname; @@ -1033,14 +1033,6 @@ void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *s return; } - /* - * If O_TRUNC was set, ensure we truncate the file. - * open_file_shared explicitly clears this flag before - * calling open_file, so we can safely do this here. - */ - if(flags & O_TRUNC) - ftruncate(fd_ptr->fd, 0); - } else { int open_flags; /* We need to allocate a new file_fd_struct (this increments the @@ -1389,11 +1381,19 @@ free_and_exit: Helper for open_file_shared. Truncate a file after checking locking; close file if locked. **************************************************************************/ -static void truncate_unless_locked(int fnum, int cnum) +static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, + BOOL *share_locked) { if (Files[fnum].can_write){ if (is_locked(fnum,cnum,0x3FFFFFFF,0)){ + /* If share modes are in force for this connection we + have the share entry locked. Unlock it before closing. */ + if (*share_locked && lp_share_modes(SNUM(cnum))) + unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, + Files[fnum].fd_ptr->inode, token); close_file(fnum); + /* Share mode no longer locked. */ + *share_locked = False; errno = EACCES; unix_ERR_class = ERRDOS; unix_ERR_code = ERRlock; @@ -1600,12 +1600,15 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (!file_existed) *action = 2; if (file_existed && (flags2 & O_TRUNC)) *action = 3; } - - if ((flags2&O_TRUNC) && file_existed) - truncate_unless_locked(fnum,cnum); - + /* We must create the share mode entry before truncate as + truncate can fail due to locking and have to close the + file (which expects the share_mode_entry to be there). + */ if (lp_share_modes(SNUM(cnum))) set_share_mode(token, fnum); + + if ((flags2&O_TRUNC) && file_existed) + truncate_unless_locked(fnum,cnum,token,&share_locked); } if (share_locked && lp_share_modes(SNUM(cnum))) |