From d70bab3c15e091ce4bc037c2b5d7eeb794fa5cc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Apr 2013 13:59:22 -0700 Subject: [PATCH 1/4] Add early return in file_set_dosmode() on a read only share. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit 0d88b37fc63023eeb749080713449b124e346e9e) --- source3/smbd/dosmode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index ad04a651..cff6a7f 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -707,6 +707,11 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, uint32_t old_mode; struct timespec new_create_timespec; + if (!CAN_WRITE(conn)) { + errno = EROFS; + return -1; + } + /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */ dosmode &= (SAMBA_ATTRIBUTES_MASK | FILE_ATTRIBUTE_OFFLINE); -- 1.8.2.1 From 06ff3abb32bcaccd2eac9ef7326a4b6c3ca8a540 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Apr 2013 14:00:42 -0700 Subject: [PATCH 2/4] Remove indentation around code wrapped by unneeded CAN_WRITE. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit a91aac4a5f0bd2077be267e49d1fc4f0321bb39c) --- source3/smbd/dosmode.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index cff6a7f..0179e8e 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -706,6 +706,7 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, int ret = -1, lret = -1; uint32_t old_mode; struct timespec new_create_timespec; + files_struct *fsp = NULL; if (!CAN_WRITE(conn)) { errno = EROFS; @@ -853,29 +854,25 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, bits on a file. Just like file_ntimes below. */ - /* Check if we have write access. */ - if (CAN_WRITE(conn)) { - /* - * We need to open the file with write access whilst - * still in our current user context. This ensures we - * are not violating security in doing the fchmod. - */ - files_struct *fsp; - if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname, - &fsp))) - return -1; - become_root(); - ret = SMB_VFS_FCHMOD(fsp, unixmode); - unbecome_root(); - close_file(NULL, fsp, NORMAL_CLOSE); - if (!newfile) { - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_ATTRIBUTES, - smb_fname->base_name); - } - if (ret == 0) { - smb_fname->st.st_ex_mode = unixmode; - } + /* + * We need to open the file with write access whilst + * still in our current user context. This ensures we + * are not violating security in doing the fchmod. + */ + if (!NT_STATUS_IS_OK(open_file_fchmod(conn, smb_fname, + &fsp))) + return -1; + become_root(); + ret = SMB_VFS_FCHMOD(fsp, unixmode); + unbecome_root(); + close_file(NULL, fsp, NORMAL_CLOSE); + if (!newfile) { + notify_fname(conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES, + smb_fname->base_name); + } + if (ret == 0) { + smb_fname->st.st_ex_mode = unixmode; } return( ret ); -- 1.8.2.1 From 4018fe010bfc5fbfb7ca56184c53eb1f14c0fd08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Apr 2013 14:02:24 -0700 Subject: [PATCH 3/4] Ensure we don't try the open_file_fchmod() if we can't write to the file. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke (cherry picked from commit 77e3099483489ef4d59087dc6542fe7f7b589224) --- source3/smbd/dosmode.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 0179e8e..64877d2 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -854,6 +854,11 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname, bits on a file. Just like file_ntimes below. */ + if (!can_write_to_file(conn, smb_fname)) { + errno = EACCES; + return -1; + } + /* * We need to open the file with write access whilst * still in our current user context. This ensures we -- 1.8.2.1 From 1171ec775975fba4567e95a9099e899a819a38fc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Apr 2013 14:06:03 -0700 Subject: [PATCH 4/4] Check for WRITE_ACCESS on the file before overriding an EACCESS. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Sat Apr 27 15:57:17 CEST 2013 on sn-devel-104 (cherry picked from commit 5185460067229a342ddf3951ecc968017c2ed4df) --- source3/smbd/dosmode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 64877d2..3152631 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -419,6 +419,10 @@ static bool set_ea_dos_attribute(connection_struct *conn, if(!CAN_WRITE(conn) || !lp_dos_filemode(SNUM(conn))) return false; + if (!can_write_to_file(conn, smb_fname)) { + return false; + } + /* * We need to open the file with write access whilst * still in our current user context. This ensures we -- 1.8.2.1