From: Ralph Boehme Date: Mon, 1 Feb 2021 11:01:22 +0000 (+0100) Subject: smbd: call stat before openat_pathref_fsp() in create_file_unixpath() X-Git-Tag: tevent-0.11.0~1827 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aa0ef26d1e9dcef0bcb47974d7cf60db922d7d08;p=thirdparty%2Fsamba.git smbd: call stat before openat_pathref_fsp() in create_file_unixpath() Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 7c51b0ecd61..68bc3ac4f8c 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -5568,6 +5568,7 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, files_struct *base_fsp = NULL; files_struct *fsp = NULL; NTSTATUS status; + int ret; DBG_DEBUG("create_file_unixpath: access_mask = 0x%x " "file_attributes = 0x%x, share_access = 0x%x, " @@ -5715,30 +5716,34 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, goto fail; } - SET_STAT_INVALID(smb_fname_base->st); - /* * We may be creating the basefile as part of creating the * stream, so it's legal if the basefile doesn't exist at this * point, the create_file_unixpath() below will create it. But * if the basefile exists we want a handle so we can fstat() it. */ - status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_base); - if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) - { - DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n", - smb_fname_str_dbg(smb_fname_base), - nt_errstr(status)); + + ret = vfs_stat(conn, smb_fname_base); + if (ret == -1 && errno != ENOENT) { + status = map_nt_error_from_unix(errno); TALLOC_FREE(smb_fname_base); goto fail; } - - if (smb_fname_base->fsp != NULL) { - int ret; + if (ret == 0) { + status = openat_pathref_fsp(conn->cwd_fsp, + smb_fname_base); + if (NT_STATUS_EQUAL(status, + NT_STATUS_STOPPED_ON_SYMLINK)) + { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n", + smb_fname_str_dbg(smb_fname_base), + nt_errstr(status)); + TALLOC_FREE(smb_fname_base); + goto fail; + } ret = SMB_VFS_FSTAT(smb_fname_base->fsp, &smb_fname_base->st);