From: Ralph Boehme Date: Thu, 8 Jun 2017 17:18:36 +0000 (+0200) Subject: vfs_gpfs: handle EACCES when fetching DOS attributes from xattr X-Git-Tag: samba-4.5.13~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad113e076b2a4875cbf056903a741ee913fd1688;p=thirdparty%2Fsamba.git vfs_gpfs: handle EACCES when fetching DOS attributes from xattr When trying to fetch the DOS attributes via gpfswrap_get_winattrs_path() if the filesystem doesn't grant READ_ATTR to the file the function 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 gpfswrap_get_winattrs_path() with DAC_OVERRIDE_CAPABILITY. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12944 Signed-off-by: Ralph Boehme Reviewed-by: Christof Schmitt Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Wed Aug 9 01:21:14 CEST 2017 on sn-devel-144 (cherry picked from commit 62d73f5b936550d623ef4f31c7438ac3c90105b9) --- diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index f096dd54abf..78ebd54e494 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -1520,6 +1520,47 @@ static unsigned int vfs_gpfs_dosmode_to_winattrs(uint32_t dosmode) return winattrs; } +static int get_dos_attr_with_capability(struct smb_filename *smb_fname, + struct gpfs_winattr *attr) +{ + int saved_errno = 0; + int ret; + + /* + * 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 set + * DAC_OVERRIDE_CAPABILITY based on this, add an additional + * layer of defense. + */ + DBG_ERR("Rejecting DAC override, invalid stat [%s]\n", + smb_fname_str_dbg(smb_fname)); + errno = EACCES; + return -1; + } + + set_effective_capability(DAC_OVERRIDE_CAPABILITY); + + ret = gpfswrap_get_winattrs_path(smb_fname->base_name, attr); + if (ret == -1) { + saved_errno = errno; + } + + drop_effective_capability(DAC_OVERRIDE_CAPABILITY); + + if (saved_errno != 0) { + errno = saved_errno; + } + return ret; +} + static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle, struct smb_filename *smb_fname, uint32_t *dosmode) @@ -1542,7 +1583,9 @@ static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle, return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname, dosmode); } - + if (ret == -1 && errno == EACCES) { + ret = get_dos_attr_with_capability(smb_fname, &attrs); + } if (ret == -1) { DBG_WARNING("Getting winattrs failed for %s: %s\n", smb_fname->base_name, strerror(errno)); @@ -1575,6 +1618,30 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle, return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode); } + if (ret == -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 + * open a file implies FILE_LIST_DIRECTORY. + */ + + set_effective_capability(DAC_OVERRIDE_CAPABILITY); + + ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs); + if (ret == -1) { + saved_errno = errno; + } + + drop_effective_capability(DAC_OVERRIDE_CAPABILITY); + + if (saved_errno != 0) { + errno = saved_errno; + } + } + if (ret == -1) { DBG_WARNING("Getting winattrs failed for %s: %s\n", fsp->fsp_name->base_name, strerror(errno));