From: Ralph Boehme Date: Thu, 8 Jun 2017 17:10:20 +0000 (+0200) Subject: s3/smbd: handle EACCES when fetching DOS attributes from xattr X-Git-Tag: samba-4.5.13~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c493d8e6405f6a2dd33a24f7f5237d18aab3a576;p=thirdparty%2Fsamba.git 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) --- 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",