From c493d8e6405f6a2dd33a24f7f5237d18aab3a576 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 8 Jun 2017 19:10:20 +0200 Subject: [PATCH] s3/smbd: handle EACCES when fetching DOS attributes from xattr When trying to fetch the DOS attributes xattr via SMB_VFS_GETXATTR() if the filesystem doesn't grant read access to the file the xattr read request fails with EACCESS. But according to MS-FSA 2.1.5.1.2.1 "Algorithm to Check Access to an Existing File" FILE_LIST_DIRECTORY on a directory implies FILE_READ_ATTRIBUTES for directory entries. So if the user can open the parent directory for reading this implies FILE_LIST_DIRECTORY and we can safely call SMB_VFS_GETXATTR() as root, ensuring we can read the DOS attributes xattr. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12944 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt (backported from commit c54fcb7cbd0de244eed4134e877da6e9c16e7aab) --- source3/smbd/dosmode.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 65f47eeb1b0..49ddd907a9a 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -281,6 +281,42 @@ NTSTATUS get_ea_dos_attribute(connection_struct *conn, sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr)); + if (sizeret == -1 && errno == EACCES) { + int saved_errno = 0; + + /* + * According to MS-FSA 2.1.5.1.2.1 "Algorithm to Check Access to + * an Existing File" FILE_LIST_DIRECTORY on a directory implies + * FILE_READ_ATTRIBUTES for directory entries. Being able to + * stat() a file implies FILE_LIST_DIRECTORY for the directory + * containing the file. + */ + + if (!VALID_STAT(smb_fname->st)) { + /* + * Safety net: dos_mode() already checks this, but as we + * become root based on this, add an additional layer of + * defense. + */ + DBG_ERR("Rejecting root override, invalid stat [%s]\n", + smb_fname_str_dbg(smb_fname)); + return NT_STATUS_ACCESS_DENIED; + } + + become_root(); + sizeret = SMB_VFS_GETXATTR(conn, smb_fname->base_name, + SAMBA_XATTR_DOS_ATTRIB, + attrstr, + sizeof(attrstr)); + if (sizeret == -1) { + saved_errno = errno; + } + unbecome_root(); + + if (saved_errno != 0) { + errno = saved_errno; + } + } if (sizeret == -1) { DBG_INFO("Cannot get attribute " "from EA on file %s: Error = %s\n", -- 2.47.2