summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1997-12-23 13:21:36 +0000
committerJeremy Allison <jra@samba.org>1997-12-23 13:21:36 +0000
commit08bd3b8cc0ed557e8fa9769c053b456ba0fa457e (patch)
tree64363299312fa96e34d78ec05e1533340764eb7c /source3/smbd
parentd4979e7727ef94de469e66b74a9bee6f9742d4c0 (diff)
downloadsamba-08bd3b8cc0ed557e8fa9769c053b456ba0fa457e.tar.gz
samba-08bd3b8cc0ed557e8fa9769c053b456ba0fa457e.tar.bz2
samba-08bd3b8cc0ed557e8fa9769c053b456ba0fa457e.zip
Fixed nastly little bug where client was sending open_and_X call
with smb_mode (smb_vwv[3]) of 0x20 == DENY_WRITE + read-only-open. and smb_ofun (smb_vwv[8]) of 0x11 == Create if not exist plus append on a read-only share. This was mapped into the strange unix flags of (O_RDONLY|O_CREAT) - essentially O_CREAT as O_RDONLY == 0. We were checking the unix flags directly against O_RDONLY instead of masking off the open mode flag bits before doing the comparison, so this open was being refused even though it was valid on a read-only share. Also ensured that the O_CREAT bit was masked out of the flags bit if the open was done on a read-only share (as doing a unix open( filename, O_RDONLY|O_CREAT, xxx) will create a zero length file if the user had permission to write into the directory - which should be denied on a read-only share. Thanks to Mark Peek @ Whistle for giving me this test case. Jeremy. (This used to be commit eae921ac632c8297836b85e909903da0602eac0e)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/server.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 76a9fb272a..5e5f129959 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1151,6 +1151,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
struct stat statbuf;
file_fd_struct *fd_ptr;
files_struct *fsp = &Files[fnum];
+ int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
fsp->open = False;
fsp->fd_ptr = 0;
@@ -1160,12 +1161,32 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
pstrcpy(fname,fname1);
/* check permissions */
- if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
- {
+
+ /*
+ * This code was changed after seeing a client open request
+ * containing the open mode of (DENY_WRITE/read-only) with
+ * the 'create if not exist' bit set. The previous code
+ * would fail to open the file read only on a read-only share
+ * as it was checking the flags parameter directly against O_RDONLY,
+ * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
+ * JRA.
+ */
+
+ if (!CAN_WRITE(cnum) && !Connections[cnum].printer) {
+ /* It's a read-only share - fail if we wanted to write. */
+ if(accmode != O_RDONLY) {
DEBUG(3,("Permission denied opening %s\n",fname));
check_for_pipe(fname);
return;
}
+ else if(flags & O_CREAT) {
+ /* We don't want to write - but we must make sure that O_CREAT
+ doesn't create the file if we have write access into the
+ directory.
+ */
+ flags &= ~O_CREAT;
+ }
+ }
/* this handles a bug in Win95 - it doesn't say to create the file when it
should */
@@ -1203,8 +1224,6 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
*/
if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
- int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
-
/* File was already open. */
if((flags & O_CREAT) && (flags & O_EXCL)) {
fd_ptr->ref_count--;