diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dosmode.c | 20 | ||||
-rw-r--r-- | source3/smbd/filename.c | 13 | ||||
-rw-r--r-- | source3/smbd/open.c | 6 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 14 |
4 files changed, 31 insertions, 22 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 6468544748..eeed76329c 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -379,7 +379,7 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode) } /**************************************************************************** - Gets DOS attributes, accessed via st_flags in the stat struct. + Gets DOS attributes, accessed via st_ex_flags in the stat struct. ****************************************************************************/ static bool get_stat_dos_flags(connection_struct *conn, @@ -396,15 +396,15 @@ static bool get_stat_dos_flags(connection_struct *conn, DEBUG(5, ("Getting stat dos attributes for %s.\n", fname)); - if (sbuf->st_flags & UF_DOS_ARCHIVE) + if (sbuf->st_ex_flags & UF_DOS_ARCHIVE) *dosmode |= aARCH; - if (sbuf->st_flags & UF_DOS_HIDDEN) + if (sbuf->st_ex_flags & UF_DOS_HIDDEN) *dosmode |= aHIDDEN; - if (sbuf->st_flags & UF_DOS_RO) + if (sbuf->st_ex_flags & UF_DOS_RO) *dosmode |= aRONLY; - if (sbuf->st_flags & UF_DOS_SYSTEM) + if (sbuf->st_ex_flags & UF_DOS_SYSTEM) *dosmode |= aSYSTEM; - if (sbuf->st_flags & UF_DOS_NOINDEX) + if (sbuf->st_ex_flags & UF_DOS_NOINDEX) *dosmode |= FILE_ATTRIBUTE_NONINDEXED; if (S_ISDIR(sbuf->st_ex_mode)) *dosmode |= aDIR; @@ -416,7 +416,7 @@ static bool get_stat_dos_flags(connection_struct *conn, } /**************************************************************************** - Sets DOS attributes, stored in st_flags of the inode. + Sets DOS attributes, stored in st_ex_flags of the inode. ****************************************************************************/ static bool set_stat_dos_flags(connection_struct *conn, @@ -439,15 +439,15 @@ static bool set_stat_dos_flags(connection_struct *conn, DEBUG(5, ("Setting stat dos attributes for %s.\n", fname)); - new_flags = (sbuf->st_flags & ~UF_DOS_FLAGS) | + new_flags = (sbuf->st_ex_flags & ~UF_DOS_FLAGS) | dos_attributes_to_stat_dos_flags(dosmode); /* Return early if no flags changed. */ - if (new_flags == sbuf->st_flags) + if (new_flags == sbuf->st_ex_flags) return true; DEBUG(5, ("Setting stat dos attributes=0x%x, prev=0x%x\n", new_flags, - sbuf->st_flags)); + sbuf->st_ex_flags)); /* Set new flags with chflags. */ error = SMB_VFS_CHFLAGS(conn, fname, new_flags); diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 72b4ab7aa6..059dca29c8 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -513,8 +513,14 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, goto fail; } - /* ENOENT is the only valid error here. */ - if ((errno != 0) && (errno != ENOENT)) { + /* + * ENOENT/EACCESS are the only valid errors + * here. EACCESS needs handling here for + * "dropboxes", i.e. directories where users + * can only put stuff with permission -wx. + */ + if ((errno != 0) && (errno != ENOENT) + && (errno != EACCES)) { /* * ENOTDIR and ELOOP both map to * NT_STATUS_OBJECT_PATH_NOT_FOUND @@ -524,8 +530,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx, errno == ELOOP) { result = NT_STATUS_OBJECT_PATH_NOT_FOUND; - } - else { + } else { result = map_nt_error_from_unix(errno); } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index c1b29f68f3..fdfa99953f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -346,7 +346,7 @@ static NTSTATUS open_file(files_struct *fsp, if (!CAN_WRITE(conn)) { /* It's a read-only share - fail if we wanted to write. */ - if(accmode != O_RDONLY) { + if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) { DEBUG(3,("Permission denied opening %s\n", path)); return NT_STATUS_ACCESS_DENIED; } else if(flags & O_CREAT) { @@ -354,8 +354,8 @@ static NTSTATUS open_file(files_struct *fsp, O_CREAT doesn't create the file if we have write access into the directory. */ - flags &= ~O_CREAT; - local_flags &= ~O_CREAT; + flags &= ~(O_CREAT|O_EXCL); + local_flags &= ~(O_CREAT|O_EXCL); } } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1d95c207ba..d11bf088e0 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -6870,16 +6870,20 @@ static void call_trans2setfilepathinfo(connection_struct *conn, } } - if (!CAN_WRITE(conn)) { - reply_doserror(req, ERRSRV, ERRaccess); - return; - } - if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) { reply_nterror(req, NT_STATUS_INVALID_LEVEL); return; } + if (!CAN_WRITE(conn)) { + /* Allow POSIX opens. The open path will deny + * any non-readonly opens. */ + if (info_level != SMB_POSIX_PATH_OPEN) { + reply_doserror(req, ERRSRV, ERRaccess); + return; + } + } + DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n", tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data)); |