From: Jeremy Allison Date: Tue, 22 Jun 2021 23:49:11 +0000 (-0700) Subject: s3: VFS: streams_xattr: Use openat_pathref_fsp() to create a smb_fname->fsp (and... X-Git-Tag: tevent-0.11.0~162 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f54eb555d0ef5ff332ed635ce2c52625ce74952;p=thirdparty%2Fsamba.git s3: VFS: streams_xattr: Use openat_pathref_fsp() to create a smb_fname->fsp (and the smb_fname->fsp->base_fsp) if the incoming name doesn't have one. Use new smb_fname->fsp->base_fsp parameter in get_xattr_size(), change name parameter to NULL. If openat_pathref_fsp() fails, return the correct error code (thanks Ralph!). Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 37da83ea8ce..69528a36851 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -238,6 +238,8 @@ static int streams_xattr_stat(vfs_handle_struct *handle, int result = -1; char *xattr_name = NULL; char *tmp_stream_name = NULL; + struct smb_filename *smb_fname_cp = NULL; + struct files_struct *fsp = smb_fname->fsp; if (!is_named_stream(smb_fname)) { return SMB_VFS_NEXT_STAT(handle, smb_fname); @@ -267,23 +269,55 @@ static int streams_xattr_stat(vfs_handle_struct *handle, } /* Augment the base file's stat information before returning. */ - if (smb_fname->fsp == NULL) { - smb_fname->st.st_ex_size = get_xattr_size(handle->conn, - NULL, - smb_fname, - xattr_name); - } else { - SMB_ASSERT(smb_fname->fsp->base_fsp != NULL); - smb_fname->st.st_ex_size = get_xattr_size(handle->conn, - smb_fname->fsp->base_fsp, - NULL, - xattr_name); + if (fsp == NULL) { + /* + * openat_pathref_fsp() checks for the same + * filetype as the incoming stat info before allowing + * the open, so we must ensure it's correct here. + */ + smb_fname->st.st_ex_mode &= ~S_IFMT; + smb_fname->st.st_ex_mode |= S_IFREG; + + /* + * openat_pathref_fsp() expects a talloc'ed + * smb_filename. stat can be passed a struct + * from the stack. Make a talloc'ed copy + * so openat_pathref_fsp() can add its + * destructor. + */ + smb_fname_cp = cp_smb_filename(talloc_tos(), + smb_fname); + if (smb_fname_cp == NULL) { + TALLOC_FREE(xattr_name); + errno = ENOMEM; + return -1; + } + status = openat_pathref_fsp(handle->conn->cwd_fsp, + smb_fname_cp); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("openat_pathref_fsp for %s failed with %s\n", + smb_fname_str_dbg(smb_fname), + nt_errstr(status)); + TALLOC_FREE(xattr_name); + TALLOC_FREE(smb_fname_cp); + SET_STAT_INVALID(smb_fname->st); + errno = ENOENT; + return -1; + } + fsp = smb_fname_cp->fsp; } + + SMB_ASSERT(fsp->base_fsp != NULL); + smb_fname->st.st_ex_size = get_xattr_size(handle->conn, + fsp->base_fsp, + NULL, + xattr_name); if (smb_fname->st.st_ex_size == -1) { + TALLOC_FREE(xattr_name); + TALLOC_FREE(smb_fname_cp); SET_STAT_INVALID(smb_fname->st); errno = ENOENT; - result = -1; - goto fail; + return -1; } smb_fname->st.st_ex_ino = hash_inode(&smb_fname->st, xattr_name); @@ -293,10 +327,9 @@ static int streams_xattr_stat(vfs_handle_struct *handle, smb_fname->st.st_ex_blocks = smb_fname->st.st_ex_size / STAT_ST_BLOCKSIZE + 1; - result = 0; - fail: TALLOC_FREE(xattr_name); - return result; + TALLOC_FREE(smb_fname_cp); + return 0; } static int streams_xattr_lstat(vfs_handle_struct *handle,